From 79ba52cb7d7a7d4ef9fbce618aae4e32647a694c Mon Sep 17 00:00:00 2001 From: Hamza-Ayed Date: Mon, 18 May 2026 18:22:27 +0300 Subject: [PATCH] feat: implement Firebase Admin SDK push notification logic in server.js with fallback support --- whatsapp_bridge/package.json | 1 + whatsapp_bridge/server.js | 81 ++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/whatsapp_bridge/package.json b/whatsapp_bridge/package.json index 7b0e674..936d41a 100644 --- a/whatsapp_bridge/package.json +++ b/whatsapp_bridge/package.json @@ -15,6 +15,7 @@ "license": "ISC", "dependencies": { "express": "^4.18.2", + "firebase-admin": "^11.11.1", "puppeteer": "^21.0.0", "qrcode": "^1.5.3", "whatsapp-web.js": "^1.26.0", diff --git a/whatsapp_bridge/server.js b/whatsapp_bridge/server.js index 923429a..e5af63e 100644 --- a/whatsapp_bridge/server.js +++ b/whatsapp_bridge/server.js @@ -16,6 +16,72 @@ const app = express(); const server = http.createServer(app); const wss = new WebSocketServer({ server }); +// ─── Firebase Admin SDK Configuration (Optional Background Pushes) ───────── +const admin = require('firebase-admin'); +const path = require('path'); +const fs = require('fs'); + +let firebaseApp = null; +const serviceAccountPath = path.join(__dirname, 'serviceAccountKey.json'); + +if (fs.existsSync(serviceAccountPath)) { + try { + const serviceAccount = require(serviceAccountPath); + firebaseApp = admin.initializeApp({ + credential: admin.credential.cert(serviceAccount) + }); + console.log('[FCM] Firebase Admin SDK initialized successfully using serviceAccountKey.json'); + } catch (err) { + console.error('[FCM ERROR] Failed to initialize Firebase Admin SDK:', err.message); + } +} else { + console.warn('[FCM WARNING] serviceAccountKey.json not found in server directory. Background push notifications will be disabled.'); +} + +async function sendPushNotification(chatId, senderName, body) { + if (!firebaseApp) { + console.log('[FCM] Push skipped: Firebase Admin SDK not initialized.'); + return; + } + + const tokenPath = path.join(__dirname, 'fcm_token.json'); + if (!fs.existsSync(tokenPath)) { + console.log('[FCM] Push skipped: No registered FCM device token found.'); + return; + } + + try { + const tokenData = JSON.parse(fs.readFileSync(tokenPath)); + const token = tokenData.token; + if (!token) return; + + const message = { + token: token, + notification: { + title: senderName || 'WhatsApp Message', + body: body || 'New Message' + }, + data: { + chatId: chatId, + name: senderName || 'WhatsApp' + }, + apns: { + payload: { + aps: { + sound: 'default', + badge: 1 + } + } + } + }; + + const response = await admin.messaging().send(message); + console.log('[FCM] Push notification sent successfully, messageId:', response); + } catch (err) { + console.error('[FCM SEND ERROR] Failed to send push notification:', err.message); + } +} + // ─── State ───────────────────────────────────────────────────────────────── let waClient = null; let clientReady = false; @@ -216,6 +282,21 @@ function initWhatsApp() { try { const formatted = formatMessage(msg); broadcast({ type: 'new_message', chatId: msg.from, data: formatted }); + + // Trigger background push notification if not sent by me + if (!msg.fromMe) { + try { + const contact = await msg.getContact(); + const senderName = contact.name || contact.pushname || msg.from.split('@')[0]; + let body = msg.body || ''; + if (!body && msg.hasMedia) { + body = '📷 Media/Attachment'; + } + await sendPushNotification(msg.from, senderName, body); + } catch (fcmErr) { + console.error('[FCM PUSH ERROR] Failed to send background push:', fcmErr.message); + } + } } catch (err) { console.error('[WA] Error formatting new message event:', err.message); }