From 1e0b8b9d29dfb0847125fa53ba79b92463ff7f74 Mon Sep 17 00:00:00 2001 From: adriano Date: Fri, 28 Jul 2023 09:25:13 -0300 Subject: [PATCH] =?UTF-8?q?finaliza=C3=A7=C3=A3o=20da=20implementa=C3=A7?= =?UTF-8?q?=C3=A3o=20para=20que=20um=20mesmo=20contato=20fale=20com=20what?= =?UTF-8?q?sapps=20distintos=20da=20interface=20omnihit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/controllers/SettingController.ts | 3 + backend/src/controllers/TicketController.ts | 9 +- ...7191215-add-contact-multi-chat-settings.ts | 22 + .../src/helpers/CheckContactOpenTickets.ts | 11 +- backend/src/helpers/LoadSettings.ts | 27 + backend/src/helpers/WhaticketSettings.ts | 18 + backend/src/server.ts | 86 +-- .../FindOrCreateTicketService.ts | 21 +- .../WbotServices/wbotMessageListener.ts | 728 +++++++++--------- frontend/src/pages/Settings/index.js | 28 + 10 files changed, 532 insertions(+), 421 deletions(-) create mode 100644 backend/src/database/seeds/20230727191215-add-contact-multi-chat-settings.ts create mode 100644 backend/src/helpers/LoadSettings.ts create mode 100644 backend/src/helpers/WhaticketSettings.ts diff --git a/backend/src/controllers/SettingController.ts b/backend/src/controllers/SettingController.ts index 7144a89..711af60 100644 --- a/backend/src/controllers/SettingController.ts +++ b/backend/src/controllers/SettingController.ts @@ -5,6 +5,7 @@ import AppError from "../errors/AppError"; import UpdateSettingService from "../services/SettingServices/UpdateSettingService"; import ListSettingsService from "../services/SettingServices/ListSettingsService"; +import loadSettings from "../helpers/LoadSettings"; export const index = async (req: Request, res: Response): Promise => { // if (req.user.profile !== "master") { @@ -31,6 +32,8 @@ export const update = async ( value }); + loadSettings(); + const io = getIO(); io.emit("settings", { action: "update", diff --git a/backend/src/controllers/TicketController.ts b/backend/src/controllers/TicketController.ts index 2bc8b61..defdaaf 100644 --- a/backend/src/controllers/TicketController.ts +++ b/backend/src/controllers/TicketController.ts @@ -63,6 +63,7 @@ import endPointQuery from "../helpers/old_EndPointQuery"; import Contact from "../models/Contact"; import BotIsOnQueue from "../helpers/BotIsOnQueue"; import { setMessageAsRead } from "../helpers/SetMessageAsRead"; +import { getSettingValue } from "../helpers/WhaticketSettings"; export const index = async (req: Request, res: Response): Promise => { const { @@ -242,13 +243,7 @@ export const update = async ( let ticketData: TicketData = req.body; - // console.log('ticketData: ', ticketData) - // console.log('ticketData.transfer', ticketData.transfer) - - // return res.send() - - if (1 == 1 + 1) { - } else { + if (getSettingValue("oneContactChatWithManyWhats")?.value == "enabled") { if (ticketData.transfer) { const defaultWhatsapp: any = await GetDefaultWhatsApp( ticketData.userId diff --git a/backend/src/database/seeds/20230727191215-add-contact-multi-chat-settings.ts b/backend/src/database/seeds/20230727191215-add-contact-multi-chat-settings.ts new file mode 100644 index 0000000..cdafb33 --- /dev/null +++ b/backend/src/database/seeds/20230727191215-add-contact-multi-chat-settings.ts @@ -0,0 +1,22 @@ +import { QueryInterface } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.bulkInsert( + "Settings", + [ + { + key: "oneContactChatWithManyWhats", + value: "enabled", + createdAt: new Date(), + updatedAt: new Date() + } + ], + {} + ); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.bulkDelete("Settings", {}); + } +}; diff --git a/backend/src/helpers/CheckContactOpenTickets.ts b/backend/src/helpers/CheckContactOpenTickets.ts index 4d2fd78..6c75ce4 100644 --- a/backend/src/helpers/CheckContactOpenTickets.ts +++ b/backend/src/helpers/CheckContactOpenTickets.ts @@ -2,6 +2,7 @@ import { Op } from "sequelize"; import AppError from "../errors/AppError"; import Ticket from "../models/Ticket"; import ListWhatsAppsNumber from "../services/WhatsappService/ListWhatsAppsNumber"; +import { getSettingValue } from "./WhaticketSettings"; const CheckContactOpenTickets = async ( contactId: number, @@ -9,11 +10,7 @@ const CheckContactOpenTickets = async ( ): Promise => { let ticket; - if (1 == 1 + 1) { - ticket = await Ticket.findOne({ - where: { contactId, status: { [Op.or]: ["open", "pending"] } } - }); - } else { + if (getSettingValue("oneContactChatWithManyWhats")?.value == "enabled") { let whats = await ListWhatsAppsNumber(whatsappId); ticket = await Ticket.findOne({ @@ -25,6 +22,10 @@ const CheckContactOpenTickets = async ( ] } }); + } else { + ticket = await Ticket.findOne({ + where: { contactId, status: { [Op.or]: ["open", "pending"] } } + }); } if (ticket) { diff --git a/backend/src/helpers/LoadSettings.ts b/backend/src/helpers/LoadSettings.ts new file mode 100644 index 0000000..14f531f --- /dev/null +++ b/backend/src/helpers/LoadSettings.ts @@ -0,0 +1,27 @@ +import Setting from "../models/Setting"; +import fs from "fs"; +import dir from "path"; +import os from "os"; + +async function loadSettings() { + const setting = await Setting.findAll({}); + + if (setting) { + let sett = setting.map((s: any) => { + return { key: s.key, value: s.value }; + }); + + try { + const keyFilename = dir.join(os.tmpdir(), `whaticket_settings.json`); + + const jsonSettings = JSON.stringify(sett, null, 2); + + fs.writeFileSync(keyFilename, jsonSettings); + console.log(`Settings saved to ${keyFilename}`); + } catch (err) { + console.error("Error saving Settings to file:", err); + } + } +} + +export default loadSettings; diff --git a/backend/src/helpers/WhaticketSettings.ts b/backend/src/helpers/WhaticketSettings.ts new file mode 100644 index 0000000..41a512a --- /dev/null +++ b/backend/src/helpers/WhaticketSettings.ts @@ -0,0 +1,18 @@ +import fs from "fs"; +import dir from "path"; +import os from "os"; + +export function getSettingValue(key: any) { + let value: any = {}; + + try { + const keyFilename = dir.join(os.tmpdir(), `whaticket_settings.json`); + const jsonData = fs.readFileSync(keyFilename, "utf8"); + const settings = JSON.parse(jsonData); + value = settings.find((s: any) => s.key === key); + } catch (err) { + console.error("Error reading or parsing data from file:", err); + } + + return value; +} diff --git a/backend/src/server.ts b/backend/src/server.ts index 2ab92c0..45082d5 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -11,15 +11,20 @@ import { loadContactsCache } from "./helpers/ContactsCache"; import { loadSchedulesCache } from "./helpers/SchedulingNotifyCache"; import { delRestoreControllFile } from "./helpers/RestoreControll"; -import "./helpers/SchedulingNotifySendMessage" +import "./helpers/SchedulingNotifySendMessage"; import axios from "axios"; -import os from 'os'; +import os from "os"; +import Setting from "./models/Setting"; + +import fs from "fs"; +import dir from "path"; +import { getSettingValue } from "./helpers/WhaticketSettings"; +import loadSettings from "./helpers/LoadSettings"; const server = app.listen(process.env.PORT, () => { logger.info(`Server started on port: ${process.env.PORT}`); }); - // if (global.gc) { // console.log(">> Starting Garbage Collector..."); // global.gc(); @@ -33,96 +38,83 @@ initIO(server); gracefulShutdown(server); (async () => { + console.log("os.tmpdir(): ", os.tmpdir()); - console.log('os.tmpdir(): ', os.tmpdir()) + loadSettings(); - let whatsapps: any = await Whatsapp.findAll({ attributes: ['id', 'url'] }) + let whatsapps: any = await Whatsapp.findAll({ attributes: ["id", "url"] }); // console.log('whatsapps: ', whatsapps) if (whatsapps && whatsapps.length > 0) { - for (let i = 0; i < whatsapps.length; i++) { - try { + console.log( + `API URL: ${whatsapps[i].dataValues.url}/api/connection/status` + ); - console.log(`API URL: ${whatsapps[i].dataValues.url}/api/connection/status`) + const response = await axios.get( + `${whatsapps[i].dataValues.url}/api/connection/status`, + {} + ); - const response = await axios.get(`${whatsapps[i].dataValues.url}/api/connection/status`, {}); - - console.log(`-------> Response: ${response.data.data}`) + console.log(`-------> Response: ${response.data.data}`); if (!response) { - throw new Error('Response null'); + throw new Error("Response null"); } - if (response.data.data && response.data.data == 'CONNECTED') { - await whatsapps[i].update({ status: 'CONNECTED' }); + if (response.data.data && response.data.data == "CONNECTED") { + await whatsapps[i].update({ status: "CONNECTED" }); } - } catch (error: any) { + await whatsapps[i].update({ status: "OPENING" }); - await whatsapps[i].update({ status: 'OPENING' }); - - console.log(`There was an error on try acess the api sessions ${whatsapps[i].dataValues.url}`) + console.log( + `There was an error on try acess the api sessions ${whatsapps[i].dataValues.url}` + ); } await new Promise(f => setTimeout(f, 100)); - } } - if (process.env.CACHE) { + const cacheLength = await cacheSize(); - const cacheLength = await cacheSize() - - console.log('cacheSize: ', cacheLength) + console.log("cacheSize: ", cacheLength); if (cacheLength == 0) { - console.log('Loading from cache...') - await flushCache() - await loadContactsCache() - await loadTicketsCache() + console.log("Loading from cache..."); + await flushCache(); + await loadContactsCache(); + await loadTicketsCache(); } - await loadSchedulesCache() + await loadSchedulesCache(); // await loadWhatsappCache() } - delRestoreControllFile() -})() + delRestoreControllFile(); +})(); setTimeout(async () => { - const io = getIO(); - console.log('Triggered socket!') + console.log("Triggered socket!"); - let users = await User.findAll({ raw: true, attributes: ["id"], }) + let users = await User.findAll({ raw: true, attributes: ["id"] }); if (users && users.length > 0) { - for (let i = 0; i < users.length; i++) { - io.emit("reload_page", { action: "update", userId: users[i].id }); - console.log('USER ID: ', users[i].id) + console.log("USER ID: ", users[i].id); await new Promise(f => setTimeout(f, 100)); - } } - - -}, 5000) - - - - - - - +}, 5000); diff --git a/backend/src/services/TicketServices/FindOrCreateTicketService.ts b/backend/src/services/TicketServices/FindOrCreateTicketService.ts index c104bff..e7d8bf9 100644 --- a/backend/src/services/TicketServices/FindOrCreateTicketService.ts +++ b/backend/src/services/TicketServices/FindOrCreateTicketService.ts @@ -7,6 +7,7 @@ import ShowWhatsAppService from "../WhatsappService/ShowWhatsAppService"; import ShowTicketService from "./ShowTicketService"; import AppError from "../../errors/AppError"; import ListWhatsAppsNumber from "../WhatsappService/ListWhatsAppsNumber"; +import { getSettingValue } from "../../helpers/WhaticketSettings"; const FindOrCreateTicketService = async ( contact: Contact, @@ -17,16 +18,7 @@ const FindOrCreateTicketService = async ( try { let ticket; - if (1 == 1 + 1) { - ticket = await Ticket.findOne({ - where: { - status: { - [Op.or]: ["open", "pending", "queueChoice"] - }, - contactId: groupContact ? groupContact.id : contact.id - } - }); - } else { + if (getSettingValue("oneContactChatWithManyWhats")?.value == "enabled") { let whats = await ListWhatsAppsNumber(whatsappId); ticket = await Ticket.findOne({ @@ -38,6 +30,15 @@ const FindOrCreateTicketService = async ( whatsappId: { [Op.in]: whats.whatsapps.map((w: any) => w.id) } } }); + } else { + ticket = await Ticket.findOne({ + where: { + status: { + [Op.or]: ["open", "pending", "queueChoice"] + }, + contactId: groupContact ? groupContact.id : contact.id + } + }); } const { queues, greetingMessage } = await ShowWhatsAppService(whatsappId); diff --git a/backend/src/services/WbotServices/wbotMessageListener.ts b/backend/src/services/WbotServices/wbotMessageListener.ts index 053b625..8b1ef87 100644 --- a/backend/src/services/WbotServices/wbotMessageListener.ts +++ b/backend/src/services/WbotServices/wbotMessageListener.ts @@ -5,12 +5,10 @@ import * as Sentry from "@sentry/node"; import { copyFolder } from "../../helpers/CopyFolder"; import { removeDir } from "../../helpers/DeleteDirectory"; -import path from 'path'; +import path from "path"; import { format } from "date-fns"; -import ptBR from 'date-fns/locale/pt-BR'; - - +import ptBR from "date-fns/locale/pt-BR"; import { Contact as WbotContact, @@ -34,38 +32,44 @@ import UpdateTicketService from "../TicketServices/UpdateTicketService"; import { date } from "faker"; import ShowQueueService from "../QueueService/ShowQueueService"; -import ShowTicketMessage from "../TicketServices/ShowTicketMessage" -import BotIsOnQueue from "../../helpers/BotIsOnQueue" +import ShowTicketMessage from "../TicketServices/ShowTicketMessage"; +import BotIsOnQueue from "../../helpers/BotIsOnQueue"; import Queue from "../../models/Queue"; -import fs from 'fs'; +import fs from "fs"; import { StartWhatsAppSession } from "../../services/WbotServices/StartWhatsAppSession"; -import { removeWbot } from '../../libs/wbot' +import { removeWbot } from "../../libs/wbot"; import { restartWhatsSession } from "../../helpers/RestartWhatsSession"; -// test del -import data_ura from './ura' -import msg_client_transfer from './ura_msg_transfer' +// test del +import data_ura from "./ura"; +import msg_client_transfer from "./ura_msg_transfer"; import final_message from "./ura_final_message"; import SendWhatsAppMessage from "./SendWhatsAppMessage"; import Whatsapp from "../../models/Whatsapp"; import { splitDateTime } from "../../helpers/SplitDateTime"; -// +// -import { updateTicketCacheByTicketId } from '../../helpers/TicketCache' -import { insertMessageContactCache, getLastId } from '../../helpers/LastMessageIdByContactCache' +import { updateTicketCacheByTicketId } from "../../helpers/TicketCache"; +import { + insertMessageContactCache, + getLastId +} from "../../helpers/LastMessageIdByContactCache"; import autoRestore from "../../helpers/AutoRestore"; import { _restore } from "../../helpers/RestoreControll"; import sendWhatsAppMessageSocket from "../../helpers/SendWhatsappMessageSocket"; -import { getWhatsappIds, setWhatsappId } from "../../helpers/WhatsappIdMultiSessionControl"; +import { + getWhatsappIds, + setWhatsappId +} from "../../helpers/WhatsappIdMultiSessionControl"; import AppError from "../../errors/AppError"; import { setMessageAsRead } from "../../helpers/SetMessageAsRead"; +import { getSettingValue } from "../../helpers/WhaticketSettings"; +import { Op } from "sequelize"; - -var lst: any[] = getWhatsappIds() - +var lst: any[] = getWhatsappIds(); interface Session extends Client { id?: number; @@ -113,7 +117,7 @@ const verifyMediaMessage = async ( ticket: Ticket, contact: Contact, media: any, - quotedMsg?: any, + quotedMsg?: any ): Promise => { // const quotedMsg = await verifyQuotedMessage(msg); @@ -123,12 +127,15 @@ const verifyMediaMessage = async ( throw new Error("ERR_WAPP_DOWNLOAD_MEDIA"); } - console.log('MEDIA.FILENAME: ', media.fileName, ' | msg.fromMe: ', msg.fromMe) + console.log( + "MEDIA.FILENAME: ", + media.fileName, + " | msg.fromMe: ", + msg.fromMe + ); if (!media.filename) { - - console.log('No file name -----------------------------------------') - + console.log("No file name -----------------------------------------"); const ext = media.mimetype.split("/")[1].split(";")[0]; media.filename = `${new Date().getTime()}.${ext}`; @@ -141,15 +148,13 @@ const verifyMediaMessage = async ( // "base64" // ); - console.log('FROM wbotMessageListener.ts media.filename: ', media.filename) - + console.log("FROM wbotMessageListener.ts media.filename: ", media.filename); await writeFileAsync( join(__dirname, "..", "..", "..", "..", "..", "public", media.filename), media.data, "base64" ); - } catch (err) { Sentry.captureException(err); logger.error(`There was an error: wbotMessageLitener.ts: ${err}`); @@ -178,11 +183,8 @@ const verifyMessage = async ( msg: WbotMessage, ticket: Ticket, contact: Contact, - quotedMsg?: any, + quotedMsg?: any ) => { - - - // const quotedMsg = await verifyQuotedMessage(msg); // const quotedMsg = await verifyQuotedMessage(msg); @@ -199,21 +201,17 @@ const verifyMessage = async ( // quotedMsgId: quotedMsg?.id }; - await ticket.update({ lastMessage: msg.body }); await CreateMessageService({ messageData }); }; - - const verifyQueue = async ( wbot: Session, msg: WbotMessage, ticket: Ticket, contact: Contact ) => { - const { queues, greetingMessage } = await ShowWhatsAppService(wbot.id!); /*if (queues.length === 1) { @@ -224,45 +222,53 @@ const verifyQueue = async ( return; }*/ - - let selectedOption = null; - let choosenQueue = null + let choosenQueue = null; //Habilitar esse caso queira usar o bot - // const botInfo = await BotIsOnQueue('botqueue') - const botInfo = { isOnQueue: false, botQueueId: 0, userIdBot: 0 } + // const botInfo = await BotIsOnQueue('botqueue') + const botInfo = { isOnQueue: false, botQueueId: 0, userIdBot: 0 }; if (botInfo.isOnQueue) { - choosenQueue = await ShowQueueService(botInfo.botQueueId); - - } - - else if (queues.length === 1) { + } else if (queues.length === 1) { selectedOption = 1; choosenQueue = queues[+selectedOption - 1]; - } - else { - + } else { selectedOption = msg.body; //////////////// EXTRAIR APENAS O NÚMERO /////////////////// - selectedOption = selectedOption.replace(/[^1-9]/g, '') + selectedOption = selectedOption.replace(/[^1-9]/g, ""); /////////////////////////////////// choosenQueue = queues[+selectedOption - 1]; } - - if (choosenQueue) { + // TEST DEL + // let _ticket = await Ticket.findOne({ + // where: { + // status: { + // [Op.or]: ["open", "pending", "queueChoice"] + // }, + // contactId: contact.id, + // queueId: choosenQueue.id + // } + // }); + + // if (_ticket) { + // await UpdateTicketService({ + // ticketData: { queueId: choosenQueue.id }, + // ticketId: ticket.id + // }); + + // return; + // } + // // Atualizando o status do ticket para mostrar notificação para o atendente da fila escolhida pelo usuário. De queueChoice para pending if (queues.length > 1 && !botInfo.isOnQueue) { - await ticket.update({ status: "pending" }); - } // @@ -271,48 +277,42 @@ const verifyQueue = async ( ticketId: ticket.id }); - - let botOptions = '' + let botOptions = ""; // O bot abre a mensagem na fila para atender o usuario if (botInfo.isOnQueue) { - await UpdateTicketService({ - ticketData: { status: 'open', userId: botInfo.userIdBot }, + ticketData: { status: "open", userId: botInfo.userIdBot }, ticketId: ticket.id }); - data_ura.forEach((s, index) => { botOptions += `*${index + 1}* - ${s.option}\n` }); + data_ura.forEach((s, index) => { + botOptions += `*${index + 1}* - ${s.option}\n`; + }); } // - let body = '' + let body = ""; if (botOptions.length > 0) { body = `\u200e${choosenQueue.greetingMessage}\n\n${botOptions}\n${final_message.msg}`; - } - else { + } else { body = `\u200e${choosenQueue.greetingMessage}`; } - // const sentMessage = await wbot.sendMessage(`${contact.number}@c.us`, body); - // await verifyMessage(sentMessage, ticket, contact); + // const sentMessage = await wbot.sendMessage(`${contact.number}@c.us`, body); + // await verifyMessage(sentMessage, ticket, contact); - sendWhatsAppMessageSocket(ticket, body) - - } - else { - - - //test del transfere o atendimento se entrar na ura infinita + sendWhatsAppMessageSocket(ticket, body); + } else { + //test del transfere o atendimento se entrar na ura infinita let ticket_message = await ShowTicketMessage(ticket.id, false); if (ticket_message.length > 10) { - - await UpdateTicketService({ ticketData: { status: 'pending', queueId: queues[0].id }, ticketId: ticket.id }); - - } - else { - + await UpdateTicketService({ + ticketData: { status: "pending", queueId: queues[0].id }, + ticketId: ticket.id + }); + } else { let options = ""; queues.forEach((queue, index) => { @@ -323,24 +323,17 @@ const verifyQueue = async ( const debouncedSentMessage = debounce( async () => { - - // const sentMessage = await wbot.sendMessage(`${contact.number}@c.us`, body); + // const sentMessage = await wbot.sendMessage(`${contact.number}@c.us`, body); // verifyMessage(sentMessage, ticket, contact); - sendWhatsAppMessageSocket(ticket, body) - - + sendWhatsAppMessageSocket(ticket, body); }, 3000, ticket.id ); debouncedSentMessage(); - } - - - } }; @@ -360,36 +353,44 @@ const isValidMsg = (msg: WbotMessage): boolean => { return false; }; - const queuesOutBot = async (wbot: Session, botId: string | number) => { - const { queues, greetingMessage } = await ShowWhatsAppService(wbot.id!); - const indexQueue = queues.findIndex((q) => q.id == botId) + const indexQueue = queues.findIndex(q => q.id == botId); if (indexQueue != -1) { - queues.splice(indexQueue, 1) + queues.splice(indexQueue, 1); } - return { queues, greetingMessage } - -} - -const botTransferTicket = async (queues: Queue, ticket: Ticket, contact: Contact, wbot: Session) => { + return { queues, greetingMessage }; +}; +const botTransferTicket = async ( + queues: Queue, + ticket: Ticket, + contact: Contact, + wbot: Session +) => { await ticket.update({ userId: null }); - await UpdateTicketService({ ticketData: { status: 'pending', queueId: queues.id }, ticketId: ticket.id }); - -} - - -const botSendMessage = (ticket: Ticket, contact: Contact, wbot: Session, msg: string) => { + await UpdateTicketService({ + ticketData: { status: "pending", queueId: queues.id }, + ticketId: ticket.id + }); +}; +const botSendMessage = ( + ticket: Ticket, + contact: Contact, + wbot: Session, + msg: string +) => { const debouncedSentMessage = debounce( - async () => { - const sentMessage = await wbot.sendMessage(`${contact.number}@c.us`, `${msg}`); + const sentMessage = await wbot.sendMessage( + `${contact.number}@c.us`, + `${msg}` + ); verifyMessage(sentMessage, ticket, contact); }, 3000, @@ -397,69 +398,61 @@ const botSendMessage = (ticket: Ticket, contact: Contact, wbot: Session, msg: st ); debouncedSentMessage(); - -} +}; const _clear_lst = () => { + console.log("THE lst.length: ", lst.length); - console.log('THE lst.length: ', lst.length) + if (lst.length <= 199) return; - if (lst.length <= 199) return - - const chunk: any = Math.floor((lst.length / 2)) + const chunk: any = Math.floor(lst.length / 2); lst = lst.slice(chunk, chunk + lst.length); - let whatsappIdsSplited = lst.map((e) => `${e.id}`).toString() + let whatsappIdsSplited = lst.map(e => `${e.id}`).toString(); - setWhatsappId(whatsappIdsSplited, true) - -} - -const handleMessage = async ( - msg: any, - wbot: any -): Promise => { + setWhatsappId(whatsappIdsSplited, true); +}; +const handleMessage = async (msg: any, wbot: any): Promise => { if (!msg.fromMe) { + _clear_lst(); - _clear_lst() + let index = lst.findIndex((x: any) => x.id == msg.id.id); - let index = lst.findIndex((x: any) => x.id == msg.id.id) - - console.log('INDEX: ', index) + console.log("INDEX: ", index); if (index == -1) { - // console.log('-----------------> LST: ', lst):q - lst.push({ id: msg.id.id }) + lst.push({ id: msg.id.id }); - setWhatsappId(msg.id.id) + setWhatsappId(msg.id.id); + } else { + console.log("IGNORED ID: ", msg.id.id); - } - else { - console.log('IGNORED ID: ', msg.id.id) - - return + return; } // console.log('LIST OF ID MESSAGE lst: ', lst) - console.log('PASSOU.................................FROM: ', msg.from.split("@")[0], ' | ID: ', msg.id.id) + console.log( + "PASSOU.................................FROM: ", + msg.from.split("@")[0], + " | ID: ", + msg.id.id + ); } - if (!isValidMsg(msg)) { return; } try { - let msgContact: any = wbot.msgContact + let msgContact: any = wbot.msgContact; // let groupContact: Contact | undefined; if (msg.fromMe) { - // console.log('FROM ME: ', msg.fromMe, ' | /\u200e/.test(msg.body[0]: ', (/\u200e/.test(msg.body[0]))) // messages sent automatically by wbot have a special character in front of it @@ -479,14 +472,12 @@ const handleMessage = async ( // console.log('1 --------------> msgContat: ', JSON.parse(JSON.stringify(msgContact))) // console.log(' # msg.type: ', msg.type ) - } else { - // msgContact = await msg.getContact(); // console.log('2 --------------> msgContat: ', JSON.parse(JSON.stringify(msgContact))) - // + // console.log(`\n <<<<<<<<<< RECEIVING MESSAGE: Parcial msg and msgContact info: msgContact.name: ${msgContact.name} @@ -497,15 +488,14 @@ const handleMessage = async ( msg.body: ${msg.body} msg.type: ${msg.type} msg.from: ${msg.from} - msg.to: ${msg.to}\n`) - + msg.to: ${msg.to}\n`); } // const chat = await msg.getChat(); - const chat = wbot.chat + const chat = wbot.chat; // if(chat.isGroup){ - + // console.log('This message is from a Group and will be ignored!') // return // } @@ -524,8 +514,6 @@ const handleMessage = async ( // groupContact = await verifyContact(msgGroupContact); // } - - const whatsapp = await ShowWhatsAppService(wbot.id!); // const whatsapp = await ShowWhatsAppService(46); @@ -536,47 +524,55 @@ const handleMessage = async ( // console.log('----------> contact: ', JSON.parse(JSON.stringify(contact))) - - - if (unreadMessages === 0 && whatsapp.farewellMessage && whatsapp.farewellMessage === msg.body) return; + if ( + unreadMessages === 0 && + whatsapp.farewellMessage && + whatsapp.farewellMessage === msg.body + ) + return; const ticket = await FindOrCreateTicketService( contact, wbot.id!, - unreadMessages, + unreadMessages // groupContact ); - // + // // await updateTicketCacheByTicketId(ticket.id, {'contact.profilePicUrl': ticket.contact.profilePicUrl}) - // Para responder para o cliente pelo mesmo whatsapp que ele enviou a mensagen - if (wbot.id != ticket.whatsappId) { + if (getSettingValue("oneContactChatWithManyWhats")?.value == "disabled") { + // Para responder para o cliente pelo mesmo whatsapp que ele enviou a mensagen + if (wbot.id != ticket.whatsappId) { + // console.log('PARA RESPONDER PELO MEMOS WHATSAPP wbot.id: ', wbot.id, ' | wbot.status: ', wbot.status) + // console.log('WHATSAPP STATUS ticket.whatsappId: ', ticket.whatsappId) - // console.log('PARA RESPONDER PELO MEMOS WHATSAPP wbot.id: ', wbot.id, ' | wbot.status: ', wbot.status) - // console.log('WHATSAPP STATUS ticket.whatsappId: ', ticket.whatsappId) - - try { - await ticket.update({ whatsappId: wbot.id }); - } catch (error: any) { - console.error('===> Error on wbotMessageListener.ts into handleMessage fuction file: \n', error) - throw new AppError(error.message); + try { + await ticket.update({ whatsappId: wbot.id }); + } catch (error: any) { + console.error( + "===> Error on wbotMessageListener.ts into handleMessage fuction file: \n", + error + ); + throw new AppError(error.message); + } } - - - + // } - // if (msg.hasMedia) { - await verifyMediaMessage(msg, ticket, contact, wbot.media, wbot.quotedMsg); + await verifyMediaMessage( + msg, + ticket, + contact, + wbot.media, + wbot.quotedMsg + ); } else { - // console.log('>>>>>>> msg.fromMe: ',msg.fromMe ) await verifyMessage(msg, ticket, contact, wbot.quotedMsg); } - if ( !ticket.queue && !chat.isGroup && @@ -587,324 +583,352 @@ const handleMessage = async ( await verifyQueue(wbot, msg, ticket, contact); } - - // O bot interage com o cliente e encaminha o atendimento para fila de atendende quando o usuário escolhe a opção falar com atendente //Habilitar esse caso queira usar o bot // const botInfo = await BotIsOnQueue('botqueue') - const botInfo = { isOnQueue: false, botQueueId: 0, userIdBot: 0 } - - if (botInfo.isOnQueue && !msg.fromMe && ticket.userId == botInfo.userIdBot) { - - - if (msg.body === '0') { + const botInfo = { isOnQueue: false, botQueueId: 0, userIdBot: 0 }; + if ( + botInfo.isOnQueue && + !msg.fromMe && + ticket.userId == botInfo.userIdBot + ) { + if (msg.body === "0") { const queue = await ShowQueueService(ticket.queue.id); const greetingMessage = `\u200e${queue.greetingMessage}`; let options = ""; - data_ura.forEach((s, index) => { options += `*${index + 1}* - ${s.option}\n` }); - - botSendMessage(ticket, contact, wbot, `${greetingMessage}\n\n${options}\n${final_message.msg}`) - - } - else { - + data_ura.forEach((s, index) => { + options += `*${index + 1}* - ${s.option}\n`; + }); + botSendMessage( + ticket, + contact, + wbot, + `${greetingMessage}\n\n${options}\n${final_message.msg}` + ); + } else { // Pega as ultimas 9 opções numericas digitadas pelo cliente em orde DESC // Consulta apenas mensagens do usuári + let lastOption = ""; - let lastOption = '' + let ura_length = data_ura.length; - let ura_length = data_ura.length + let indexAttendant = data_ura.findIndex(u => u.atendente); - let indexAttendant = data_ura.findIndex((u) => u.atendente) - - let opt_user_attendant = '-1' + let opt_user_attendant = "-1"; if (indexAttendant != -1) { - opt_user_attendant = data_ura[indexAttendant].id + opt_user_attendant = data_ura[indexAttendant].id; } - // + // - let ticket_message = await ShowTicketMessage(ticket.id, true, ura_length, `^[0-${ura_length}}]$`); + let ticket_message = await ShowTicketMessage( + ticket.id, + true, + ura_length, + `^[0-${ura_length}}]$` + ); if (ticket_message.length > 1) { + lastOption = ticket_message[1].body; - lastOption = ticket_message[1].body + const queuesWhatsGreetingMessage = await queuesOutBot( + wbot, + botInfo.botQueueId + ); - const queuesWhatsGreetingMessage = await queuesOutBot(wbot, botInfo.botQueueId) - - const queues = queuesWhatsGreetingMessage.queues + const queues = queuesWhatsGreetingMessage.queues; if (queues.length > 1) { - - const index_opt_user_attendant = ticket_message.findIndex((q) => q.body == opt_user_attendant) - const index0 = ticket_message.findIndex((q) => q.body == '0') + const index_opt_user_attendant = ticket_message.findIndex( + q => q.body == opt_user_attendant + ); + const index0 = ticket_message.findIndex(q => q.body == "0"); if (index_opt_user_attendant != -1) { - if (index0 > -1 && index0 < index_opt_user_attendant) { - lastOption = '' - } - else { - lastOption = opt_user_attendant + lastOption = ""; + } else { + lastOption = opt_user_attendant; } } - } - } - - - - // + // // // È numero - if (!Number.isNaN(Number(msg.body.trim())) && (+msg.body >= 0 && +msg.body <= data_ura.length)) { - - const indexUra = data_ura.findIndex((ura) => ura.id == msg.body.trim()) - - + if ( + !Number.isNaN(Number(msg.body.trim())) && + +msg.body >= 0 && + +msg.body <= data_ura.length + ) { + const indexUra = data_ura.findIndex(ura => ura.id == msg.body.trim()); if (indexUra != -1) { - - if (data_ura[indexUra].id != opt_user_attendant && lastOption != opt_user_attendant) { - - - - - + if ( + data_ura[indexUra].id != opt_user_attendant && + lastOption != opt_user_attendant + ) { // test del - let next = true + let next = true; - let indexAux = ticket_message.findIndex((e) => e.body == '0') + let indexAux = ticket_message.findIndex(e => e.body == "0"); - let listMessage = null + let listMessage = null; if (indexAux != -1) { - - listMessage = ticket_message.slice(0, indexAux) - } - else { - - listMessage = ticket_message - + listMessage = ticket_message.slice(0, indexAux); + } else { + listMessage = ticket_message; } - let id = '' - let subUra = null + let id = ""; + let subUra = null; if (listMessage.length > 1) { + id = listMessage[listMessage.length - 1].body; + subUra = data_ura.filter(e => e.id == id)[0]; - id = listMessage[listMessage.length - 1].body - subUra = data_ura.filter((e) => e.id == id)[0] - - if (subUra && (!subUra.subOptions || subUra.subOptions.length == 0)) { - - listMessage.pop() - + if ( + subUra && + (!subUra.subOptions || subUra.subOptions.length == 0) + ) { + listMessage.pop(); } - } - if (listMessage.length > 1) { - - id = listMessage[listMessage.length - 1].body - subUra = data_ura.filter((e) => e.id == id)[0] + id = listMessage[listMessage.length - 1].body; + subUra = data_ura.filter(e => e.id == id)[0]; if (subUra.subOptions && subUra.subOptions.length > 0) { - - if (!Number.isNaN(Number(msg.body.trim())) && (+msg.body >= 0 && +msg.body <= subUra.subOptions?.length) && subUra.subOptions) { - - + if ( + !Number.isNaN(Number(msg.body.trim())) && + +msg.body >= 0 && + +msg.body <= subUra.subOptions?.length && + subUra.subOptions + ) { if (subUra.subOptions[+msg.body - 1].responseToClient) { - - botSendMessage(ticket, contact, wbot, `*${subUra.option}*\n\n${subUra.subOptions[+msg.body - 1].responseToClient}`) - - } - else { - botSendMessage(ticket, contact, wbot, `*${subUra.option}*\n\n${subUra.subOptions[+msg.body - 1].subOpt}`) + botSendMessage( + ticket, + contact, + wbot, + `*${subUra.option}*\n\n${ + subUra.subOptions[+msg.body - 1].responseToClient + }` + ); + } else { + botSendMessage( + ticket, + contact, + wbot, + `*${subUra.option}*\n\n${ + subUra.subOptions[+msg.body - 1].subOpt + }` + ); } - const queuesWhatsGreetingMessage = await queuesOutBot(wbot, botInfo.botQueueId) + const queuesWhatsGreetingMessage = await queuesOutBot( + wbot, + botInfo.botQueueId + ); - const queues = queuesWhatsGreetingMessage.queues + const queues = queuesWhatsGreetingMessage.queues; if (queues.length > 0) { - await botTransferTicket(queues[0], ticket, contact, wbot) + await botTransferTicket(queues[0], ticket, contact, wbot); + } else { + console.log("NO QUEUE!"); } - else { - console.log('NO QUEUE!') - } - - } - else { - + } else { let options = ""; - let subOptions: any[] = subUra.subOptions + let subOptions: any[] = subUra.subOptions; - subOptions?.forEach((s, index) => { options += `*${index + 1}* - ${s.subOpt}\n` }); - - botSendMessage(ticket, contact, wbot, `*${subUra.option}*\n\nDigite um número válido disponível no menu de opções de atendimento abaixo: \n${options}\n\n*0* - Voltar ao menu principal`) + subOptions?.forEach((s, index) => { + options += `*${index + 1}* - ${s.subOpt}\n`; + }); + botSendMessage( + ticket, + contact, + wbot, + `*${subUra.option}*\n\nDigite um número válido disponível no menu de opções de atendimento abaixo: \n${options}\n\n*0* - Voltar ao menu principal` + ); } - next = false - + next = false; } - } - // if (next) { - if (data_ura[indexUra].subOptions && data_ura[indexUra].subOptions.length > 0) { - + if ( + data_ura[indexUra].subOptions && + data_ura[indexUra].subOptions.length > 0 + ) { let options = ""; - let option = data_ura[indexUra].option - let subOptions: any[] = data_ura[indexUra].subOptions - let description = data_ura[indexUra].description + let option = data_ura[indexUra].option; + let subOptions: any[] = data_ura[indexUra].subOptions; + let description = data_ura[indexUra].description; - subOptions?.forEach((s, index) => { options += `*${index + 1}* - ${s.subOpt}\n` }); + subOptions?.forEach((s, index) => { + options += `*${index + 1}* - ${s.subOpt}\n`; + }); - const body = `\u200e${description}:\n${options}` - - botSendMessage(ticket, contact, wbot, `*${option}*\n\n${body}\n\n *0* - Voltar ao menu principal`) - - } - else { + const body = `\u200e${description}:\n${options}`; + botSendMessage( + ticket, + contact, + wbot, + `*${option}*\n\n${body}\n\n *0* - Voltar ao menu principal` + ); + } else { //test del deletar isso (Usar somente na hit) if (data_ura[indexUra].closeChat) { - - const { ticket: res } = await UpdateTicketService({ - ticketData: { 'status': 'closed', 'userId': botInfo.userIdBot }, ticketId: ticket.id + ticketData: { + status: "closed", + userId: botInfo.userIdBot + }, + ticketId: ticket.id }); /////////////////////////////// - const whatsapp = await ShowWhatsAppService(ticket.whatsappId); + const whatsapp = await ShowWhatsAppService( + ticket.whatsappId + ); const { farewellMessage } = whatsapp; if (farewellMessage) { - await SendWhatsAppMessage({ body: farewellMessage, ticket: res }); + await SendWhatsAppMessage({ + body: farewellMessage, + ticket: res + }); } /////////////////////////////// - - } - else { - botSendMessage(ticket, contact, wbot, `${data_ura[indexUra].description}\n\n *0* - Voltar ao menu principal`) + } else { + botSendMessage( + ticket, + contact, + wbot, + `${data_ura[indexUra].description}\n\n *0* - Voltar ao menu principal` + ); } // - - // botSendMessage(ticket, contact, wbot, `${data_ura[indexUra].description}\n\n *0* - Voltar ao menu principal`) - + // botSendMessage(ticket, contact, wbot, `${data_ura[indexUra].description}\n\n *0* - Voltar ao menu principal`) } } + } else if (data_ura[indexUra].id == opt_user_attendant) { + const queuesWhatsGreetingMessage = await queuesOutBot( + wbot, + botInfo.botQueueId + ); - } - else if (data_ura[indexUra].id == opt_user_attendant) { - - const queuesWhatsGreetingMessage = await queuesOutBot(wbot, botInfo.botQueueId) - - const queues = queuesWhatsGreetingMessage.queues + const queues = queuesWhatsGreetingMessage.queues; // Se fila for maior que 1 exibi as opções fila para atendimento humano if (queues.length > 1) { - let options = ""; queues.forEach((queue, index) => { - options += `*${index + 1}* - ${queue.name}\n`; - }); const body = `\u200eSelecione uma das opções de atendimento abaixo:\n${options}`; - botSendMessage(ticket, contact, wbot, body) - + botSendMessage(ticket, contact, wbot, body); } // Para situações onde há apenas uma fila com exclusão da fila do bot, já direciona o cliente para essa fila de atendimento humano else if (queues.length == 1) { + await botTransferTicket(queues[0], ticket, contact, wbot); - await botTransferTicket(queues[0], ticket, contact, wbot) - - botSendMessage(ticket, contact, wbot, `${msg_client_transfer.msg}`) - + botSendMessage( + ticket, + contact, + wbot, + `${msg_client_transfer.msg}` + ); } - } - else if (lastOption == opt_user_attendant) { + } else if (lastOption == opt_user_attendant) { + const queuesWhatsGreetingMessage = await queuesOutBot( + wbot, + botInfo.botQueueId + ); - const queuesWhatsGreetingMessage = await queuesOutBot(wbot, botInfo.botQueueId) - - const queues = queuesWhatsGreetingMessage.queues + const queues = queuesWhatsGreetingMessage.queues; // É numero - if (!Number.isNaN(Number(msg.body.trim())) && (+msg.body >= 0 && +msg.body <= queues.length)) { - - await botTransferTicket(queues[+msg.body - 1], ticket, contact, wbot) - - botSendMessage(ticket, contact, wbot, `${msg_client_transfer.msg}`) - } - else { - - botSendMessage(ticket, contact, wbot, `Digite um número válido disponível no menu de opções de atendimento\n\n*0* - Voltar ao menu principal`) + if ( + !Number.isNaN(Number(msg.body.trim())) && + +msg.body >= 0 && + +msg.body <= queues.length + ) { + await botTransferTicket( + queues[+msg.body - 1], + ticket, + contact, + wbot + ); + botSendMessage( + ticket, + contact, + wbot, + `${msg_client_transfer.msg}` + ); + } else { + botSendMessage( + ticket, + contact, + wbot, + `Digite um número válido disponível no menu de opções de atendimento\n\n*0* - Voltar ao menu principal` + ); } } - - } - - } - else { - + } else { // É numero if (!Number.isNaN(Number(msg.body.trim()))) { - - botSendMessage(ticket, contact, wbot, `Opção numérica inválida!\nDigite um dos números mostrados no menu de opções\n\n*0* - Voltar ao menu principal`) - + botSendMessage( + ticket, + contact, + wbot, + `Opção numérica inválida!\nDigite um dos números mostrados no menu de opções\n\n*0* - Voltar ao menu principal` + ); + } else { + botSendMessage( + ticket, + contact, + wbot, + `Digite um número válido disponível no menu de opções\n\n*0* - Voltar ao menu principal` + ); } - else { - - botSendMessage(ticket, contact, wbot, `Digite um número válido disponível no menu de opções\n\n*0* - Voltar ao menu principal`) - - } - } - } - - - } - - - if (msg && !msg.fromMe && ticket.status == 'pending') { - - await setMessageAsRead(ticket) - } + if (msg && !msg.fromMe && ticket.status == "pending") { + await setMessageAsRead(ticket); + } } catch (err) { Sentry.captureException(err); - logger.error(`Error handling whatsapp message: Err: ${err}`); + logger.error(`Error handling whatsapp message: Err: ${err}`); } }; const handleMsgAck = async (msg_id: any, ack: any) => { - await new Promise(r => setTimeout(r, 4000)); const io = getIO(); @@ -921,16 +945,17 @@ const handleMsgAck = async (msg_id: any, ack: any) => { ] }); if (!messageToUpdate) { - console.log(`Not found the MESSAGE ID ${msg_id}to change the ACK into the Message table`) + console.log( + `Not found the MESSAGE ID ${msg_id}to change the ACK into the Message table` + ); return; } await messageToUpdate.update({ ack }); - + io.to(messageToUpdate.ticketId.toString()).emit("appMessage", { action: "update", message: messageToUpdate }); - } catch (err) { Sentry.captureException(err); logger.error(`Error handling message ack. Err: ${err}`); @@ -938,7 +963,6 @@ const handleMsgAck = async (msg_id: any, ack: any) => { }; const wbotMessageListener = (wbot: Session): void => { - wbot.on("message_create", async msg => { handleMessage(msg, wbot); }); diff --git a/frontend/src/pages/Settings/index.js b/frontend/src/pages/Settings/index.js index ab79873..459e11d 100644 --- a/frontend/src/pages/Settings/index.js +++ b/frontend/src/pages/Settings/index.js @@ -198,6 +198,34 @@ const Settings = () => { + +
+ + + + Contato conversar com whatsapps distintos no omnihit + + + + + +
)} />