diff --git a/whatsapp-gateway/puppeteer-client.js b/whatsapp-gateway/puppeteer-client.js index 0b21b4f..d2b6b10 100644 --- a/whatsapp-gateway/puppeteer-client.js +++ b/whatsapp-gateway/puppeteer-client.js @@ -62,6 +62,19 @@ function cleanChromeLocks(sessionKey) { } } +// Clear Session Folder recursively to prevent corruption on logouts +function clearSessionFolder(sessionKey) { + const sessionPath = path.join(SESSIONS_DIR, `session-${sessionKey}`); + try { + if (fs.existsSync(sessionPath)) { + console.log(`[CLEANUP] Recursively removing session folder for ${sessionKey}: ${sessionPath}`); + fs.rmSync(sessionPath, { recursive: true, force: true }); + } + } catch (err) { + console.error(`[CLEANUP ERROR] Failed to delete session folder for ${sessionKey}:`, err.message); + } +} + async function sendWebhook(webhook_url, payload) { try { console.log(`[Webhook] Sending to ${webhook_url} | state=${payload.state}`); @@ -130,6 +143,8 @@ async function startSession(session_key, webhook_url) { }); sessions.delete(session_key); try { client.destroy(); } catch (_) {} + // Wipe session folder to prevent corrupted state loading on next boot + clearSessionFolder(session_key); }); // Handle Incoming Messages to Webhook @@ -191,10 +206,15 @@ async function startSession(session_key, webhook_url) { async function disconnectSession(session_key) { const client = sessions.get(session_key); if (client) { - await client.logout(); - client.destroy(); + try { + await client.logout(); + } catch (_) {} + try { + client.destroy(); + } catch (_) {} sessions.delete(session_key); } + clearSessionFolder(session_key); } async function checkContact(session_key, phone) { diff --git a/whatsapp-gateway/server.js b/whatsapp-gateway/server.js index 7cdf79b..21cf2da 100644 --- a/whatsapp-gateway/server.js +++ b/whatsapp-gateway/server.js @@ -98,9 +98,20 @@ app.post('/api/contacts/check', async (req, res) => { } } if (activeSlots.length === 0) { - return res.status(503).json({ error: 'No WhatsApp slots are ready' }); + return res.status(503).json({ error: 'No WhatsApp slots are ready to check contacts' }); } - session_key = activeSlots[0]; // Just use the first available slot for checking + + let checkError = null; + for (const slotKey of activeSlots) { + try { + const result = await checkContact(slotKey, phone); + return res.json({ status: 'success', session_key: slotKey, data: result }); + } catch (err) { + console.error(`[ContactCheck] Failed check via ${slotKey}:`, err.message); + checkError = err; + } + } + return res.status(500).json({ error: `Failed to check contact via any active slot. Last error: ${checkError.message}` }); } try { @@ -128,7 +139,7 @@ app.post('/api/messages/send', async (req, res) => { try { if (session_key === 'auto') { - const activeSlots = []; + let activeSlots = []; for (let i = 1; i <= 6; i++) { if (isSessionReady(`slot-${i}`)) { activeSlots.push(`slot-${i}`); @@ -139,14 +150,35 @@ app.post('/api/messages/send', async (req, res) => { return res.status(503).json({ error: 'No WhatsApp slots are currently ready to send messages' }); } - // Round-robin selection - session_key = activeSlots[currentSlotIndex % activeSlots.length]; - currentSlotIndex++; - console.log(`[RoundRobin] Selected ${session_key} out of ${activeSlots.length} active slots.`); - } + let lastError = null; + let attempts = 0; + const maxAttempts = activeSlots.length; - const result = await sendMessage(session_key, phone, message, media_url, audio, mimetype, image); - res.json({ status: 'success', data: result }); + while (attempts < maxAttempts) { + const selectedKey = activeSlots[currentSlotIndex % activeSlots.length]; + currentSlotIndex++; + attempts++; + + try { + console.log(`[RoundRobin] Attempt ${attempts}/${maxAttempts}: Trying to send via ${selectedKey}`); + const result = await sendMessage(selectedKey, phone, message, media_url, audio, mimetype, image); + return res.json({ status: 'success', session_key: selectedKey, data: result }); + } catch (err) { + console.error(`[RoundRobin] Attempt ${attempts} failed via ${selectedKey}:`, err.message); + lastError = err; + + activeSlots = activeSlots.filter(s => s !== selectedKey); + if (activeSlots.length === 0) break; + } + } + + return res.status(500).json({ + error: `Failed to send message after trying all active slots. Last error: ${lastError ? lastError.message : 'Unknown'}` + }); + } else { + const result = await sendMessage(session_key, phone, message, media_url, audio, mimetype, image); + res.json({ status: 'success', data: result }); + } } catch (err) { console.error(`Error sending message via ${session_key} to ${phone}:`, err); res.status(500).json({ error: err.message || 'Failed to send message' });