feat: Enable direct transfer of tickets to agent via WhatsApp user input

pull/22/head
adriano 2024-02-20 12:33:36 -03:00
parent 18660b6947
commit db140a328c
5 changed files with 164 additions and 54 deletions

View File

@ -15,9 +15,9 @@ async function omnihitDashboardSession(data: any) {
} }
); );
} catch (error) { } catch (error) {
console.log( // console.log(
`Post request error to ${process.env.URL_DASHBOARD_SESSIONS}/api/v1/omnihit/monitor` // `Post request error to ${process.env.URL_DASHBOARD_SESSIONS}/api/v1/omnihit/monitor`
); // );
} }
} }

View File

@ -8,7 +8,7 @@ type WhatsappData = {
value?: string; value?: string;
}; };
export async function set(key: string, value: string) { export async function set(key: string, value: string | object) {
await redis.set(key, JSON.stringify(value)); await redis.set(key, JSON.stringify(value));
} }
@ -17,6 +17,20 @@ export async function get(key: string) {
return JSON.parse(value); return JSON.parse(value);
} }
export async function findByContain() {
// const keys = await redis.keys("*" + substring + "*");
const keys = await redis.keys("user:*");
const results: any[] = [];
for (const key of keys) {
const value = await redis.get(key);
if (value) {
results.push(JSON.parse(value));
}
}
return results;
}
export async function createObject({ export async function createObject({
whatsappId, whatsappId,
contactId, contactId,

View File

@ -23,6 +23,7 @@ import fs from "fs";
import dir from "path"; import dir from "path";
import { getSettingValue } from "./helpers/WhaticketSettings"; import { getSettingValue } from "./helpers/WhaticketSettings";
import loadSettings from "./helpers/LoadSettings"; import loadSettings from "./helpers/LoadSettings";
import { set } from "./helpers/RedisClient";
const server = app.listen(process.env.PORT, () => { const server = app.listen(process.env.PORT, () => {
logger.info(`Server started on port: ${process.env.PORT}`); logger.info(`Server started on port: ${process.env.PORT}`);
@ -43,6 +44,13 @@ gracefulShutdown(server);
(async () => { (async () => {
console.log("os.tmpdir(): ", os.tmpdir()); console.log("os.tmpdir(): ", os.tmpdir());
const users = await User.findAll();
for (const user of users) {
const { id, name } = user;
await set(`user:${id}:${name.toLowerCase()}`, { id, name });
}
loadSettings(); loadSettings();
let whatsapps: any = await Whatsapp.findAll({ let whatsapps: any = await Whatsapp.findAll({

View File

@ -0,0 +1,37 @@
import { Op, Sequelize } from "sequelize";
import Whatsapp from "../../models/Whatsapp";
import WhatsappQueue from "../../models/WhatsappQueue";
import { List } from "whatsapp-web.js";
import UserQueue from "../../models/UserQueue";
import Queue from "../../models/Queue";
const dbConfig = require("../../config/database");
const { QueryTypes } = require("sequelize");
const sequelize = new Sequelize(dbConfig);
const ListWhatsappQueuesByUserQueue = async (userId: string | number) => {
try {
let userQueue: any = await UserQueue.findAll({
where: { userId },
attributes: ["queueId"],
raw: true
});
if (userQueue && userQueue.length > 0) {
userQueue = userQueue.map((u: any) => u.queueId);
const result = await sequelize.query(
`select w.id, w.number, wq.whatsappId, wq.queueId, q.id, q.name from WhatsappQueues wq join Queues q on
wq.queueId = q.id join Whatsapps w
on wq.whatsappId = w.id where q.id in (${userQueue.join()})`,
{ type: QueryTypes.SELECT }
);
return result;
}
} catch (error) {
console.error("Error fetching joined data:", error);
}
return [];
};
export default ListWhatsappQueuesByUserQueue;

View File

@ -83,14 +83,21 @@ import AppError from "../../errors/AppError";
import { setMessageAsRead } from "../../helpers/SetMessageAsRead"; import { setMessageAsRead } from "../../helpers/SetMessageAsRead";
import { getSettingValue } from "../../helpers/WhaticketSettings"; import { getSettingValue } from "../../helpers/WhaticketSettings";
import { Op } from "sequelize"; import { Op, json } 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 {
import FindOrCreateTicketServiceBot from "../TicketServices/FindOrCreateTicketServiceBot" createObject,
import ShowTicketService from "../TicketServices/ShowTicketService" findByContain,
findObject,
get
} from "../../helpers/RedisClient";
import FindOrCreateTicketServiceBot from "../TicketServices/FindOrCreateTicketServiceBot";
import ShowTicketService from "../TicketServices/ShowTicketService";
import ShowQueuesByUser from "../UserServices/ShowQueuesByUser";
import ListWhatsappQueuesByUserQueue from "../UserServices/ListWhatsappQueuesByUserQueue";
var lst: any[] = getWhatsappIds(); var lst: any[] = getWhatsappIds();
@ -504,13 +511,10 @@ const transferTicket = async (queueName: any, wbot: any, ticket: Ticket) => {
const queues = queuesWhatsGreetingMessage.queues; const queues = queuesWhatsGreetingMessage.queues;
// console.log("queues ---> ", console.log(JSON.stringify(queues, null, 6)));
if (typeof queueName == "string") { if (typeof queueName == "string") {
queue = queues.find( queue = queues.find(
(q: any) => q?.name?.toLowerCase() == queueName.trim().toLowerCase() (q: any) => q?.name?.toLowerCase() == queueName.trim().toLowerCase()
); );
// await deleteObject(wbot.id, `${ticket.contactId}`, "ura");
} else if (typeof queueName == "number") { } else if (typeof queueName == "number") {
queue = queues[queueName]; queue = queues[queueName];
} }
@ -527,6 +531,21 @@ const botTransferTicket = async (queues: Queue, ticket: Ticket) => {
}); });
}; };
const botTransferTicketToUser = async (
userId: number,
ticket: Ticket,
queueId?: number | undefined
) => {
console.log("USER ID: ", userId);
// await ticket.update({ userId: userId });
await UpdateTicketService({
ticketData: { status: "open", userId, queueId },
ticketId: ticket.id
});
};
const botSendMessage = (ticket: Ticket, msg: string) => { const botSendMessage = (ticket: Ticket, msg: string) => {
const { phoneNumberId } = ticket; const { phoneNumberId } = ticket;
@ -665,39 +684,38 @@ const handleMessage = async (
) )
return; return;
let ticket; let ticket;
const _botInfo = await BotIsOnQueue("botqueue"); const _botInfo = await BotIsOnQueue("botqueue");
if (_botInfo.isOnQueue) { if (_botInfo.isOnQueue) {
let ticket_obj: any = await FindOrCreateTicketServiceBot( let ticket_obj: any = await FindOrCreateTicketServiceBot(
contact, contact,
wbot.id!, wbot.id!,
unreadMessages unreadMessages
// groupContact // groupContact
); );
ticket = ticket_obj.ticket; ticket = ticket_obj.ticket;
if (ticket_obj.created) { if (ticket_obj.created) {
let queue = await ShowQueueService(_botInfo.botQueueId); let queue = await ShowQueueService(_botInfo.botQueueId);
await UpdateTicketService({ await UpdateTicketService({
ticketData: { queueId: queue.id }, ticketData: { queueId: queue.id },
ticketId: ticket.id ticketId: ticket.id
}); });
ticket = await ShowTicketService(ticket.id);
}
} else {
ticket = await FindOrCreateTicketService(
contact,
wbot.id!,
unreadMessages
// groupContact
);
}
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
@ -768,21 +786,54 @@ const handleMessage = async (
} else { } else {
console.log("MSG body: ", msg.body); console.log("MSG body: ", msg.body);
if (msg.type != "chat") { if (msg.type != "chat") {
botSendMessage( botSendMessage(
ticket, ticket,
`Desculpe, nao compreendi!\nEnvie apenas texto quando estiver interagindo com o bot!\n _Digite *0* para voltar ao menu principal._` `Desculpe, nao compreendi!\nEnvie apenas texto quando estiver interagindo com o bot!\n _Digite *0* para voltar ao menu principal._`
); );
return; return;
} }
if (msg.type == "chat" && String(msg.body).length > 120) { if (msg.type == "chat" && String(msg.body).length > 120) {
botSendMessage( botSendMessage(
ticket, ticket,
`Desculpe, nao compreendi!\nTexto acima de 120 caracteres!\n _Digite *0* para voltar ao menu principal._` `Desculpe, nao compreendi!\nTexto acima de 120 caracteres!\n _Digite *0* para voltar ao menu principal._`
); );
return; return;
} }
// Transfer to agent
const listUser = await findByContain();
let filteredUsers = listUser.filter(user =>
msg?.body?.trim()?.toLowerCase().includes(user.name)
);
if (filteredUsers && filteredUsers.length > 0) {
const whatsappQueues = await ListWhatsappQueuesByUserQueue(
+filteredUsers[0].id
);
const obj: any = whatsappQueues.find(
(ob: any) => ob.whatsappId == wbot.id
);
if (obj) {
await botTransferTicketToUser(
+filteredUsers[0].id,
ticket,
+obj.queueId
);
botSendMessage(
ticket,
`Você foi transferido para falar com o agente ${filteredUsers[0].name}`
);
}
return;
}
//
const menuMsg: any = await menu(msg.body, wbot.id, contact.id); const menuMsg: any = await menu(msg.body, wbot.id, contact.id);