diff --git a/whatsapp-gateway/baileys-client.js b/whatsapp-gateway/baileys-client.js index 52f2567..5992232 100644 --- a/whatsapp-gateway/baileys-client.js +++ b/whatsapp-gateway/baileys-client.js @@ -1,7 +1,8 @@ const baileys = require('@whiskeysockets/baileys'); const makeWASocket = baileys.default || baileys.makeWASocket || baileys; -const { useMultiFileAuthState, DisconnectReason, fetchLatestBaileysVersion, downloadMediaMessage } = baileys; +const { useMultiFileAuthState, DisconnectReason, fetchLatestBaileysVersion, downloadMediaMessage, makeCacheableSignalKeyStore } = baileys; const pino = require('pino'); +const NodeCache = require('node-cache'); const axios = require('axios'); const fs = require('fs'); const path = require('path'); @@ -10,6 +11,11 @@ const sessions = new Map(); // Store active sockets in memory const retryCounters = new Map(); // Track reconnection attempts per session const recentMessages = new Map(); // Cache of recent messages in memory to serve getMessage callback +// Global retry counter cache — persists across socket reconnects +// This is CRITICAL for E2EE: tracks message retry attempts so Baileys can +// re-encrypt messages when a recipient's device requests a retry +const msgRetryCounterCache = new NodeCache({ stdTTL: 600, checkperiod: 120 }); + const MAX_RETRIES = 5; // Maximum reconnection attempts before giving up // Local folder for saving auth keys @@ -60,18 +66,27 @@ async function startSession(session_key, webhook_url) { console.warn(`[Baileys] Could not fetch version, using default`); } + const logger = pino({ level: 'silent' }); + const socketConfig = { - auth: state, + auth: { + creds: state.creds, + // Wrap keys with makeCacheableSignalKeyStore for fast in-memory + // Signal key access — this prevents E2EE key lookup failures + // that cause "Waiting for this message" on recipient devices + keys: makeCacheableSignalKeyStore(state.keys, logger), + }, printQRInTerminal: false, - logger: pino({ level: 'silent' }), + logger: logger, browser: ['Nabeh Gateway', 'Chrome', '120.0.0'], + // Message retry counter cache — tracks how many times each message + // retry has been attempted, preventing infinite retry loops + msgRetryCounterCache, getMessage: async (key) => { if (recentMessages.has(key.id)) { return recentMessages.get(key.id); } - return { - conversation: ' ' // Fallback message content to trigger E2EE decryption retry on companion devices - }; + return undefined; } }; if (version) socketConfig.version = version; diff --git a/whatsapp-gateway/package.json b/whatsapp-gateway/package.json index 585fdb8..5837100 100644 --- a/whatsapp-gateway/package.json +++ b/whatsapp-gateway/package.json @@ -12,6 +12,7 @@ "cors": "^2.8.5", "dotenv": "^16.4.5", "express": "^4.19.2", + "node-cache": "^5.1.2", "pino": "^9.2.0" } }