feat: Enable direct transfer of tickets to agent via WhatsApp user input
parent
18660b6947
commit
db140a328c
|
@ -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`
|
||||||
);
|
// );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,15 +8,29 @@ 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
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 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,
|
||||||
|
|
|
@ -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,11 +44,18 @@ 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({
|
||||||
attributes: ["id", "url", "phoneNumberId"]
|
attributes: ["id", "url", "phoneNumberId"]
|
||||||
});
|
});
|
||||||
|
|
||||||
if (whatsapps && whatsapps.length > 0) {
|
if (whatsapps && whatsapps.length > 0) {
|
||||||
for (let i = 0; i < whatsapps.length; i++) {
|
for (let i = 0; i < whatsapps.length; i++) {
|
||||||
|
|
|
@ -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;
|
|
@ -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);
|
ticket = await ShowTicketService(ticket.id);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ticket = await FindOrCreateTicketService(
|
ticket = await FindOrCreateTicketService(
|
||||||
contact,
|
contact,
|
||||||
wbot.id!,
|
wbot.id!,
|
||||||
unreadMessages
|
unreadMessages
|
||||||
// groupContact
|
// 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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue