feat: Adapt migration from Dialogflow to Redis-based bot and optimize bot access using Redis

adriano 2024-02-07 16:36:45 -03:00
parent ad89d3ccdb
commit bc93d3a9d6
13 changed files with 1019 additions and 91 deletions

View File

@ -0,0 +1,176 @@
import { Request, Response } from "express";
import BotIsOnQueue from "../helpers/BotIsOnQueue";
import GetDefaultWhatsApp from "../helpers/GetDefaultWhatsApp";
import { getIO } from "../libs/socket";
import { getWbot } from "../libs/wbot";
import Ticket from "../models/Ticket";
import ContactByCustomField from "../services/HitServices/ShowContactByCustomFieldValueService";
import ShowQueueService from "../services/QueueService/ShowQueueService";
import CreateTicketService from "../services/TicketServices/CreateTicketService";
import ShowTicketService from "../services/TicketServices/ShowTicketService";
import UpdateTicketService from "../services/TicketServices/UpdateTicketService";
import SendWhatsAppMessage from "../services/WbotServices/SendWhatsAppMessage";
import { Op, where, Sequelize } from "sequelize";
import ShowTicketServiceByContactId from "../services/TicketServices/ShowTicketServiceByContactId";
import hitPortalMonitoring from "../helpers/HitPortalMonitoring";
import FindOrCreateTicketServiceBot from "../services/TicketServices/FindOrCreateTicketServiceBot";
import Contact from "../models/Contact";
// type IndexQuery = {
// centro_custo: string;
// };
export const hit = async (req: Request, res: Response): Promise<Response> => {
console.log("req.body: ", req.body);
if (req.headers["auth"] === "0424bd59b807674191e7d77572075f33") {
let contact = null;
try {
contact = await ContactByCustomField(req.body["centro_custo"]);
} catch (error) {
console.log("There was an error on try get centro_custo info: ", error);
}
if (!contact) {
return res.status(200).json({ message: "Ok" });
}
if (req.body["action"] === "atdfechou") {
console.log("FECHOU");
try {
console.log("atdfechou ----------> THE CONTACT: ", contact);
let data = req.body;
let str = "";
let str2 = "";
str = `*Cliente*: ${contact["contact.name"]}`;
let historico = data["historico"];
for (const key in historico) {
const hist = Object.keys(historico[key]);
hist.forEach((keys, index) => {
str2 += `*${keys}*: ${historico[key][keys]}\n`;
});
str2 += "\n";
}
await statuschange(
req,
res,
contact,
`*Olá. Somos a TI Espaçolaser.*\nO chamado da sua loja ${contact["contact.name"]} foi fechado pela operadora. Abaixo seguem informações sobre o incidente.\n\n*Situação do chamado na Operadora*\n\n*Incidente:*\n\n ${str}\n\n*Atualizações*:\n\n${str2}`,
false
);
} catch (error) {
console.log(`Error on try sending the monitor message closed: `, error);
}
} else if (req.body["action"] === "atdatualizou") {
console.log("status: atdatualizou --------------> contact: ", contact);
await statuschange(
req,
res,
contact,
`*Olá. Somos a TI Espaçolaser.*\nAtualização do chamado para sua loja ${contact["contact.name"]}. Abaixo seguem informações sobre o incidente para que possam acompanhar.\n\n`
);
} else if (req.body["action"] === "atdabriu") {
console.log("PASS 1");
await statuschange(
req,
res,
contact,
`*Olá. Somos a TI Espaçolaser.*\nIdentificamos em nossos monitoramentos que há um problema na internet da sua loja ${contact["contact.name"]} e já estamos resolvendo. Abaixo seguem informações sobre o incidente para que possam acompanhar.\n\n`
);
console.log("PASS 2");
}
} else {
res.status(401).json({ message: "Token Inválido!" });
}
return res.status(200).json({ message: "Ok" });
};
async function sendMessageHitMonitoring(msg: string, ticket: Ticket) {
if (msg && msg.length > 0) {
console.log("MESSAGE WILL BE SENT!");
await SendWhatsAppMessage({ body: msg, ticket });
}
}
async function statuschange(
req: Request,
res: Response,
contact: any,
header_msg: string,
request: boolean = true
) {
try {
const botInfo = await BotIsOnQueue("botqueue");
let ticket: any = await ShowTicketServiceByContactId(contact.contactId);
console.log("PASS 01");
if (!ticket.dataValues.id) {
const defaultWhatsapp = await GetDefaultWhatsApp({});
let _contact: any = await Contact.findByPk(contact.contactId);
let ticket_obj: any = await FindOrCreateTicketServiceBot(
_contact,
defaultWhatsapp.id!,
0
);
ticket = ticket_obj.ticket;
}
console.log("PASS 02");
let _response: string;
if (request) {
let response = await hitPortalMonitoring(req.body["centro_custo"]);
if (!response || response.length == 0) {
console.log(
"Empty result from hit portal monitoring. Centro_de_custo: ",
req.body["centro_custo"]
);
return;
}
_response = `${header_msg} *Situação do chamado na Operadora*\n\n*Incidente*:\n\n ${response[0].header}\n${response[0].body}`;
} else {
_response = header_msg;
}
console.log("PASS 03");
if (ticket.id && ticket.status == "pending") {
await sendMessageHitMonitoring(_response, ticket);
} else if (ticket.id && ticket.userId == botInfo.userIdBot) {
let queue = await ShowQueueService(botInfo.botQueueId);
await UpdateTicketService({
ticketData: { queueId: queue.id },
ticketId: ticket.id
});
ticket = await ShowTicketService(ticket.id);
await sendMessageHitMonitoring(_response, ticket);
}
} catch (error) {
console.log(`Error on try sending the message monitor: `, error);
}
}

View File

@ -60,9 +60,11 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
" | quotedMsg: ", " | quotedMsg: ",
quotedMsg, quotedMsg,
" | params: ", " | params: ",
params params, ' | body: ', JSON.stringify(body, null, 6)
); );
const { phoneNumberId, whatsappId } = ticket; const { phoneNumberId, whatsappId } = ticket;
if (phoneNumberId) { if (phoneNumberId) {

View File

@ -0,0 +1,57 @@
const fsPromises = require("fs/promises");
const fs = require("fs");
import axios from "axios";
import * as https from "https";
const endPointQuery = async (
url: string,
method: string,
param: string = ""
) => {
let response: any = null;
try {
const httpsAgent = new https.Agent({ rejectUnauthorized: false });
if (method == "get") {
// const url = 'https://sos.espacolaser.com.br/api/whatsapp/ticket/R32656'
response = await axios.get(url, {
httpsAgent,
headers: {
"x-access-token":
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOnsiaWQiOjEsInJvbGUiOiJjbGllbnQiLCJob3N0Ijoic29zLmVzcGFjb2xhc2VyLmNvbS5iciIsInRlbmFudCI6ImVzcGFjb2xhc2VyIiwibmFtZSI6IlNFTlNSLklUIiwiY29tcGFueSI6eyJpZCI6NDR9fSwiZGF0ZSI6MTY2MTI2MjY0MywiaWF0IjoxNjYxMjYyNjQzLCJleHAiOjE3NDc2NjI2NDN9.zf91OmRs4_C7B8OlVpLLrQMiRBYc7edP4qAdH_hqxpk",
Origin: "espacolaser"
}
});
console.log(
`TEST URL CLIENT GET ROUTE: ${url} | STATUS CODE: ${response.status}`
);
} else if (method == "post") {
// const url = 'http://177.107.193.124:8095/labs/zabbix-frontend/api/api.php'
response = await axios.post(
url,
{
auth: "0424bd59b807674191e7d77572075f33",
jsonrpc: "2.0",
method: "chamado.ematendimento",
"params[ccusto]": param,
id: "101"
},
{
httpsAgent,
headers: { "Content-Type": "multipart/form-data" }
}
);
console.log(
`TEST URL CLIENT POST ROUTE: ${url} | STATUS CODE: ${response.status}`
);
}
} catch (error) {
console.error(`Erro ao consultar endpoint ${url}: ${error}`);
}
return response;
};
export default endPointQuery;

View File

@ -0,0 +1,68 @@
const fsPromises = require("fs/promises");
const fs = require('fs')
import endPointQuery2 from './EndpointQuery2'
import WhatsQueueIndex from "./WhatsQueueIndex";
const hitPortalMonitoring = async (centro_de_custo: string) => {
let msg_endpoint: any = []
let response2 = await endPointQuery2('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
}
export default hitPortalMonitoring

View File

@ -2,20 +2,25 @@ const Redis = require("ioredis");
const redis = new Redis(process.env.REDIS_URI); const redis = new Redis(process.env.REDIS_URI);
type WhatsappData = { type WhatsappData = {
whatsappId: string; whatsappId: string | number;
contactId: string; contactId: string | number;
identifier: string; identifier: string;
value?: string; value?: string;
}; };
export async function set(key: string, value: string) { export async function set(key: string, value: string, expire: boolean = false) {
await redis.set(key, JSON.stringify(value)); await redis.set(key, JSON.stringify(value));
if (expire) await redis.expire(key, 300);
} }
export async function get(key: string) { export async function get(key: string) {
const value: any = await redis.get(key); const value: any = await redis.get(key);
return JSON.parse(value); return JSON.parse(value);
} }
export async function del(key: string) {
await redis.del(key);
}
export async function createObject({ export async function createObject({
whatsappId, whatsappId,
@ -51,8 +56,8 @@ export async function updateObject({
} }
export async function findObject( export async function findObject(
whatsappId: string, whatsappId: string | number,
contactId: string, contactId: string | number,
identifier: string identifier: string
) { ) {
const key = `whatsappId:${whatsappId}:contactId:${contactId}:identifier:${identifier}`; const key = `whatsappId:${whatsappId}:contactId:${contactId}:identifier:${identifier}`;

View File

@ -0,0 +1,9 @@
import express from "express";
import * as HitController from "../controllers/HitController"
const hitRoutes = express.Router();
hitRoutes.post("/espacolaser/incidente", HitController.hit);
export default hitRoutes;

View File

@ -13,6 +13,7 @@ import quickAnswerRoutes from "./quickAnswerRoutes";
import reportRoutes from "./reportRoutes"; import reportRoutes from "./reportRoutes";
import schedulingNotifiyRoutes from "./SchedulingNotifyRoutes"; import schedulingNotifiyRoutes from "./SchedulingNotifyRoutes";
import statusChatEndRoutes from "./statusChatEndRoutes"; import statusChatEndRoutes from "./statusChatEndRoutes";
import hitRoutes from "./hitRoutes";
import wbotMonitorRoutes from "./wbotMonitorRoutes"; import wbotMonitorRoutes from "./wbotMonitorRoutes";
const routes = Router(); const routes = Router();
@ -32,6 +33,7 @@ routes.use(quickAnswerRoutes);
routes.use(schedulingNotifiyRoutes); routes.use(schedulingNotifiyRoutes);
routes.use(reportRoutes); routes.use(reportRoutes);
routes.use(statusChatEndRoutes); routes.use(statusChatEndRoutes);
routes.use(hitRoutes);
routes.use(wbotMonitorRoutes); routes.use(wbotMonitorRoutes);
export default routes; export default routes;

View File

@ -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<ContactCustomField[]> => {
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;

View File

@ -0,0 +1,27 @@
import Contact from "../../models/Contact";
import ContactCustomField from "../../models/ContactCustomField";
const ContactByCustomField = async (value: string | number): Promise<any> => {
const contact = await ContactCustomField.findOne({
where: { value },
raw: true,
attributes: ['id', 'value', 'contactId'],
include: [
{
model: Contact,
required: true,
attributes: ['id', 'name', 'number'],
},
],
});
return contact;
};
export default ContactByCustomField;

View File

@ -0,0 +1,73 @@
import Ticket from "../../models/Ticket";
import AppError from "../../errors/AppError";
import Contact from "../../models/Contact";
import User from "../../models/User";
import Queue from "../../models/Queue";
import Message from "../../models/Message";
import { userInfo } from "os";
import { Op, where } from "sequelize";
import { Sequelize } from "sequelize";
import moment from "moment";
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,
fromMe?: boolean,
limit?: number,
regexp?: string
): Promise<Message[]> => {
let where_clause = {};
if (onlyNumber) {
where_clause = {
ticketId: ticketId,
fromMe: fromMe ? fromMe : 0,
//body: {[Op.regexp]: '^[0-9]*$'},
// body: {[Op.regexp]: '^[0-3]$'},
body: { [Op.regexp]: regexp }
};
} else {
where_clause = {
ticketId: ticketId,
fromMe: fromMe ? fromMe : 0
};
}
const ticket = await Message.findAll({
where: where_clause,
limit: limit ? limit : 10000,
raw: true,
attributes: [
"body",
"read",
"mediaType",
"fromMe",
"mediaUrl",
[
Sequelize.fn(
"DATE_FORMAT",
Sequelize.col("createdAt"),
"%d/%m/%Y %H:%i:%s"
),
"createdAt"
]
],
order: [["createdAt", "DESC"]]
});
if (!ticket) {
throw new AppError("ERR_NO_TICKET_FOUND", 404);
}
return ticket;
};
export default ShowTicketMessage;

View File

@ -0,0 +1,44 @@
import Ticket from "../../models/Ticket";
import AppError from "../../errors/AppError";
import Contact from "../../models/Contact";
import User from "../../models/User";
import Queue from "../../models/Queue";
import { Op } from "sequelize";
const ShowTicketServiceByContactId = async (contactId: string | number): Promise<Ticket> => {
const ticket = await Ticket.findOne({
where: { contactId, [Op.or]: [{ status: 'open' }, { status: 'pending' }] },
include: [
{
model: Contact,
as: "contact",
attributes: ["id", "name", "number", "profilePicUrl", "useQueues"],
include: ["extraInfo"]
},
{
model: User,
as: "user",
attributes: ["id", "name"]
},
{
model: Queue,
as: "queue",
attributes: ["id", "name", "color"],
}
]
});
if (!ticket) {
return new Ticket
}
return ticket;
};
export default ShowTicketServiceByContactId;

View File

@ -68,6 +68,9 @@ import { splitDateTime } from "../../helpers/SplitDateTime";
// //
import { updateTicketCacheByTicketId } from "../../helpers/TicketCache"; import { updateTicketCacheByTicketId } from "../../helpers/TicketCache";
import endPointQuery from "../../helpers/EndpointQuery2";
import { import {
insertMessageContactCache, insertMessageContactCache,
getLastId getLastId
@ -81,6 +84,7 @@ import {
} from "../../helpers/WhatsappIdMultiSessionControl"; } from "../../helpers/WhatsappIdMultiSessionControl";
import AppError from "../../errors/AppError"; import AppError from "../../errors/AppError";
import { setMessageAsRead } from "../../helpers/SetMessageAsRead"; import { setMessageAsRead } from "../../helpers/SetMessageAsRead";
import FindOrCreateTicketServiceBot from "../TicketServices/FindOrCreateTicketServiceBot";
import { getSettingValue } from "../../helpers/WhaticketSettings"; import { getSettingValue } from "../../helpers/WhaticketSettings";
import { Op } from "sequelize"; import { Op } from "sequelize";
@ -88,7 +92,15 @@ import { Op } from "sequelize";
import SettingTicket from "../../models/SettingTicket"; import SettingTicket from "../../models/SettingTicket";
import mostRepeatedPhrase from "../../helpers/MostRepeatedPhrase"; import mostRepeatedPhrase from "../../helpers/MostRepeatedPhrase";
import ListWhatsAppsNumber from "../WhatsappService/ListWhatsAppsNumber"; import ListWhatsAppsNumber from "../WhatsappService/ListWhatsAppsNumber";
import { createObject, findObject, get } from "../../helpers/RedisClient"; import {
createObject,
del,
findObject,
get,
set
} from "../../helpers/RedisClient";
import ShowContactCustomFieldService from "../ContactServices/ShowContactCustomFieldsService";
import ShowTicketService from "../TicketServices/ShowTicketService"
var lst: any[] = getWhatsappIds(); var lst: any[] = getWhatsappIds();
@ -197,73 +209,6 @@ const verifyMediaMessage = async (
return newMessage; return newMessage;
}; };
// const verifyMediaMessage = async (
// msg: any,
// ticket: Ticket,
// contact: Contact,
// media: any,
// quotedMsg?: any
// ): Promise<Message | any> => {
// // const quotedMsg = await verifyQuotedMessage(msg);
// // const media = await msg.downloadMedia();
// if (!media) {
// throw new Error("ERR_WAPP_DOWNLOAD_MEDIA");
// }
// console.log(
// "MEDIA.FILENAME: ",
// media.fileName,
// " | msg.fromMe: ",
// msg.fromMe
// );
// if (!media.filename) {
// console.log("No file name -----------------------------------------");
// const ext = media.mimetype.split("/")[1].split(";")[0];
// media.filename = `${new Date().getTime()}.${ext}`;
// }
// try {
// // await writeFileAsync(
// // join(__dirname, "..", "..", "..", "public", media.filename),
// // media.data,
// // "base64"
// // );
// 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}`);
// }
// const messageData = {
// id: msg.id.id,
// ticketId: ticket.id,
// contactId: msg.fromMe ? undefined : contact.id,
// body: msg.body || media.filename,
// fromMe: msg.fromMe,
// read: msg.fromMe,
// mediaUrl: media.filename,
// mediaType: media.mimetype.split("/")[0],
// quotedMsgId: quotedMsg
// // quotedMsgId: quotedMsg?.id
// };
// await ticket.update({ lastMessage: msg.body || media.filename });
// const newMessage = await CreateMessageService({ messageData });
// return newMessage;
// };
const verifyMessage = async ( const verifyMessage = async (
msg: any, msg: any,
ticket: Ticket, ticket: Ticket,
@ -287,6 +232,374 @@ const verifyMessage = async (
await CreateMessageService({ messageData }); await CreateMessageService({ messageData });
}; };
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;
};
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) {
await SendWhatsAppMessage({
body: `Houve um erro ao tentar consultar o monitoramento da Operadora!${final_message}`,
ticket,
number: `${contact.number}@c.us`
});
} else if (response.length > 0) {
for (let i = 0; i < response.length; i++) {
await SendWhatsAppMessage({
body: `*Situação do chamado na Operadora*\n\n*Incidente*:\n\n ${response[i].header}\n${response[i].body}${final_message}`,
ticket,
number: `${contact.number}@c.us`
});
}
} else if (send_empty_incident) {
await SendWhatsAppMessage({
body: `Conforme Monitoramento a internet da unidade está operacional${final_message}`,
ticket,
number: `${contact.number}@c.us`
});
}
};
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) {
let msgAction = botMsgActions(body);
if (msgAction.actions[0] == "request_endpoint") {
await SendWhatsAppMessage({
body: msgAction.msgBody,
ticket,
number: `${contact.number}@c.us`
});
// const url = 'https://sos.espacolaser.com.br/api/whatsapps/ticket/R32656'
let endPointResponse = await endPointQuery(msgAction.actions[1], "get");
await del(
`whatsappId:${wbot.id}:contactId:${contact.id}:identifier:query`
);
console.log(
"Object.entries(endPointResponse.data).length: ",
Object.entries(endPointResponse.data).length
);
if (
endPointResponse &&
endPointResponse.status == 200 &&
Object.entries(endPointResponse.data).length > 0
) {
if (
endPointResponse.data.categoria != "INFRAESTRUTURA" &&
endPointResponse.data.categoria != "ELOS"
) {
botSendMessage(
ticket,
`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 = "";
let msg_endpoint2: any = [];
let centro_de_custo = "";
for (let i = 0; i < response.length; i++) {
if (
[
"id_solicitante",
"centro_custo_departamento",
"departamento_do_formulario",
"centro_de_custo_do_departamento_do_formulario"
].includes(response[i][0])
)
continue;
msg_endpoint_response += `*${response[i][0]}*: ${String(
response[i][1]
).replace(/(<([^>]+)>)/gi, "")}\n`;
}
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;
msg_endpoint2 = await queryEndPointHit(centro_de_custo);
}
const itsm_response = async (
message1: string = "",
message2: string = ""
) => {
await SendWhatsAppMessage({
body: `*Situação do chamado ${extractCallCode(
msgAction.msgBody
)}:*${message1}${msg_endpoint_response}${message2}\n_Digite *0* para voltar ao menu principal._`,
ticket,
number: `${contact.number}@c.us`
});
};
const sendMessageBot = async (
message1: string = "",
message2: string = ""
) => {
await SendWhatsAppMessage({
body: `${message1}${message2}`,
ticket,
number: `${contact.number}@c.us`
});
};
if (body.search("dialog_options") != -1) {
let msgAction = botMsgActions(body);
let index = msgAction.actions.findIndex(i => i == "dialog_options");
if (index != -1) {
let dialog_options = msgAction.actions[index + 1];
if (
dialog_options == "3" &&
endPointResponse.data.categoria == "ELOS"
) {
index = msgAction.actions.findIndex(i => i == "queue_transfer");
if (index != -1) {
await itsm_response("\n\n");
await monitoramento_response2(
msg_endpoint2,
wbot,
contact,
ticket,
centro_de_custo,
"\n\n",
false
);
botSendMessage(
ticket,
`Estamos direcionando seu atendimento para o Suporte. Em breve você será atendido por um de nossos atendentes!\n\nPara voltar ao atendimento *automatizado* e sair da fila de atendimento *humano* digite *0*`
);
await transferTicket(
+msgAction.actions[index + 1],
wbot,
ticket
);
}
}
}
} else if (
(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 == "VENDAS") ||
(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 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(
"Acompanhe a evolução do atendimento através do SOS"
);
return;
}
} else if (
endPointResponse &&
endPointResponse.status == 200 &&
Object.entries(endPointResponse.data).length == 0
) {
botSendMessage(
ticket,
`Não existe nenhum chamado para consulta com esse número!\n _Digite *0* para voltar ao menu principal._`
);
return;
} else if (endPointResponse && endPointResponse.status == 500) {
botSendMessage(
ticket,
`Houve um erro ao realizar a consulta no sos espacolaser!\n _Digite *0* para voltar ao menu principal._`
);
return;
} else {
botSendMessage(
ticket,
`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);
await SendWhatsAppMessage({
body: msgAction.msgBody,
ticket,
number: `${contact.number}@c.us`
});
await transferTicket(+msgAction.actions[1], wbot, ticket);
} else if (msgAction.actions[0] == "send_file") {
const sourcePath = path.join(__dirname, `../../../public/bot`);
await SendWhatsAppMessage({
body: msgAction.msgBody,
ticket,
number: `${contact.number}@c.us`
});
}
} else {
sendWhatsAppMessageSocket(ticket, body);
}
}
const extractCallCode = (str: string) => {
if (str.includes("*") && str.indexOf("*") < str.lastIndexOf("*")) {
return str
.substring(str.indexOf("*"), str.lastIndexOf("*") + 1)
.split("*")
.join("");
}
return "";
};
const verifyQueue = async ( const verifyQueue = async (
wbot: Session, wbot: Session,
msg: WbotMessage, msg: WbotMessage,
@ -457,6 +770,17 @@ const mediaTypeWhatsappOfficial = (mimetype: string): object => {
return { type: null, mbsize: 0 }; return { type: null, mbsize: 0 };
}; };
const botMsgActions = (params: string) => {
let lstActions = params.split("dialog_actions=");
let bodyMsg = lstActions[0];
let obj = {};
console.log("lstActions: ", lstActions[1].split("="));
let actions = lstActions[1].split("=");
return { msgBody: bodyMsg, actions: actions };
};
const isValidMsg = (msg: any): boolean => { const isValidMsg = (msg: any): boolean => {
if (msg.from === "status@broadcast") return false; if (msg.from === "status@broadcast") return false;
if ( if (
@ -663,12 +987,38 @@ const handleMessage = async (
) )
return; return;
const ticket = await FindOrCreateTicketService( let ticket;
contact,
wbot.id!, const _botInfo = await BotIsOnQueue("botqueue");
unreadMessages
// groupContact if (_botInfo.isOnQueue) {
); let ticket_obj: any = await FindOrCreateTicketServiceBot(
contact,
wbot.id!,
unreadMessages
// groupContact
);
ticket = ticket_obj.ticket;
if (ticket_obj.created) {
let queue = await ShowQueueService(_botInfo.botQueueId);
await UpdateTicketService({
ticketData: { queueId: queue.id },
ticketId: ticket.id
});
ticket = await ShowTicketService(ticket.id);
}
} else {
ticket = await FindOrCreateTicketService(
contact,
wbot.id!,
unreadMessages
// groupContact
);
}
if (getSettingValue("oneContactChatWithManyWhats")?.value == "disabled") { if (getSettingValue("oneContactChatWithManyWhats")?.value == "disabled") {
// Para responder para o cliente pelo mesmo whatsapp que ele enviou a mensagen // Para responder para o cliente pelo mesmo whatsapp que ele enviou a mensagen
@ -739,6 +1089,63 @@ const handleMessage = async (
} else { } else {
console.log("MSG body: ", msg.body); console.log("MSG body: ", msg.body);
if (msg.type != "chat") {
botSendMessage(
ticket,
`Desculpe, nao compreendi!\nEnvie apenas texto quando estiver interagindo com o bot!\n _Digite *0* para voltar ao menu principal._`
);
return;
}
if (msg.type == "chat" && String(msg.body).length > 120) {
botSendMessage(
ticket,
`Desculpe, nao compreendi!\nTexto acima de 120 caracteres!\n _Digite *0* para voltar ao menu principal._`
);
return;
}
let query = await get(
`whatsappId:${wbot.id}:contactId:${contact?.id}:identifier:query`
);
if (query && msg?.body?.trim() != "0") {
query = JSON.parse(query);
const regexString = query?.queryRegex?.slice(1, -1);
query.queryRegex = new RegExp(regexString);
if (!query?.queryRegex.test(msg.body)) {
await botSendMessage(ticket, query?.queryMsgInvalidParam);
return;
}
if (query?.value?.trim()?.length == 0) {
await set(
`whatsappId:${wbot.id}:contactId:${contact?.id}:identifier:query`,
JSON.stringify({ ...query, value: msg.body }),
true
);
}
let message = "";
// Refactor later
if (query?.optionsMenu == "3") {
message = `Consultando *${msg?.body?.trim()}* aguarde...
dialog_actions=request_endpoint=https://sos.espacolaser.com.br/api/whatsapp/ticket/${msg?.body?.trim()}=dialog_options=3=queue_transfer=1`;
} else if (query?.optionsMenu == "1") {
message = `Consultando *${msg.body}* aguarde...
dialog_actions=request_endpoint=https://sos.espacolaser.com.br/api/whatsapp/ticket/${msg?.body?.trim()}`;
}
if (message.trim().length > 0)
await sendDelayedMessages(wbot, ticket, contact, message);
return;
}
const menuMsg: any = await menu(msg.body, wbot.id, contact.id); const menuMsg: any = await menu(msg.body, wbot.id, contact.id);
console.log("menuMsg: ", menuMsg); console.log("menuMsg: ", menuMsg);
@ -755,6 +1162,22 @@ const handleMessage = async (
); );
transferTicket(menuMsg.transferToQueue.trim(), wbot, ticket); transferTicket(menuMsg.transferToQueue.trim(), wbot, ticket);
} else if (menuMsg?.query) {
await set(
`whatsappId:${wbot.id}:contactId:${contact?.id}:identifier:query`,
JSON.stringify({
whatsappId: wbot.id,
contactId: contact.id,
identifier: "query",
value: "",
queryRegex: menuMsg?.queryRegex,
query: menuMsg?.query,
queryMsg: menuMsg?.queryMsg,
queryMsgInvalidParam: menuMsg?.queryMsgInvalidParam,
optionsMenu: menuMsg?.optionsMenu
}),
true
);
} }
} }
@ -894,6 +1317,10 @@ const menu = async (userTyped: string, whatsappId: any, contactId: any) => {
value: data[1].id value: data[1].id
}); });
await del(
`whatsappId:${whatsappId}:contactId:${contactId}:identifier:query`
);
return data[1]; return data[1];
} else { } else {
console.log("INVALID SEARCH"); console.log("INVALID SEARCH");

View File

@ -321,16 +321,34 @@ const MessageInput = ({ ticketStatus }) => {
setTabOption('open') setTabOption('open')
} }
const message = {
if (templateParams) {
for (let key in templateParams) {
if (templateParams.hasOwnProperty(key)) {
// let value = templateParams[key]
// console.log('key: ', key, ' | ', 'VALUE: ', value)
if (key === '_reactName') {
templateParams = null
break
}
}
}
}
let message = {
read: 1, read: 1,
fromMe: true, fromMe: true,
mediaUrl: "", mediaUrl: "",
body: (signMessage && !templateParams) body: (signMessage && !templateParams) ? `*${user?.name}:*\n${inputMessage.trim()}` : inputMessage.trim(),
? `*${user?.name}:*\n${inputMessage.trim()}` quotedMsg: replyingMessage
: inputMessage.trim(),
quotedMsg: replyingMessage,
params: templateParams
} }
if (templateParams) {
message = { ...message, params: templateParams }
}
try { try {
const { data } = await api.post(`/messages/${ticketId}`, message) const { data } = await api.post(`/messages/${ticketId}`, message)
@ -358,8 +376,8 @@ const MessageInput = ({ ticketStatus }) => {
let { text } = body_params let { text } = body_params
console.log('PARAMS FROM MESSAGE INPUT: ', params, ' | text: ', text) console.log('PARAMS FROM MESSAGE INPUT: ', params, ' | text: ', text)
let body = text.match(/{{\d+}}/g) let body = text.match(/{{\d+}}/g)
if (body && body.length > 0) { if (body && body.length > 0) {
@ -373,9 +391,9 @@ const MessageInput = ({ ticketStatus }) => {
} }
} }
} }
console.log('NEW TEXT: ', text) console.log('NEW TEXT: ', text)
setInputMessage(text) setInputMessage(text)
}, [params]) }, [params])