Files
nabeh/whatsapp-gateway/baileys-client.js
2026-05-21 18:24:56 +03:00

114 lines
3.8 KiB
JavaScript

const { default: makeWASocket, useMultiFileAuthState, DisconnectReason } = require('@whiskeysockets/baileys');
const pino = require('pino');
const axios = require('axios');
const fs = require('fs');
const path = require('path');
const sessions = new Map(); // Store active sockets in memory
// Local folder for saving auth keys
const SESSIONS_DIR = path.join(__dirname, 'sessions');
if (!fs.existsSync(SESSIONS_DIR)) {
fs.mkdirSync(SESSIONS_DIR, { recursive: true });
}
async function sendWebhook(webhook_url, payload) {
try {
console.log(`Sending webhook to ${webhook_url} with state ${payload.state}`);
await axios.post(webhook_url, payload, {
headers: {
'Content-Type': 'application/json',
'X-Webhook-Secret': process.env.WEBHOOK_SECRET || 'fallback'
},
timeout: 5000
});
console.log(`Webhook sent successfully to ${webhook_url}`);
} catch (err) {
console.error(`Failed to send webhook to ${webhook_url}:`, err.message);
}
}
async function startSession(session_key, webhook_url) {
// Return existing socket if it's already active
if (sessions.has(session_key)) {
return sessions.get(session_key);
}
const sessionFolder = path.join(SESSIONS_DIR, session_key);
const { state, saveCreds } = await useMultiFileAuthState(sessionFolder);
const sock = makeWASocket({
auth: state,
printQRInTerminal: false,
logger: pino({ level: 'silent' }), // Suppress massive terminal output
browser: ['Nabeh Gateway', 'Chrome', '1.0.0']
});
sessions.set(session_key, sock);
sock.ev.on('creds.update', saveCreds);
sock.ev.on('connection.update', async (update) => {
const { connection, lastDisconnect, qr } = update;
if (qr) {
// Forward the raw QR code string to PHP
await sendWebhook(webhook_url, {
session_key,
state: 'waiting_qr',
qr_code: qr
});
}
if (connection === 'close') {
const statusCode = lastDisconnect?.error?.output?.statusCode;
const shouldReconnect = statusCode !== DisconnectReason.loggedOut;
console.log(`Session ${session_key} connection closed. Reconnect: ${shouldReconnect}`);
if (shouldReconnect) {
// Try reconnecting after a short delay
sessions.delete(session_key);
setTimeout(() => startSession(session_key, webhook_url), 3000);
} else {
// Number was banned or manually logged out from the phone
await disconnectSession(session_key);
await sendWebhook(webhook_url, {
session_key,
state: 'disconnected'
});
}
} else if (connection === 'open') {
console.log(`Session ${session_key} connected successfully!`);
// Parse phone number from the JID (e.g. 9665XXXXXXX@s.whatsapp.net)
const phone = sock.user.id.split(':')[0];
await sendWebhook(webhook_url, {
session_key,
state: 'connected',
phone: phone
});
}
});
return sock;
}
async function disconnectSession(session_key) {
const sock = sessions.get(session_key);
if (sock) {
try { sock.logout(); } catch (e) { } // best effort
sessions.delete(session_key);
}
// Completely wipe the auth directory so a fresh session can be created next time
const sessionFolder = path.join(SESSIONS_DIR, session_key);
if (fs.existsSync(sessionFolder)) {
fs.rmSync(sessionFolder, { recursive: true, force: true });
}
}
module.exports = {
startSession,
disconnectSession
};