UNPKG

whatsapp-claude-gpt

Version:

WhatsApp-Claude-GPT is a WhatsApp chatbot that supports multiple AI providers for chat, optional image generation/editing, and voice (speech-to-text and text-to-speech). It’s built for natural, contextual conversations and can now also handle reminders an

109 lines (89 loc) 3.48 kB
import logger from './logger'; import { Client, LocalAuth, Message } from "whatsapp-web.js"; import qrcode from 'qrcode-terminal'; import Roboto from "./bot/roboto"; import WhatsappHandler from "./bot/wsp-web"; import Reminders from "./services/reminder-service"; import { configValidation, logConfigInfo } from "./utils"; import { CONFIG } from "./config"; require('dotenv').config(); configValidation() logConfigInfo(); async function start() { try { const puppeteerArgs: string[] = [ '--disable-dev-shm-usage', '--disable-accelerated-2d-canvas', '--no-first-run', '--disable-gpu' ]; // Chromium only accepts --no-zygote when sandbox is also disabled, so keep // those flags coupled for Docker/root environments that require them. if (CONFIG.BotConfig.puppeteerNoSandbox) { puppeteerArgs.unshift('--no-sandbox', '--disable-setuid-sandbox', '--no-zygote'); } const wspClient = new Client({ authStrategy: new LocalAuth(), puppeteer: { args: puppeteerArgs, } }); // Set the WhatsApp client immediately after construction so all downstream // consumers can access it as soon as it becomes available. WhatsappHandler.setWspClient(wspClient); logger.info('Starting WhatsApp client...'); wspClient.on('qr', qr => { logger.info('QR Code received, scan please'); qrcode.generate(qr, { small: true }); }); wspClient.on('authenticated', () => { logger.info('Client authenticated'); }); wspClient.on('auth_failure', async (msg) => { logger.error(`Authentication failure: ${msg}`); }); wspClient.on('ready', () => { logger.info('Client is ready!'); // Start the reminder checker now that the WhatsApp client is available. Reminders.startReminderChecker(); }); // Capture unhandled rejections from the message listener so a single // failing message does not crash the process. wspClient.on('message', (message: Message) => { void Roboto.readWspMessage(message).catch((e) => { logger.error(`[index] Unhandled error in readWspMessage: ${e.message}`); }); }); await wspClient.initialize(); const shutdown = async (signal: string) => { logger.info(`Received ${signal}, shutting down gracefully...`); try { Reminders.stopReminderChecker(); await wspClient.destroy(); logger.info('WhatsApp client destroyed'); } catch (e: any) { logger.error(`Error destroying WhatsApp client: ${e.message}`); } process.exit(0); }; process.on('SIGTERM', () => shutdown('SIGTERM')); process.on('SIGINT', () => shutdown('SIGINT')); } catch (e: any) { logger.error(`ERROR: ${e.message}`); } } // Global handlers for unhandled rejections and uncaught exceptions. // These prevent silent process crashes and log the error for debugging. process.on('unhandledRejection', (reason: any, promise: Promise<any>) => { logger.error(`[process] Unhandled Rejection at: ${promise}, reason: ${reason?.message || reason}`); }); process.on('uncaughtException', (error: Error) => { logger.error(`[process] Uncaught Exception: ${error.message}`); // For uncaught exceptions we perform a controlled shutdown // because the process may be in an inconsistent state. try { Reminders.stopReminderChecker(); } catch (_) { /* ignore errors during emergency cleanup */ } process.exit(1); }); start();