Skip to main content
Glama
whatsapp-integration.js4.89 kB
// WhatsApp client initialization module const { Client, LocalAuth } = require('whatsapp-web.js'); const qrcode = require('qrcode'); // Global variables to track WhatsApp client status let whatsappClient = null; let connectionStatus = 'disconnected'; let qrCodeData = null; let initializationError = null; let apiKey = null; // Store API key after successful connection // Function to initialize WhatsApp client async function initializeWhatsAppClient() { console.log('[WhatsApp] Starting WhatsApp client initialization'); try { // Determine the proper auth path - use /app/.wwebjs_auth in production (Render), // or a local path when running on the development machine const isRunningOnRender = process.env.IS_RENDER || process.env.RENDER; const authPath = isRunningOnRender ? '/app/.wwebjs_auth' : './wwebjs_auth'; console.log(`[WhatsApp] Using auth path: ${authPath}`); // Initialize the WhatsApp client whatsappClient = new Client({ authStrategy: new LocalAuth({ dataPath: authPath }), puppeteer: { headless: true, args: [ '--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage', '--disable-accelerated-2d-canvas', '--no-first-run', '--no-zygote', '--disable-gpu' ], executablePath: process.env.PUPPETEER_EXECUTABLE_PATH || undefined } }); // Set up event handlers whatsappClient.on('qr', (qr) => { console.log('[WhatsApp] QR code received'); qrCodeData = qr; connectionStatus = 'qr_received'; }); whatsappClient.on('ready', () => { // Generate API key when client is ready apiKey = generateApiKey(); console.log('[WhatsApp] Client is ready'); console.log(`[WhatsApp] API Key: ${apiKey}`); connectionStatus = 'ready'; qrCodeData = null; // Notify all registered callbacks that the client is ready clientReadyCallbacks.forEach(callback => { try { callback(whatsappClient); } catch (error) { console.error('[WhatsApp] Error in client ready callback', error); } }); }); whatsappClient.on('authenticated', () => { console.log('[WhatsApp] Client is authenticated'); connectionStatus = 'authenticated'; }); whatsappClient.on('auth_failure', (error) => { console.error('[WhatsApp] Authentication failure', error); connectionStatus = 'auth_failure'; initializationError = error.message; }); whatsappClient.on('disconnected', (reason) => { console.log('[WhatsApp] Client disconnected', reason); connectionStatus = 'disconnected'; // Attempt to reinitialize after disconnection setTimeout(initializeWhatsAppClient, 5000); }); // Initialize the client (this will trigger the QR code event) console.log('[WhatsApp] Initializing client...'); connectionStatus = 'initializing'; await whatsappClient.initialize(); } catch (error) { console.error('[WhatsApp] Failed to initialize WhatsApp client', error); connectionStatus = 'error'; initializationError = error.message; // Retry initialization after a delay setTimeout(initializeWhatsAppClient, 10000); } } // Generate a new API key function generateApiKey() { return [...Array(64)] .map(() => (Math.random() * 36 | 0).toString(36)) .join('') .replace(/[^a-z0-9]/g, '') .substring(0, 64); } // Callback for when client is ready let clientReadyCallbacks = []; // Export functions and state for the HTTP server to use module.exports = { initializeWhatsAppClient, getStatus: () => ({ status: connectionStatus, error: initializationError, apiKey: connectionStatus === 'ready' ? apiKey : null }), // Register a callback to get the WhatsApp client instance when it's ready onClientReady: (callback) => { clientReadyCallbacks.push(callback); // If client is already ready, call the callback immediately if (connectionStatus === 'ready' && whatsappClient) { callback(whatsappClient); } }, getQRCode: async () => { if (!qrCodeData) { return null; } try { // Generate QR code as data URL return await qrcode.toDataURL(qrCodeData); } catch (error) { console.error('[WhatsApp] Failed to generate QR code', error); return null; } }, sendMessage: async (to, message) => { if (connectionStatus !== 'ready') { throw new Error(`Cannot send message. WhatsApp status: ${connectionStatus}`); } try { const formattedNumber = to.includes('@c.us') ? to : `${to}@c.us`; return await whatsappClient.sendMessage(formattedNumber, message); } catch (error) { console.error('[WhatsApp] Failed to send message', error); throw error; } } };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/fyimail/whatsapp-mcp2'

If you have feedback or need assistance with the MCP directory API, please join our Discord server