diff --git a/packages/core.gbapp/services/GBMinService.ts b/packages/core.gbapp/services/GBMinService.ts index df564d46c..238536207 100644 --- a/packages/core.gbapp/services/GBMinService.ts +++ b/packages/core.gbapp/services/GBMinService.ts @@ -167,9 +167,6 @@ export class GBMinService { GBServer.globals.server.get('/instances/:botId', this.handleGetInstanceForClient.bind(this)); } - // Servers the WhatsApp callback. - - GBServer.globals.server.post('/webhooks/whatsapp/:botId', this.WhatsAppCallback.bind(this)); // Calls mountBot event to all bots. @@ -342,224 +339,6 @@ export class GBMinService { return req.body.phone_id ? "maytapi" : "chatapi"; } - private async WhatsAppCallback(req, res) { - try { - - if (req.body && req.body.webhook) { - res.status(200); - res.end(); - - return; - } - - let provider = GBMinService.isChatAPI(req, res); - let id; - let senderName; - let botId; - let text; - - switch (provider) { - case "GeneralBots": - - id = req.body.messages[0].author.split('@')[0]; - senderName = req.body.messages[0].senderName; - text = req.body; - - break; - - case "chatapi": - - if (req.body.ack) { - res.status(200); - res.end(); - - return; - } - if (req.body.messages[0].fromMe) { - res.end(); - - return; // Exit here. - } - id = req.body.messages[0].author.split('@')[0]; - senderName = req.body.messages[0].senderName; - text = req.body.messages[0].body; - botId = req.params.botId; - if (botId === '[default]' || botId === undefined) { - botId = GBConfigService.get('BOT_ID'); - } - break; - case "maytapi": - - if (req.body.type !== 'message') { - res.status(200); - res.end(); - - return; - } - if (req.body.message.fromMe) { - res.end(); - - return; // Exit here. - } - id = req.body.user.phone; - senderName = req.body.user.name; - text = req.body.message.text; - - botId = WhatsappDirectLine.phones[req.body.phoneId]; - break; - } - - const sec = new SecService(); - let user = await sec.getUserFromSystemId(id); - - GBLog.info(`A WhatsApp mobile requested instance for: ${botId}.`); - - let urlMin: any = GBServer.globals.minInstances.filter - (p => p.instance.botId === botId)[0]; - - const botNumber = urlMin ? urlMin.core.getParam(urlMin.instance, 'Bot Number', null) : null; - let activeMin; - - // Processes group behaviour. - - text = text.replace(/\@\d+ /gi, ''); - - if (provider === "chatapi") { - - // Ensures that the bot group is the active bot for the user (like switching). - - const message = req.body.messages[0]; - if (message.chatName.charAt(0) !== '+') { - const group = message.chatName; - - const botGroup = await this.core.loadInstanceByBotId(group); - if (botGroup && user.instanceId !== botGroup.instanceId) { - await sec.updateUserInstance(id, botGroup.instanceId); - } - if (botGroup) { - activeMin = GBServer.globals.minInstances.filter - (p => p.instance.instanceId === botGroup.instanceId)[0]; - await (activeMin as any).whatsAppDirectLine.received(req, res); - return; // EXIT HERE. - } - } - } - - // Detects if the welcome message is enabled. - - if (process.env.WHATSAPP_WELCOME_DISABLED !== 'true') { - - // Tries to find if user wants to switch bots. - - let toSwitchMin = GBServer.globals.minInstances.filter( - p => p.instance.botId.toLowerCase() === text.toLowerCase() - )[0]; - if (!toSwitchMin) { - toSwitchMin = GBServer.globals.minInstances.filter(p => - p.instance.activationCode ? p.instance.activationCode.toLowerCase() === text.toLowerCase() : false - )[0]; - } - - // If bot has a fixed Find active bot instance. - - activeMin = botNumber ? urlMin : - toSwitchMin ? toSwitchMin : GBServer.globals.minBoot; - - // If it is the first time for the user, tries to auto-execute - // start dialog if any is specified in Config.xlsx. - - if (user === null || user.hearOnDialog) { - user = await sec.ensureUser(activeMin.instance.instanceId, id, senderName, '', 'whatsapp', senderName, null); - - const startDialog = user.hearOnDialog ? - user.hearOnDialog : - activeMin.core.getParam(activeMin.instance, 'Start Dialog', null); - - if (startDialog) { - GBLog.info(`Calling /start to Auto start ${startDialog} for ${activeMin.instance.instanceId}...`); - if (provider === "chatapi") { - req.body.messages[0].body = `/start`; - } - else if (provider === "maytapi") { - req.body.message = `/start`; - } - - // Resets HEAR ON DIALOG value to none and passes - // current dialog to the direct line. - - await sec.updateUserHearOnDialog(user.userId, null); - await (activeMin as any).whatsAppDirectLine.received(req, res); - } else { - await (activeMin as any).whatsAppDirectLine.sendToDevice( - id, - `Olá! Seja bem-vinda(o)!\nMe chamo ${activeMin.instance.title}. Como posso ajudar? Pode me falar que eu te ouço, me manda um aúdio.` - , null); - res.end(); - } - } else { - - // User wants to switch bots. - - if (toSwitchMin !== undefined) { - - // So gets the new bot instance information and prepares to - // auto start dialog if any is specified. - - const instance = await this.core.loadInstanceByBotId(activeMin.botId); - await sec.updateUserInstance(id, instance.instanceId); - await (activeMin as any).whatsAppDirectLine.resetConversationId(activeMin.botId, id, ''); - const startDialog = activeMin.core.getParam(activeMin.instance, 'Start Dialog', null); - - - if (startDialog) { - GBLog.info(`Calling /start for Auto start : ${startDialog} for ${activeMin.instance.botId}...`); - if (provider === "chatapi") { - req.body.messages[0].body = `/start`; - } - else if (provider === "maytapi") { - req.body.message = `/start`; - } - - - await (activeMin as any).whatsAppDirectLine.received(req, res); - } else { - await (activeMin as any).whatsAppDirectLine.sendToDevice( - id, - `Agora falando com ${activeMin.instance.title}...`, - null - ); - - - } - res.end(); - } else { - activeMin = GBServer.globals.minInstances.filter(p => p.instance.instanceId === user.instanceId)[0]; - if (activeMin === undefined) { - activeMin = GBServer.globals.minBoot; - await (activeMin as any).whatsAppDirectLine.sendToDevice( - id, - `O outro Bot que você estava falando(${user.instanceId}), não está mais disponível. Agora você está falando comigo, ${activeMin.instance.title}...` - ); - } - await (activeMin as any).whatsAppDirectLine.received(req, res); - } - } - } else { - let minInstance = GBServer.globals.minInstances.filter( - p => p.instance.botId.toLowerCase() === botId.toLowerCase() - )[0]; - - - // Just pass the message to the receiver. - - await minInstance.whatsAppDirectLine.received(req, res); - } - } catch (error) { - - GBLog.error(`Error on Whatsapp callback: ${error.data ? error.data : error} ${error.stack}`); - } - } - /** * Creates a listener that can be used by external monitors to check * bot instance health. diff --git a/packages/whatsapp.gblib/services/WhatsappDirectLine.ts b/packages/whatsapp.gblib/services/WhatsappDirectLine.ts index bb710d792..d45ef300a 100644 --- a/packages/whatsapp.gblib/services/WhatsappDirectLine.ts +++ b/packages/whatsapp.gblib/services/WhatsappDirectLine.ts @@ -45,6 +45,8 @@ import { Messages } from '../strings'; import { GuaribasUser } from '../../security.gbapp/models'; import { DialogKeywords } from '../../basic.gblib/services/DialogKeywords'; import { GBAdminService } from '../../admin.gbapp/services/GBAdminService'; +import { GBMinService } from '../../core.gbapp/services/GBMinService'; +import { GBConfigService } from '../../core.gbapp/services/GBConfigService'; const { MessageMedia, Client, LocalAuth } = require('whatsapp-web.js'); const qrcode = require('qrcode-terminal'); @@ -138,7 +140,7 @@ export class WhatsappDirectLine extends GBService { // Dispatches messages to the received method. client.on('message', (async message => { - await this.received(message, null); + await this.WhatsAppCallback(message, null); }).bind(this)); client.on('qr', (async (qr) => { @@ -838,4 +840,223 @@ export class WhatsappDirectLine extends GBService { await this.sendToDevice(to, text, conversationId); } + + private async WhatsAppCallback(req, res) { + try { + + if (req.body && req.body.webhook) { + res.status(200); + res.end(); + + return; + } + + let provider = GBMinService.isChatAPI(req, res); + let id; + let senderName; + let botId; + let text; + + switch (provider) { + case "GeneralBots": + + id = req.author.split('@')[0]; + senderName = req._data.notifyName; + text = req.body; + + + break; + + case "chatapi": + + if (req.body.ack) { + res.status(200); + res.end(); + + return; + } + if (req.body.messages[0].fromMe) { + res.end(); + + return; // Exit here. + } + id = req.body.messages[0].author.split('@')[0]; + senderName = req.body.messages[0].senderName; + text = req.body.messages[0].body; + botId = req.params.botId; + if (botId === '[default]' || botId === undefined) { + botId = GBConfigService.get('BOT_ID'); + } + break; + case "maytapi": + + if (req.body.type !== 'message') { + res.status(200); + res.end(); + + return; + } + if (req.body.message.fromMe) { + res.end(); + + return; // Exit here. + } + id = req.body.user.phone; + senderName = req.body.user.name; + text = req.body.message.text; + + botId = WhatsappDirectLine.phones[req.body.phoneId]; + break; + } + + const sec = new SecService(); + let user = await sec.getUserFromSystemId(id); + + GBLog.info(`A WhatsApp mobile requested instance for: ${botId}.`); + + let urlMin: any = GBServer.globals.minInstances.filter + (p => p.instance.botId === botId)[0]; + + const botNumber = urlMin ? urlMin.core.getParam(urlMin.instance, 'Bot Number', null) : null; + let activeMin; + + // Processes group behaviour. + + text = text.replace(/\@\d+ /gi, ''); + + if (provider === "chatapi") { + + // Ensures that the bot group is the active bot for the user (like switching). + + const message = req.body.messages[0]; + if (message.chatName.charAt(0) !== '+') { + const group = message.chatName; + + const botGroup = await this.min.core.loadInstanceByBotId(group); + if (botGroup && user.instanceId !== botGroup.instanceId) { + await sec.updateUserInstance(id, botGroup.instanceId); + } + if (botGroup) { + activeMin = GBServer.globals.minInstances.filter + (p => p.instance.instanceId === botGroup.instanceId)[0]; + await (activeMin as any).whatsAppDirectLine.received(req, res); + return; // EXIT HERE. + } + } + } + + // Detects if the welcome message is enabled. + + if (process.env.WHATSAPP_WELCOME_DISABLED !== 'true') { + + // Tries to find if user wants to switch bots. + + let toSwitchMin = GBServer.globals.minInstances.filter( + p => p.instance.botId.toLowerCase() === text.toLowerCase() + )[0]; + if (!toSwitchMin) { + toSwitchMin = GBServer.globals.minInstances.filter(p => + p.instance.activationCode ? p.instance.activationCode.toLowerCase() === text.toLowerCase() : false + )[0]; + } + + // If bot has a fixed Find active bot instance. + + activeMin = botNumber ? urlMin : + toSwitchMin ? toSwitchMin : GBServer.globals.minBoot; + + // If it is the first time for the user, tries to auto-execute + // start dialog if any is specified in Config.xlsx. + + if (user === null || user.hearOnDialog) { + user = await sec.ensureUser(activeMin.instance.instanceId, id, senderName, '', 'whatsapp', senderName, null); + + const startDialog = user.hearOnDialog ? + user.hearOnDialog : + activeMin.core.getParam(activeMin.instance, 'Start Dialog', null); + + if (startDialog) { + GBLog.info(`Calling /start to Auto start ${startDialog} for ${activeMin.instance.instanceId}...`); + if (provider === "chatapi") { + req.body.messages[0].body = `/start`; + } + else if (provider === "maytapi") { + req.body.message = `/start`; + } + + // Resets HEAR ON DIALOG value to none and passes + // current dialog to the direct line. + + await sec.updateUserHearOnDialog(user.userId, null); + await (activeMin as any).whatsAppDirectLine.received(req, res); + } else { + await (activeMin as any).whatsAppDirectLine.sendToDevice( + id, + `Olá! Seja bem-vinda(o)!\nMe chamo ${activeMin.instance.title}. Como posso ajudar? Pode me falar que eu te ouço, me manda um aúdio.` + , null); + res.end(); + } + } else { + + // User wants to switch bots. + + if (toSwitchMin !== undefined) { + + // So gets the new bot instance information and prepares to + // auto start dialog if any is specified. + + const instance = await this.min.core.loadInstanceByBotId(activeMin.botId); + await sec.updateUserInstance(id, instance.instanceId); + await (activeMin as any).whatsAppDirectLine.resetConversationId(activeMin.botId, id, ''); + const startDialog = activeMin.core.getParam(activeMin.instance, 'Start Dialog', null); + + + if (startDialog) { + GBLog.info(`Calling /start for Auto start : ${startDialog} for ${activeMin.instance.botId}...`); + if (provider === "chatapi") { + req.body.messages[0].body = `/start`; + } + else if (provider === "maytapi") { + req.body.message = `/start`; + } + else { + req.body = `/start`; + } + + await (activeMin as any).whatsAppDirectLine.received(req, res); + } else { + await (activeMin as any).whatsAppDirectLine.sendToDevice( + id, + `Agora falando com ${activeMin.instance.title}...`, + null + ); + } + res.end(); + } else { + activeMin = GBServer.globals.minInstances.filter(p => p.instance.instanceId === user.instanceId)[0]; + if (activeMin === undefined) { + activeMin = GBServer.globals.minBoot; + await (activeMin as any).whatsAppDirectLine.sendToDevice( + id, + `O outro Bot que você estava falando(${user.instanceId}), não está mais disponível. Agora você está falando comigo, ${activeMin.instance.title}...` + ); + } + await (activeMin as any).whatsAppDirectLine.received(req, res); + } + } + } else { + let minInstance = GBServer.globals.minInstances.filter( + p => p.instance.botId.toLowerCase() === botId.toLowerCase() + )[0]; + + + // Just pass the message to the receiver. + + await minInstance.whatsAppDirectLine.received(req, res); + } + } catch (error) { + + GBLog.error(`Error on Whatsapp callback: ${error.data ? error.data : error} ${error.stack}`); + } + } }