Fix E2EE retry handling with makeCacheableSignalKeyStore and msgRetryCounterCache

This commit is contained in:
Hamza-Ayed
2026-05-22 20:00:24 +03:00
parent 81efa2e8eb
commit d868364c18
2 changed files with 22 additions and 6 deletions

View File

@@ -1,7 +1,8 @@
const baileys = require('@whiskeysockets/baileys'); const baileys = require('@whiskeysockets/baileys');
const makeWASocket = baileys.default || baileys.makeWASocket || 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 pino = require('pino');
const NodeCache = require('node-cache');
const axios = require('axios'); const axios = require('axios');
const fs = require('fs'); const fs = require('fs');
const path = require('path'); 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 retryCounters = new Map(); // Track reconnection attempts per session
const recentMessages = new Map(); // Cache of recent messages in memory to serve getMessage callback 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 const MAX_RETRIES = 5; // Maximum reconnection attempts before giving up
// Local folder for saving auth keys // 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`); console.warn(`[Baileys] Could not fetch version, using default`);
} }
const logger = pino({ level: 'silent' });
const socketConfig = { 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, printQRInTerminal: false,
logger: pino({ level: 'silent' }), logger: logger,
browser: ['Nabeh Gateway', 'Chrome', '120.0.0'], 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) => { getMessage: async (key) => {
if (recentMessages.has(key.id)) { if (recentMessages.has(key.id)) {
return recentMessages.get(key.id); return recentMessages.get(key.id);
} }
return { return undefined;
conversation: ' ' // Fallback message content to trigger E2EE decryption retry on companion devices
};
} }
}; };
if (version) socketConfig.version = version; if (version) socketConfig.version = version;

View File

@@ -12,6 +12,7 @@
"cors": "^2.8.5", "cors": "^2.8.5",
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"express": "^4.19.2", "express": "^4.19.2",
"node-cache": "^5.1.2",
"pino": "^9.2.0" "pino": "^9.2.0"
} }
} }