diff --git a/backend/src/helpers/BotIsOnQueue.ts b/backend/src/helpers/BotIsOnQueue.ts index 793ee59..4a531f9 100644 --- a/backend/src/helpers/BotIsOnQueue.ts +++ b/backend/src/helpers/BotIsOnQueue.ts @@ -30,8 +30,7 @@ const _botIsOnQueue = async (botName: string) => { } catch (error) { console.log('There was an error on try to read the botInfo.json file: ',error) } - - console.log('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ') + const { users, count, hasMore } = await ListUsersService({ searchParam: `${botName}`, pageNumber: 1 }); let botIsOnQueue = false diff --git a/backend/src/helpers/CloseBotTickets.ts b/backend/src/helpers/CloseBotTickets.ts new file mode 100644 index 0000000..6b5e853 --- /dev/null +++ b/backend/src/helpers/CloseBotTickets.ts @@ -0,0 +1,14 @@ +const fsPromises = require("fs/promises"); +const fs = require('fs') + +const CloseBotTickets = async () => { + + try { + + } catch (error) { + console.log('There was an error on try close the bot tickets: ', error) + } + +} + +export default CloseBotTickets; \ No newline at end of file diff --git a/backend/src/helpers/RestartWhatsSession.ts b/backend/src/helpers/RestartWhatsSession.ts index 1864152..a1feaf6 100644 --- a/backend/src/helpers/RestartWhatsSession.ts +++ b/backend/src/helpers/RestartWhatsSession.ts @@ -17,8 +17,8 @@ export const restartWhatsSession = async (whatsapp: Whatsapp, backupSession: boo const sourcePath = path.join(__dirname, `../../.wwebjs_auth/sessions/`, `session-bd_${whatsapp.id}`) const destPath = path.join(__dirname, `../../.wwebjs_auth/`, `session-bd_${whatsapp.id}`) - console.log('================sourcePath: ', sourcePath) - console.log('================destPath: ', destPath) + console.log('================> sourcePath: ', sourcePath) + console.log('================> destPath: ', destPath) removeWbot(whatsapp.id) @@ -34,6 +34,8 @@ export const restartWhatsSession = async (whatsapp: Whatsapp, backupSession: boo console.log('RESTARTING SESSION...') - await StartWhatsAppSession(whatsapp, backupSession); + // await StartWhatsAppSession(whatsapp, backupSession); + + setTimeout(() => StartWhatsAppSession(whatsapp, backupSession), 2000); } \ No newline at end of file diff --git a/backend/src/services/ContactServices/ShowContactCustomFieldsService.ts b/backend/src/services/ContactServices/ShowContactCustomFieldsService.ts new file mode 100644 index 0000000..35aabb7 --- /dev/null +++ b/backend/src/services/ContactServices/ShowContactCustomFieldsService.ts @@ -0,0 +1,20 @@ +import { raw } from "express"; +import AppError from "../../errors/AppError"; +import ContactCustomField from "../../models/ContactCustomField"; + +const ShowContactCustomFieldService = async (contactId: number | string): Promise => { + + const queue = await ContactCustomField.findAll({ + where: { contactId: contactId }, + raw: true + } + ); + + // if (!queue) { + // throw new AppError("ERR_CONTACT_CUSTOM_FIELD_NOT_FOUND"); + // } + + return queue; +}; + +export default ShowContactCustomFieldService; diff --git a/backend/src/services/TicketServices/ShowTicketMessage.ts b/backend/src/services/TicketServices/ShowTicketMessage.ts index d0af812..34a087d 100644 --- a/backend/src/services/TicketServices/ShowTicketMessage.ts +++ b/backend/src/services/TicketServices/ShowTicketMessage.ts @@ -16,23 +16,23 @@ import { startOfDay, endOfDay, parseISO, getDate} from "date-fns"; import { string } from "yup/lib/locale"; //Report by user, startDate, endDate -const ShowTicketMessage = async (ticketId: string | number, onlyNumber: boolean = false, limit?: number, regexp?: string): Promise => { +const ShowTicketMessage = async (ticketId: string | number, onlyNumber: boolean = false, fromMe?:boolean, limit?: number, regexp?: string): Promise => { let where_clause = {} if(onlyNumber){ where_clause = { ticketId: ticketId, - fromMe: 0, + fromMe: fromMe ? fromMe : 0, //body: {[Op.regexp]: '^[0-9]*$'}, // body: {[Op.regexp]: '^[0-3]$'}, body: {[Op.regexp]: regexp}, } } - else{ + else{ where_clause = { ticketId: ticketId, - fromMe: 0, + fromMe: fromMe ? fromMe : 0, } } diff --git a/backend/src/services/WbotServices/wbotMessageListener.ts b/backend/src/services/WbotServices/wbotMessageListener.ts index 53e75eb..c355b96 100644 --- a/backend/src/services/WbotServices/wbotMessageListener.ts +++ b/backend/src/services/WbotServices/wbotMessageListener.ts @@ -62,6 +62,8 @@ import ShowTicketService from "../TicketServices/ShowTicketService"; import { updateTicketCacheByTicketId } from '../../helpers/TicketCache' import endPointQuery from "../../helpers/EndpointQuery"; +import { Console } from "console"; +import ShowContactCustomFieldService from "../ContactServices/ShowContactCustomFieldsService"; @@ -180,9 +182,99 @@ const verifyMessage = async ( +const queryEndPointHit = async (centro_de_custo: string) => { + + let msg_endpoint: any = [] + + let response2 = await endPointQuery('http://177.107.193.124:8095/labs/zabbix-frontend/api/api.php', 'post', centro_de_custo.trim()) + + if (response2 && response2.data.result) { + + response2 = response2.data.result; + + for (let i = 0; i < response2.length; i++) { + + let data = '' + let sub_data = '*Atualizações:*\n\n' + + const properties: any = Object.entries(response2[i]); + + for (let x = 0; x < properties.length; x++) { + + if (typeof (properties[x][1]) != 'object') { + + data += `*${properties[x][0]}*: ${properties[x][1].replace(/(\r\n|\n|\r)/gm, "")}\n` + + } + else if (typeof (properties[x][1]) == 'object') { + + const sub_properties = properties[x][1]; + + for (let k = 0; k < sub_properties.length; k++) { + + const inner_properties: any = Object.entries(sub_properties[k]); + + for (let y = 0; y < inner_properties.length; y++) { + + sub_data += `*${inner_properties[y][0]}*: ${inner_properties[y][1].replace(/(\r\n|\n|\r)/gm, "")}\n` + + } + + sub_data += '\n' + + } + + } + + } + + msg_endpoint.push({ header: data, body: sub_data }) + + } + + } + else { + msg_endpoint = null + } + + return msg_endpoint + +} -async function sendDelayedMessages(wbot: Session, ticket: Ticket, contact: Contact, message: string) { +const monitoramento_response2 = async (response: any | null, wbot: any, contact: any, ticket: any, centro_de_custo: any, final_message:string='', send_empty_incident?:boolean) => { + + if (!response) { + + const msg = await wbot.sendMessage(`${contact.number}@c.us`, `Houve um erro ao tentar consultar o monitoramento da hit!${final_message}`); + await verifyMessage(msg, ticket, contact); + await new Promise(f => setTimeout(f, 1000)); + + } + else if (response.length > 0) { + + for (let i = 0; i < response.length; i++) { + + const msg = await wbot.sendMessage(`${contact.number}@c.us`, `Centro de custo: ${centro_de_custo}*\n\n*Incidente*:\n\n ${response[i].header}\n${response[i].body}${final_message}`); + await verifyMessage(msg, ticket, contact); + await new Promise(f => setTimeout(f, 1000)); + + } + + } + else if (send_empty_incident) { + + const msg = await wbot.sendMessage(`${contact.number}@c.us`, `Sem incidente!${final_message}`); + await verifyMessage(msg, ticket, contact); + await new Promise(f => setTimeout(f, 1000)); + + } + +} + + + +async function sendDelayedMessages(wbot: Session, ticket: Ticket, contact: Contact, message: string, _msg?: WbotMessage) { const body = message.replace(/\\n/g, '\n'); if (body.search('dialog_actions') != -1) { @@ -200,7 +292,20 @@ async function sendDelayedMessages(wbot: Session, ticket: Ticket, contact: Conta // const url = 'https://sos.espacolaser.com.br/api/whatsapps/ticket/R32656' let endPointResponse = await endPointQuery(msgAction.actions[1], 'get') - if (endPointResponse) { + console.log('Object.entries(endPointResponse.data).length: ', Object.entries(endPointResponse.data).length) + + if (endPointResponse && Object.entries(endPointResponse.data).length > 0) { + + // endPointResponse.data.categoria = 'INFRAESTRUTURA' + // endPointResponse.data.subcategoria = 'INTERNET' + // endPointResponse.data.terceiro_nivel = 'QUEDA TOTAL' + + console.log('-------------> endPointResponse.data.categoria: ', endPointResponse.data.categoria) + + if (endPointResponse.data.categoria != 'INFRAESTRUTURA' && endPointResponse.data.categoria != 'ELOS') { + botSendMessage(ticket, contact, wbot, `A categorização desse chamado não se enquadra no atendimento deste canal!\n\n _Digite *0* para voltar ao menu principal._`) + return + } const response = Object.entries(endPointResponse.data); let msg_endpoint_response = '' @@ -216,145 +321,199 @@ async function sendDelayedMessages(wbot: Session, ticket: Ticket, contact: Conta - if (endPointResponse.data.centro_custo_departamento && endPointResponse.data.centro_custo_departamento.trim().length > 0) { + if (endPointResponse.data.centro_custo_departamento && endPointResponse.data.centro_custo_departamento.trim().length > 0 && (endPointResponse.data.categoria == 'INFRAESTRUTURA' && endPointResponse.data.subcategoria == 'INTERNET')) { centro_de_custo = endPointResponse.data.centro_custo_departamento - - let response2 = await endPointQuery('http://177.107.193.124:8095/labs/zabbix-frontend/api/api.php', 'post', centro_de_custo.trim()) + msg_endpoint2 = await queryEndPointHit(centro_de_custo) - if (response2 && response2.data.result) { - response2 = response2.data.result; + // let response2 = await endPointQuery('http://177.107.193.124:8095/labs/zabbix-frontend/api/api.php', 'post', centro_de_custo.trim()) - for (let i = 0; i < response2.length; i++) { + // if (response2 && response2.data.result) { - let data = '' - let sub_data = '*Atualizações:*\n\n' + // response2 = response2.data.result; - const properties: any = Object.entries(response2[i]); + // for (let i = 0; i < response2.length; i++) { - for (let x = 0; x < properties.length; x++) { + // let data = '' + // let sub_data = '*Atualizações:*\n\n' - if (typeof (properties[x][1]) != 'object') { + // const properties: any = Object.entries(response2[i]); - data += `*${properties[x][0]}*: ${properties[x][1].replace(/(\r\n|\n|\r)/gm, "")}\n` + // for (let x = 0; x < properties.length; x++) { - } - else if (typeof (properties[x][1]) == 'object') { + // if (typeof (properties[x][1]) != 'object') { - const sub_properties = properties[x][1]; + // data += `*${properties[x][0]}*: ${properties[x][1].replace(/(\r\n|\n|\r)/gm, "")}\n` - for (let k = 0; k < sub_properties.length; k++) { + // } + // else if (typeof (properties[x][1]) == 'object') { - const inner_properties: any = Object.entries(sub_properties[k]); + // const sub_properties = properties[x][1]; - for (let y = 0; y < inner_properties.length; y++) { + // for (let k = 0; k < sub_properties.length; k++) { - sub_data += `*${inner_properties[y][0]}*: ${inner_properties[y][1].replace(/(\r\n|\n|\r)/gm, "")}\n` + // const inner_properties: any = Object.entries(sub_properties[k]); - } + // for (let y = 0; y < inner_properties.length; y++) { - sub_data += '\n' + // sub_data += `*${inner_properties[y][0]}*: ${inner_properties[y][1].replace(/(\r\n|\n|\r)/gm, "")}\n` - } + // } - } + // sub_data += '\n' - } + // } - msg_endpoint2.push({ header: data, body: sub_data }) + // } - } + // } - } - else { - msg_endpoint2 = null - } + // msg_endpoint2.push({ header: data, body: sub_data }) + + // } + + // } + // else { + // msg_endpoint2 = null + // } } - const monitoramento_response = async (response: any | null) => { + // const monitoramento_response = async (response: any | null) => { - if (!response) { + // if (!response) { - const msg = await wbot.sendMessage(`${contact.number}@c.us`, `Houve um erro ao tentar consultar o monitoramento!\n\n_Digite *0* para voltar ao menu principal._`); - await verifyMessage(msg, ticket, contact); - await new Promise(f => setTimeout(f, 1000)); + // const msg = await wbot.sendMessage(`${contact.number}@c.us`, `Houve um erro ao tentar consultar o monitoramento!\n\n_Digite *0* para voltar ao menu principal._`); + // await verifyMessage(msg, ticket, contact); + // await new Promise(f => setTimeout(f, 1000)); - } - else if (response.length > 0) { + // } + // else if (response.length > 0) { - for (let i = 0; i < response.length; i++) { + // for (let i = 0; i < response.length; i++) { - const msg = await wbot.sendMessage(`${contact.number}@c.us`, - `*Chamado ${extractCallCode(msgAction.msgBody)}*\n*Centro de custo: ${centro_de_custo}*\n\n*Incidente*:\n\n ${response[i].header}\n${response[i].body} _Digite *0* para voltar ao menu principal._`); - await verifyMessage(msg, ticket, contact); - await new Promise(f => setTimeout(f, 1000)); + // const msg = await wbot.sendMessage(`${contact.number}@c.us`, + // `*Chamado ${extractCallCode(msgAction.msgBody)}*\n*Centro de custo: ${centro_de_custo}*\n\n*Incidente*:\n\n ${response[i].header}\n${response[i].body} _Digite *0* para voltar ao menu principal._`); + // await verifyMessage(msg, ticket, contact); + // await new Promise(f => setTimeout(f, 1000)); - } + // } - } - else { + // } + // else { - const msg = await wbot.sendMessage(`${contact.number}@c.us`, `Sem incidente!\n\n_Digite *0* para voltar ao menu principal._`); - await verifyMessage(msg, ticket, contact); - await new Promise(f => setTimeout(f, 1000)); + // const msg = await wbot.sendMessage(`${contact.number}@c.us`, `Sem incidente!\n\n_Digite *0* para voltar ao menu principal._`); + // await verifyMessage(msg, ticket, contact); + // await new Promise(f => setTimeout(f, 1000)); - } + // } - } + // } const itsm_response = async (message1: string = '', message2: string = '') => { - const msg = await wbot.sendMessage(`${contact.number}@c.us`, `*Situação do chamado ${extractCallCode(msgAction.msgBody)}:*\n\n ${message1}\n\n${msg_endpoint_response}${message2}\n_Digite *0* para voltar ao menu principal._`); + const msg = await wbot.sendMessage(`${contact.number}@c.us`, `*Situação do chamado ${extractCallCode(msgAction.msgBody)}:*${message1}${msg_endpoint_response}${message2}\n_Digite *0* para voltar ao menu principal._`); await verifyMessage(msg, ticket, contact); await new Promise(f => setTimeout(f, 1000)); } - if (endPointResponse.data.status == 'EM ATENDIMENTO') { - - await itsm_response('Seu chamado está em atendimento') - - await monitoramento_response(msg_endpoint2) - + const sendMessageBot = async (message1: string = '', message2: string = '') => { + const msg = await wbot.sendMessage(`${contact.number}@c.us`, `${message1}${message2}`); + await verifyMessage(msg, ticket, contact); + await new Promise(f => setTimeout(f, 1000)); } - else if (endPointResponse.data.categoria == 'ELOS' || (endPointResponse.data.subcategoria == 'VENDA' || endPointResponse.data.subcategoria == 'INDISPONIBILIDADE')) { - await itsm_response('Vi que está com um problema no ELOS', `\nSe seu caso for urgente para concluir uma venda, digite “URGENTE”\n`) - await monitoramento_response(msg_endpoint2) - } - else if ((endPointResponse.data.categoria == 'INFRAESTRUTURA' || endPointResponse.data.subcategoria == 'INTERNET' || - endPointResponse.data.terceiro_nivel == 'QUEDA TOTAL' || endPointResponse.data.terceiro_nivel == 'PROBLEMA DE LENTIDÃO') || - (endPointResponse.data.terceiro_nivel == 'PROBLEMA DE LENTIDÃO' || endPointResponse.data.terceiro_nivel == 'ABERTO')) { - await itsm_response('', `\n Estamos direcionando seu atendimento para o Suporte. Em breve você será atendido por um de nossos atendentes!`) - await monitoramento_response(msg_endpoint2) + if ( - await transferTicket(0, wbot, ticket, contact) + (endPointResponse.data.categoria == 'INFRAESTRUTURA' && endPointResponse.data.subcategoria == 'INTERNET' && + endPointResponse.data.terceiro_nivel == 'QUEDA TOTAL') || + + (endPointResponse.data.categoria == 'INFRAESTRUTURA' && endPointResponse.data.subcategoria == 'INTERNET' && + endPointResponse.data.terceiro_nivel == 'PROBLEMA DE LENTIDÃO') || + + (endPointResponse.data.categoria == 'ELOS' && endPointResponse.data.subcategoria == 'VENDA') || + + (endPointResponse.data.categoria == 'ELOS' && endPointResponse.data.subcategoria == 'INDISPONIBILIDADE') + + ) { + + await itsm_response('\n\n') + + if (endPointResponse.data.categoria == 'INFRAESTRUTURA' && endPointResponse.data.subcategoria == 'INTERNET' && centro_de_custo) { + await monitoramento_response2(msg_endpoint2,wbot,contact,ticket, centro_de_custo,'\n\n _Digite *0* para voltar ao menu principal._',true) + } + + await sendMessageBot('Se deseja solicitar atendimento de urgência, digite *1*!', '\n\n _Digite *0* para voltar ao menu principal._') + + return } else { + //await sendMessageBot('A categorização desse chamado não se enquadra no atendimento deste canal!', '\n\n _Digite *0* para voltar ao menu principal._') + await itsm_response('\n\n') - await itsm_response('', `\n Por favor, aguarde atendimento e acompanhe sua solicitação no SOS.`) + if (endPointResponse.data.categoria == 'INFRAESTRUTURA' && endPointResponse.data.subcategoria == 'INTERNET' && centro_de_custo) { + await monitoramento_response2(msg_endpoint2,wbot,contact,ticket, centro_de_custo,'\n\n _Digite *0* para voltar ao menu principal._',true) + } - await monitoramento_response(msg_endpoint2) + await sendMessageBot('Acompanhe a evolução do atendimento através do SOS') + + return } + // else if ((endPointResponse.data.categoria == 'INFRAESTRUTURA' || endPointResponse.data.subcategoria == 'INTERNET' || + // endPointResponse.data.terceiro_nivel == 'QUEDA TOTAL' || endPointResponse.data.terceiro_nivel == 'PROBLEMA DE LENTIDÃO') || + // (endPointResponse.data.terceiro_nivel == 'PROBLEMA DE LENTIDÃO' || endPointResponse.data.terceiro_nivel == 'ABERTO')) { + + // await itsm_response('', `\n Estamos direcionando seu atendimento para o Suporte. Em breve você será atendido por um de nossos atendentes!`) + + // await monitoramento_response(msg_endpoint2) + + // await transferTicket(0, wbot, ticket, contact) + + // } + // else { + + // await itsm_response('', `\n Por favor, aguarde atendimento e acompanhe sua solicitação no SOS.`) + + // await monitoramento_response(msg_endpoint2) + + // } + + } + else if (endPointResponse && Object.entries(endPointResponse.data).length == 0) { + botSendMessage(ticket, contact, wbot, `Não existe nenhum chamado para consulta com esse número!\n _Digite *0* para voltar ao menu principal._`) + return } else { botSendMessage(ticket, contact, wbot, `Desculpe, nao foi possível realizar a consulta!\n _Digite *0* para voltar ao menu principal._`) + return } } else if (msgAction.actions[0] == 'queue_transfer') { console.log('>>>>>>>>>>>>>>> msgAction: ', msgAction, ' | msgAction.actions[1]: ', msgAction.actions[1]) + const contact_custom_field = await ShowContactCustomFieldService(contact.id) + + if (contact_custom_field && contact_custom_field.length > 0) { + + const msg_endpoint = await queryEndPointHit(contact_custom_field[0].value) + + await monitoramento_response2(msg_endpoint, wbot, contact, ticket, contact_custom_field[0].value) + + } + + console.log('************* contact_custom_field: ', contact_custom_field) + const msg = await wbot.sendMessage(`${contact.number}@c.us`, msgAction.msgBody); await verifyMessage(msg, ticket, contact); await new Promise(f => setTimeout(f, 1000)); @@ -440,7 +599,7 @@ const sendDialogflowAwswer = async ( await new Promise(f => setTimeout(f, 1000)); for (let message of dialogFlowReply) { - await sendDelayedMessages(wbot, ticket, contact, message.text.text[0]); + await sendDelayedMessages(wbot, ticket, contact, message.text.text[0], msg); } } @@ -589,6 +748,8 @@ const transferTicket = async (queueIndex: number, wbot: Session, ticket: Ticket, const queues = queuesWhatsGreetingMessage.queues + // console.log('queues ---> ', queues) + await botTransferTicket(queues[queueIndex], ticket, contact, wbot) } @@ -797,6 +958,8 @@ const handleMessage = async ( + + // 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 @@ -804,6 +967,38 @@ const handleMessage = async ( // const botInfo = { isOnQueue: false, botQueueId: 0, userIdBot: 0 } if (botInfo.isOnQueue && !msg.fromMe && ticket.userId == botInfo.userIdBot) { + // TEST DEL + let test: any = await ShowTicketMessage(ticket.id, false, true, 5); + + if (test[0].body.includes('Se deseja solicitar atendimento de urgência, digite *1*') && msg.body == '1') { + + console.log('===================================> ENDPOINT REQUEST') + + for (let i = 0; i < test.length; i++) { + + if (test[i].body.includes('*categoria*: INFRAESTRUTURA')) { + + botSendMessage(ticket, contact, wbot, `Estamos direcionando seu atendimento para o Suporte. Em breve você será atendido por um de nossos atendentes!`) + + await transferTicket(0, wbot, ticket, contact) + break + + } + else if (test[i].body.includes('*categoria*: ELOS')) { + + botSendMessage(ticket, contact, wbot, `Estamos direcionando seu atendimento para o Suporte. Em breve você será atendido por um de nossos atendentes!`) + + await transferTicket(1, wbot, ticket, contact) + break + } + + } + + + return + } + // + await sendDialogflowAwswer(wbot, ticket, msg, contact, chat); }