diff --git a/backend/src/controllers/WhatsAppController.ts b/backend/src/controllers/WhatsAppController.ts index de4684c..8838f2b 100644 --- a/backend/src/controllers/WhatsAppController.ts +++ b/backend/src/controllers/WhatsAppController.ts @@ -31,12 +31,13 @@ export const store = async (req: Request, res: Response): Promise => { isDefault }); - initWbot(whatsapp) - .then(() => { - wbotMessageListener(whatsapp); - wbotMonitor(whatsapp); - }) - .catch(err => console.log(err)); + try { + const wbot = await initWbot(whatsapp); + wbotMessageListener(wbot); + wbotMonitor(wbot, whatsapp); + } catch (err) { + console.log(err); + } const io = getIO(); io.emit("whatsapp", { diff --git a/backend/src/libs/wbot.ts b/backend/src/libs/wbot.ts index bbbe789..3f7f75a 100644 --- a/backend/src/libs/wbot.ts +++ b/backend/src/libs/wbot.ts @@ -10,82 +10,76 @@ interface Session extends Client { const sessions: Session[] = []; -export const initWbot = async (whatsapp: Whatsapp): Promise => { - try { - const io = getIO(); - const sessionName = whatsapp.name; - let sessionCfg; +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); + if (whatsapp && whatsapp.session) { + sessionCfg = JSON.parse(whatsapp.session); + } + + const sessionIndex = sessions.findIndex(s => s.id === whatsapp.id); + if (sessionIndex !== -1) { + sessions[sessionIndex].destroy(); + sessions.splice(sessionIndex, 1); + } + + const wbot: Session = new Client({ + session: sessionCfg + }); + + wbot.initialize(); + + wbot.on("qr", async qr => { + console.log("Session:", sessionName); + qrCode.generate(qr, { small: true }); + await whatsapp.update({ qrcode: qr, status: "qrcode" }); + io.emit("whatsappSession", { + action: "update", + session: whatsapp + }); + }); + + wbot.on("authenticated", async session => { + console.log("Session:", sessionName, "AUTHENTICATED"); + await whatsapp.update({ + session: JSON.stringify(session), + status: "authenticated" + }); + io.emit("whatsappSession", { + action: "update", + session: whatsapp + }); + }); + + wbot.on("auth_failure", async msg => { + console.error("Session:", sessionName, "AUTHENTICATION FAILURE", msg); + await whatsapp.update({ status: "OFFLINE" }); + reject(new Error("Error starting whatsapp session.")); + }); + + wbot.on("ready", async () => { + console.log("Session:", sessionName, "READY"); + await whatsapp.update({ + status: "CONNECTED", + qrcode: "" + }); + io.emit("whatsappSession", { + action: "update", + session: whatsapp + }); + wbot.sendPresenceAvailable(); + wbot.id = whatsapp.id; + sessions.push(wbot); + resolve(wbot); + }); + } catch (err) { + console.log(err); } - - const sessionIndex = sessions.findIndex(s => s.id === whatsapp.id); - if (sessionIndex !== -1) { - sessions[sessionIndex].destroy(); - sessions.splice(sessionIndex, 1); - } - - const wbot: Session = new Client({ - session: sessionCfg, - restartOnAuthFail: true - }); - wbot.initialize(); - - wbot.on("qr", async qr => { - console.log("Session:", sessionName); - - qrCode.generate(qr, { small: true }); - - await whatsapp.update({ qrcode: qr, status: "qrcode" }); - - io.emit("whatsappSession", { - action: "update", - session: whatsapp - }); - }); - - wbot.on("authenticated", async session => { - console.log("Session:", sessionName, "AUTHENTICATED"); - - await whatsapp.update({ - session: JSON.stringify(session), - status: "authenticated" - }); - - io.emit("whatsappSession", { - action: "update", - session: whatsapp - }); - }); - - wbot.on("auth_failure", async msg => { - console.error("Session:", sessionName, "AUTHENTICATION FAILURE", msg); - - await whatsapp.update({ session: "" }); - }); - - wbot.on("ready", async () => { - console.log("Session:", sessionName, "READY"); - - await whatsapp.update({ - status: "CONNECTED", - qrcode: "" - }); - - io.emit("whatsappSession", { - action: "update", - session: whatsapp - }); - - wbot.sendPresenceAvailable(); - }); - - wbot.id = whatsapp.id; - sessions.push(wbot); - } catch (err) { - console.log(err); - } + }); }; export const getWbot = (whatsappId: number): Session => { diff --git a/backend/src/services/WbotServices/StartWhatsAppSessions.ts b/backend/src/services/WbotServices/StartWhatsAppSessions.ts index 82dc542..306c95a 100644 --- a/backend/src/services/WbotServices/StartWhatsAppSessions.ts +++ b/backend/src/services/WbotServices/StartWhatsAppSessions.ts @@ -6,13 +6,14 @@ import wbotMonitor from "./wbotMonitor"; export const StartWhatsAppSessions = async (): Promise => { const whatsapps = await Whatsapp.findAll(); if (whatsapps.length > 0) { - whatsapps.forEach(whatsapp => { - initWbot(whatsapp) - .then(() => { - wbotMessageListener(whatsapp); - wbotMonitor(whatsapp); - }) - .catch(err => console.log(err)); + whatsapps.forEach(async whatsapp => { + try { + const wbot = await initWbot(whatsapp); + wbotMessageListener(wbot); + wbotMonitor(wbot, whatsapp); + } catch (err) { + console.log(err); + } }); } }; diff --git a/backend/src/services/WbotServices/wbotMessageListener.ts b/backend/src/services/WbotServices/wbotMessageListener.ts index d27da96..5884391 100644 --- a/backend/src/services/WbotServices/wbotMessageListener.ts +++ b/backend/src/services/WbotServices/wbotMessageListener.ts @@ -7,20 +7,23 @@ import * as Sentry from "@sentry/node"; import { Contact as WbotContact, - Message as WbotMessage + Message as WbotMessage, + Client } from "whatsapp-web.js"; import Contact from "../../models/Contact"; import Ticket from "../../models/Ticket"; import Message from "../../models/Message"; -import Whatsapp from "../../models/Whatsapp"; import { getIO } from "../../libs/socket"; -import { getWbot } from "../../libs/wbot"; import AppError from "../../errors/AppError"; import ShowTicketService from "../TicketServices/ShowTicketService"; import CreateMessageService from "../MessageServices/CreateMessageService"; +interface Session extends Client { + id?: number; +} + const writeFileAsync = promisify(writeFile); const verifyContact = async ( @@ -236,9 +239,8 @@ const isValidMsg = (msg: WbotMessage): boolean => { return false; }; -const wbotMessageListener = (whatsapp: Whatsapp): void => { - const whatsappId = whatsapp.id; - const wbot = getWbot(whatsappId); +const wbotMessageListener = (wbot: Session): void => { + const whatsappId = wbot.id; const io = getIO(); wbot.on("message_create", async msg => { @@ -278,7 +280,7 @@ const wbotMessageListener = (whatsapp: Whatsapp): void => { const profilePicUrl = await msgContact.getProfilePicUrl(); const contact = await verifyContact(msgContact, profilePicUrl); - const ticket = await verifyTicket(contact, whatsappId, groupContact); + const ticket = await verifyTicket(contact, whatsappId!, groupContact); await handleMessage(msg, ticket, contact); } catch (err) { @@ -298,7 +300,7 @@ const wbotMessageListener = (whatsapp: Whatsapp): void => { const profilePicUrl = await msgContact.getProfilePicUrl(); const contact = await verifyContact(msgContact, profilePicUrl); - const ticket = await verifyTicket(contact, whatsappId, groupContact); + const ticket = await verifyTicket(contact, whatsappId!, groupContact); await handleMessage(msg, ticket, contact); } catch (err) { diff --git a/backend/src/services/WbotServices/wbotMonitor.ts b/backend/src/services/WbotServices/wbotMonitor.ts index a1e98f2..565861b 100644 --- a/backend/src/services/WbotServices/wbotMonitor.ts +++ b/backend/src/services/WbotServices/wbotMonitor.ts @@ -1,15 +1,22 @@ import * as Sentry from "@sentry/node"; +import { Client } from "whatsapp-web.js"; import wbotMessageListener from "./wbotMessageListener"; import { getIO } from "../../libs/socket"; -import { getWbot, initWbot } from "../../libs/wbot"; +import { initWbot } from "../../libs/wbot"; import Whatsapp from "../../models/Whatsapp"; -const wbotMonitor = (whatsapp: Whatsapp): void => { +interface Session extends Client { + id?: number; +} + +const wbotMonitor = async ( + wbot: Session, + whatsapp: Whatsapp +): Promise => { const io = getIO(); const sessionName = whatsapp.name; - const wbot = getWbot(whatsapp.id); try { wbot.on("change_state", async newState => { @@ -60,12 +67,14 @@ const wbotMonitor = (whatsapp: Whatsapp): void => { session: whatsapp }); + // to be removed after adding buttons to rebuild session on frontend + setTimeout( () => initWbot(whatsapp) .then(() => { - wbotMessageListener(whatsapp); - wbotMonitor(whatsapp); + wbotMessageListener(wbot); + wbotMonitor(wbot, whatsapp); }) .catch(err => { Sentry.captureException(err);