116 lines
3.6 KiB
TypeScript
116 lines
3.6 KiB
TypeScript
import { initializeApp, cert } from "firebase-admin/app";
|
|
import { getMessaging } from "firebase-admin/messaging";
|
|
|
|
// Inisialisasi Firebase Admin
|
|
const serviceAccount = require("./key.json");
|
|
|
|
try {
|
|
initializeApp({
|
|
credential: cert(serviceAccount),
|
|
});
|
|
console.log("Firebase berhasil diinisialisasi");
|
|
} catch (error) {
|
|
console.error("Gagal inisialisasi Firebase:", error as Error);
|
|
process.exit(1);
|
|
}
|
|
|
|
// Fungsi untuk mengirim notifikasi ke banyak perangkat dengan retry
|
|
async function sendFCMEach(maxRetries = 3, retryDelay = 1000) {
|
|
try {
|
|
// Ganti dengan token perangkat yang valid
|
|
const tokens = [
|
|
'c89yuexsS_uc1tOErVPu5a:APA91bEb6tEKXAfReZjFVJ2mMyOzoW_RXryLSnSJTpbIVV3G0L_DCNkLuRvJ02Ip-Erz88QCQBAt-C2SN8eCRxu3-v1sBzXzKPtDv-huXpkjXsyrkifqvUo',
|
|
'cRz96GHKTRaQaRJ35e8Hxa:APA91bEUSxE0VPbqKSzseQ_zGhbYsDofMexKykRw7o_3z2aPM9YFmZbeA2enrmb3qjdZ2g4-QQtiNHAyaZqAT1ITOrwo9jVJlShTeABmEFYP5GLEUZ3dlLc'
|
|
];
|
|
|
|
// Validasi token sebelum mengirim
|
|
const validTokens: string[] = [];
|
|
for (const token of tokens) {
|
|
try {
|
|
await getMessaging().send({
|
|
token,
|
|
notification: { title: "Test", body: "Validasi token" },
|
|
});
|
|
validTokens.push(token);
|
|
console.log(`Token ${token.slice(-4)} valid`);
|
|
} catch (error) {
|
|
console.error(`Token ${token.slice(-4)} tidak valid:`, error as Error);
|
|
}
|
|
}
|
|
|
|
if (validTokens.length === 0) {
|
|
throw new Error("Tidak ada token valid untuk mengirim notifikasi");
|
|
}
|
|
|
|
// Buat pesan untuk setiap token
|
|
const messages = validTokens.map((token) => ({
|
|
notification: {
|
|
title: "Judul Notifikasi",
|
|
body: `Pesan untuk perangkat ${token.slice(-4)}`,
|
|
},
|
|
token,
|
|
data: {
|
|
key1: "value1",
|
|
key2: "value2",
|
|
},
|
|
android: {
|
|
priority: "high",
|
|
notification: {
|
|
sound: "default",
|
|
channelId: "default_channel",
|
|
},
|
|
},
|
|
apns: {
|
|
payload: {
|
|
aps: {
|
|
sound: "default",
|
|
},
|
|
},
|
|
},
|
|
}));
|
|
|
|
console.log("Mengirim notifikasi ke token:", validTokens.map((t) => t.slice(-4)));
|
|
|
|
// Kirim pesan dengan retry logic
|
|
let lastError;
|
|
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
try {
|
|
const response = await getMessaging().sendEach(messages as any);
|
|
console.log("Notifikasi berhasil dikirim:", response.successCount);
|
|
console.log("Notifikasi gagal:", response.failureCount);
|
|
|
|
response.responses.forEach((resp, index) => {
|
|
if (resp.success) {
|
|
console.log(`Pesan ke ${validTokens[index].slice(-4)} berhasil:`, resp.messageId);
|
|
} else {
|
|
console.error(`Pesan ke ${validTokens[index].slice(-4)} gagal:`, resp.error?.code, resp.error?.message);
|
|
}
|
|
});
|
|
|
|
return response;
|
|
} catch (error) {
|
|
lastError = error;
|
|
console.error(`Percobaan ${attempt} gagal:`, error as Error);
|
|
if (attempt === maxRetries) {
|
|
throw new Error(`Gagal setelah ${maxRetries} percobaan: ${error as Error}`);
|
|
}
|
|
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
}
|
|
}
|
|
throw lastError;
|
|
} catch (error) {
|
|
console.error("Error mengirim notifikasi:", error as Error);
|
|
if ((error as any).code === "messaging/registration-token-not-registered") {
|
|
console.log("Token tidak valid. Hapus token dari database.");
|
|
}
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Jalankan fungsi
|
|
sendFCMEach()
|
|
.then(() => console.log("Proses selesai"))
|
|
.catch((error) => {
|
|
console.error("Gagal menjalankan sendFCMEach:", error as Error);
|
|
process.exit(1);
|
|
}); |