import qrCode from "qrcode-terminal"; import { Client } from "whatsapp-web.js"; import { getIO } from "./socket"; import Whatsapp from "../models/Whatsapp"; import AppError from "../errors/AppError"; import { logger } from "../utils/logger"; import { handleMessage } from "../services/WbotServices/wbotMessageListener"; interface Session extends Client { id?: number; } const sessions: Session[] = []; const syncUnreadMessages = async (wbot: Session) => { const chats = await wbot.getChats(); /* eslint-disable no-restricted-syntax */ /* eslint-disable no-await-in-loop */ for (const chat of chats) { if (chat.unreadCount > 0) { const unreadMessages = await chat.fetchMessages({ limit: chat.unreadCount }); for (const msg of unreadMessages) { await handleMessage(msg, wbot); } await chat.sendSeen(); } } }; export const initWbot = async (whatsapp: Whatsapp): Promise => { return new Promise((resolve, reject) => { try { const io = getIO(); const sessionName = whatsapp.name; let sessionCfg; if (whatsapp && whatsapp.session) { sessionCfg = JSON.parse(whatsapp.session); } const wbot: Session = new Client({ session: sessionCfg, puppeteer: { executablePath: process.env.CHROME_BIN || undefined } }); wbot.initialize(); wbot.on("qr", async qr => { logger.info("Session:", sessionName); qrCode.generate(qr, { small: true }); await whatsapp.update({ qrcode: qr, status: "qrcode", retries: 0 }); const sessionIndex = sessions.findIndex(s => s.id === whatsapp.id); if (sessionIndex === -1) { wbot.id = whatsapp.id; sessions.push(wbot); } io.emit("whatsappSession", { action: "update", session: whatsapp }); }); wbot.on("authenticated", async session => { logger.info(`Session: ${sessionName} AUTHENTICATED`); await whatsapp.update({ session: JSON.stringify(session) }); }); wbot.on("auth_failure", async msg => { console.error( `Session: ${sessionName} AUTHENTICATION FAILURE! Reason: ${msg}` ); if (whatsapp.retries > 1) { await whatsapp.update({ session: "", retries: 0 }); } const retry = whatsapp.retries; await whatsapp.update({ status: "DISCONNECTED", retries: retry + 1 }); io.emit("whatsappSession", { action: "update", session: whatsapp }); reject(new Error("Error starting whatsapp session.")); }); wbot.on("ready", async () => { logger.info(`Session: ${sessionName} READY`); await whatsapp.update({ status: "CONNECTED", qrcode: "", retries: 0 }); io.emit("whatsappSession", { action: "update", session: whatsapp }); const sessionIndex = sessions.findIndex(s => s.id === whatsapp.id); if (sessionIndex === -1) { wbot.id = whatsapp.id; sessions.push(wbot); } wbot.sendPresenceAvailable(); await syncUnreadMessages(wbot); resolve(wbot); }); } catch (err) { logger.error(err); } }); }; export const getWbot = (whatsappId: number): Session => { const sessionIndex = sessions.findIndex(s => s.id === whatsappId); if (sessionIndex === -1) { throw new AppError("ERR_WAPP_NOT_INITIALIZED"); } return sessions[sessionIndex]; }; export const removeWbot = (whatsappId: number): void => { try { const sessionIndex = sessions.findIndex(s => s.id === whatsappId); if (sessionIndex !== -1) { sessions[sessionIndex].destroy(); sessions.splice(sessionIndex, 1); } } catch (err) { logger.error(err); } };