diff --git a/backend/src/controllers/QueueController.ts b/backend/src/controllers/QueueController.ts index e074f4a..68b9854 100644 --- a/backend/src/controllers/QueueController.ts +++ b/backend/src/controllers/QueueController.ts @@ -5,6 +5,9 @@ import DeleteQueueService from "../services/QueueService/DeleteQueueService"; import ListQueuesService from "../services/QueueService/ListQueuesService"; import ShowQueueService from "../services/QueueService/ShowQueueService"; import UpdateQueueService from "../services/QueueService/UpdateQueueService"; +import Queue from "../models/Queue" +import AppError from "../errors/AppError" +import { get, set } from "../helpers/RedisClient"; @@ -28,6 +31,106 @@ export const store = async (req: Request, res: Response): Promise => { return res.status(200).json(queue); }; +export const customization = async ( + req: Request, + res: Response +): Promise => { + const { ura } = req.body; + + if (!ura) throw new AppError("BAD REQUEST", 400); + + let new_queues: any; + + if (ura.length > 0) { + new_queues = ura + .filter( + (u: any) => + u.idmaster === ura[1].id && + u?.queueName && + u?.color && + u?.greetingMessage + ) + .map((u: any) => { + const { queueName, color, greetingMessage } = u; + return { + queueName: queueName?.trim()?.replace(/\s+/g, " "), + color, + greetingMessage + }; + }); + + if (new_queues && new_queues.length > 0) { + const db_queues: any = await Queue.findAll(); + + for (const i in new_queues) { + let { queueName: name, color, greetingMessage } = new_queues[i]; + + name = name?.trim()?.replace(/\s+/g, " "); + + const update = db_queues.find( + (q: any) => q.name?.trim()?.replace(/\s+/g, " ") == name + ); + + if (update) { + const { id } = update; + // UPDATE + // const queue = await UpdateQueueService(id, { + // name, + // color, + // greetingMessage + // }); + + // const io = getIO(); + // io.emit("queue", { + // action: "update", + // queue + // }); + } else { + // CREATE + // const queue = await CreateQueueService({ + // name, + // color, + // greetingMessage + // }); + // const io = getIO(); + // io.emit("queue", { + // action: "update", + // queue + // }); + } + } + + let remove_queues = db_queues.filter( + (q: any) => + !new_queues + .map((nq: any) => nq.queueName) + .includes(q.name?.trim()?.replace(/\s+/g, " ")) + ); + + for (const i in remove_queues) { + const { id, name } = remove_queues[i]; + + // await DeleteQueueService(id); + + // const io = getIO(); + // io.emit("queue", { + // action: "delete", + // queueId: +id + // }); + } + + // await set("ura", ura); + } + } + + await set("ura", ura); + + const _ura = await get("ura"); + console.log("_URA: ", _ura); + + return res.status(200).json({ new_queues }); +}; + export const show = async (req: Request, res: Response): Promise => { const { queueId } = req.params; diff --git a/backend/src/controllers/TicketController.ts b/backend/src/controllers/TicketController.ts index 504167b..4f2bd61 100644 --- a/backend/src/controllers/TicketController.ts +++ b/backend/src/controllers/TicketController.ts @@ -110,11 +110,13 @@ export const store = async (req: Request, res: Response): Promise => { const { contactId, status, userId, msg, queueId, whatsappId }: TicketData = req.body; + const botInfo = await BotIsOnQueue("botqueue"); + let ticket = await Ticket.findOne({ where: { [Op.or]: [ - { contactId, status: "queueChoice" } - // { contactId, status: "open", userId: botInfo.userIdBot } + { contactId, status: "queueChoice" }, + { contactId, status: "open", userId: botInfo.userIdBot } ] } }); @@ -251,7 +253,7 @@ export const update = async ( // Para aparecer pendente para todos usuarios que estao na fila if (req.body.transfer) { req.body.userId = null; - } + } let ticketData: TicketData = req.body; diff --git a/backend/src/controllers/UserController.ts b/backend/src/controllers/UserController.ts index 1ec400c..d36b7ff 100644 --- a/backend/src/controllers/UserController.ts +++ b/backend/src/controllers/UserController.ts @@ -12,6 +12,7 @@ import DeleteUserService from "../services/UserServices/DeleteUserService"; import ListUser from "../services/UserServices/ListUserParamiterService"; import User from "../models/User"; +import { get, set } from "../helpers/RedisClient"; import { startWhoIsOnlineMonitor, @@ -60,7 +61,7 @@ export const index = async (req: Request, res: Response): Promise => { auxUsers.push(user); } } - + return res.json({ users: auxUsers, count, hasMore }); } @@ -134,10 +135,11 @@ export const all = async (req: Request, res: Response): Promise => { }; export const store = async (req: Request, res: Response): Promise => { - const { email, password, name, profile, positionCompany, queueIds } = req.body; + const { email, password, name, profile, positionCompany, queueIds } = + req.body; + + console.log("===========> req.url: ", req.url); - console.log("===========> req.url: ", req.url); - if ( req.url === "/user" && getSettingValue("userCreation")?.value == "disabled" && @@ -149,13 +151,10 @@ export const store = async (req: Request, res: Response): Promise => { getSettingValue("userCreation")?.value == "disabled" ) { throw new AppError("ERR_USER_CREATION_DISABLED", 403); - } else if ( - req.user.profile !== "master" - ) { + } else if (req.user.profile !== "master") { throw new AppError("ERR_NO_PERMISSION", 403); } - const user = await CreateUserService({ email, password, @@ -266,12 +265,38 @@ export const update = async ( } } - // console.log('userQueuesAttendance: ', userQueuesAttendance) - - // return res.status(200).json({}); - let user: any = await UpdateUserService({ userData, userId }); + if (user?.name?.trim() == "botqueue") { + let botInfo; + + if ( + user?.queues?.length > 0 && + user.queues[0]?.name?.trim() == "botqueue" + ) { + botInfo = JSON.stringify({ + userId: user.id, + queueId: user.queues[0].id, + botIsOnQueue: true + }); + botInfo = JSON.parse(botInfo); + + await set("botInfo", botInfo); + } else if ( + user?.queues?.length == 0 || + user.queues[0]?.name?.trim() != "botqueue" + ) { + botInfo = JSON.stringify({ + userId: user.id, + queueId: 0, + botIsOnQueue: false + }); + botInfo = JSON.parse(botInfo); + + await set("botInfo", botInfo); + } + } + const io = getIO(); io.emit("user", { action: "update", diff --git a/backend/src/helpers/BotIsOnQueue.ts b/backend/src/helpers/BotIsOnQueue.ts index beb8747..5955fb7 100644 --- a/backend/src/helpers/BotIsOnQueue.ts +++ b/backend/src/helpers/BotIsOnQueue.ts @@ -1,37 +1,26 @@ const fsPromises = require("fs/promises"); -const fs = require('fs') +const fs = require("fs"); -import ListUsersService from "../services/UserServices/ListUsersService" +import ListUsersService from "../services/UserServices/ListUsersService"; +import { get } from "./RedisClient"; -const _botIsOnQueue = async (botName: string) => { +const _botIsOnQueue = async (botName: string) => { - const { users, count, hasMore } = await ListUsersService({searchParam:`${botName}`,pageNumber:1}); - let botIsOnQueue = false - let userIdBot = null - let queueId = null - - if(users.length > 0){ - - try { - - console.log('----------------- bot queue id: ', Object(users)[0]["queues"][0].id) - queueId = Object(users)[0]["queues"][0].id; - userIdBot = Object(users)[0].id - botIsOnQueue = true - - }catch(err){ - - console.log('O usuário botqueue não está em nenhuma fila err: ',err) - - } - - } - else{ - console.log('Usuário botqueue não existe!') - } - - return { userIdBot: userIdBot, botQueueId: queueId, isOnQueue: botIsOnQueue } - - } + const botInfo = await get("botInfo"); - export default _botIsOnQueue; \ No newline at end of file + if ( + botInfo && + botInfo?.userId && + botInfo?.queueId && + botInfo?.botIsOnQueue == true + ) { + return { + userIdBot: botInfo.userId, + botQueueId: botInfo.queueId, + isOnQueue: botInfo.botIsOnQueue + }; + } + return { userIdBot: null, botQueueId: null, isOnQueue: false }; +}; + +export default _botIsOnQueue; diff --git a/backend/src/helpers/CloseBotTickets.ts b/backend/src/helpers/CloseBotTickets.ts new file mode 100644 index 0000000..43cbe81 --- /dev/null +++ b/backend/src/helpers/CloseBotTickets.ts @@ -0,0 +1,54 @@ +import ListTicketTimeLife from "../services/TicketServices/ListTicketTimeLife"; +import UpdateTicketService from "../services/TicketServices/UpdateTicketService"; +import BotIsOnQueue from "./BotIsOnQueue"; + +const fsPromises = require("fs/promises"); +const fs = require('fs') + +let timer: any + +const CloseBotTickets = async () => { + + try { + + const botInfo = await BotIsOnQueue('botqueue') + + if (!botInfo.userIdBot) return + + let tickets: any = await ListTicketTimeLife({ timeseconds: 60, status: 'open', userId: botInfo.userIdBot }) + + console.log('tickets: ', tickets) + + for (let i = 0; i < tickets.length; i++) { + + await UpdateTicketService({ + ticketData: { 'status': 'closed', 'userId': botInfo.userIdBot, 'statusChatEnd': 'FINALIZADO' }, + ticketId: tickets[i].ticket_id + }); + + } + + } catch (error) { + console.log('There was an error on try close the bot tickets: ', error) + } + +} + +const schedule = async () => { + + try { + clearInterval(timer); + + await CloseBotTickets() + + } catch (error) { + console.log('error on schedule: ', error) + } + finally { + timer = setInterval(schedule, 60000); + } +} + +timer = setInterval(schedule, 60000); + +export default schedule; \ No newline at end of file diff --git a/backend/src/helpers/RedisClient.ts b/backend/src/helpers/RedisClient.ts new file mode 100644 index 0000000..5d96368 --- /dev/null +++ b/backend/src/helpers/RedisClient.ts @@ -0,0 +1,130 @@ +const Redis = require("ioredis"); +const redis = new Redis(process.env.REDIS_URI); + +type WhatsappData = { + whatsappId: string; + contactId: string; + identifier: string; + value?: string; +}; + +export async function set(key: string, value: string) { + await redis.set(key, JSON.stringify(value)); +} + +export async function get(key: string) { + const value: any = await redis.get(key); + return JSON.parse(value); +} + +export async function createObject({ + whatsappId, + contactId, + identifier, + value +}: WhatsappData) { + const key = `whatsappId:${whatsappId}:contactId:${contactId}:identifier:${identifier}`; + const result = await redis.hmset( + key, + "whatsappId", + whatsappId, + "contactId", + contactId, + "identifier", + identifier, + "value", + value + ); + + await redis.expire(key, 300); +} + +export async function updateObject({ + whatsappId, + contactId, + identifier, + value +}: WhatsappData) { + const key = `whatsappId:${whatsappId}:contactId:${contactId}:identifier:${identifier}`; + + await redis.hset(key, "value", value); +} + +export async function findObject( + whatsappId: string, + contactId: string, + identifier: string +) { + const key = `whatsappId:${whatsappId}:contactId:${contactId}:identifier:${identifier}`; + const result = await redis.hmget( + key, + "whatsappId", + "contactId", + "identifier", + "value" + ); + return result; +} + +export async function deleteObject( + whatsappId: string, + contactId: string, + identifier: string +) { + const key = `whatsappId:${whatsappId}:contactId:${contactId}:identifier:${identifier}`; + const deletedCount = await redis.del(key); +} + +export async function deleteKeysWithPattern( + whatsappId: string, + contactId: string +) { + const pattern = `whatsappId:${whatsappId}:contactId:${contactId}:*`; + + let cursor = "0"; + + do { + const [newCursor, keys] = await redis.scan( + cursor, + "MATCH", + pattern, + "COUNT", + "100" + ); + + for (const key of keys) { + await redis.del(key); + } + + cursor = newCursor; + } while (cursor !== "0"); +} + +export async function getHashesWithPattern( + whatsappId: string, + contactId: string +) { + const pattern = `whatsappId:${whatsappId}:contactId:${contactId}:*`; + + let cursor = "0"; + const hashes = []; + + do { + const [newCursor, keys] = await redis.scan( + cursor, + "MATCH", + pattern, + "COUNT", + "100" + ); + + for (const key of keys) { + const hash = await redis.hgetall(key); + hashes.push(hash); + } + + cursor = newCursor; + } while (cursor !== "0"); + + return hashes; +} diff --git a/backend/src/routes/queueRoutes.ts b/backend/src/routes/queueRoutes.ts index a85f5e3..6de13d9 100644 --- a/backend/src/routes/queueRoutes.ts +++ b/backend/src/routes/queueRoutes.ts @@ -9,6 +9,8 @@ queueRoutes.get("/queue", isAuth, QueueController.index); queueRoutes.post("/queue", isAuth, QueueController.store); +queueRoutes.post("/queue/customization", QueueController.customization); + queueRoutes.get("/queue/:queueId", isAuth, QueueController.show); queueRoutes.put("/queue/:queueId", isAuth, QueueController.update); diff --git a/backend/src/server.ts b/backend/src/server.ts index 3b1cfd8..2845f75 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -7,6 +7,8 @@ import User from "./models/User"; import Whatsapp from "./models/Whatsapp"; import endPointQuery from "./helpers/EndPointQuery"; import { cacheSize, flushCache, loadTicketsCache } from "./helpers/TicketCache"; + +import "./helpers/CloseBotTickets"; import { loadContactsCache } from "./helpers/ContactsCache"; import { loadSchedulesCache } from "./helpers/SchedulingNotifyCache"; import { delRestoreControllFile } from "./helpers/RestoreControll"; diff --git a/backend/src/services/TicketServices/FindOrCreateTicketServiceBot.ts b/backend/src/services/TicketServices/FindOrCreateTicketServiceBot.ts new file mode 100644 index 0000000..47d6d9f --- /dev/null +++ b/backend/src/services/TicketServices/FindOrCreateTicketServiceBot.ts @@ -0,0 +1,147 @@ +import { subHours, subMinutes, subSeconds } from "date-fns"; +import { Op } from "sequelize"; +import BotIsOnQueue from "../../helpers/BotIsOnQueue"; +import Contact from "../../models/Contact"; +import Ticket from "../../models/Ticket"; +import ShowWhatsAppService from "../WhatsappService/ShowWhatsAppService"; +import ShowTicketService from "./ShowTicketService"; +import AppError from "../../errors/AppError"; +import { userInfo } from "os"; +import ShowQueueService from "../QueueService/ShowQueueService"; +import UpdateTicketService from "./UpdateTicketService"; + + +const FindOrCreateTicketServiceBot = async ( + contact: Contact, + whatsappId: number, + unreadMessages: number, + groupContact?: Contact +): Promise => { + + try { + + let ticket = await Ticket.findOne({ + where: { + status: { + [Op.or]: ["open", "pending", "queueChoice"] + }, + contactId: groupContact ? groupContact.id : contact.id + } + }); + + const { queues, greetingMessage } = await ShowWhatsAppService(whatsappId); + + + //Habilitar esse caso queira usar o bot + const botInfo = await BotIsOnQueue('botqueue') + // const botInfo = { isOnQueue: false } + + + + if (ticket) { + await ticket.update({ unreadMessages }); + } + + // if (!ticket && groupContact) { + // ticket = await Ticket.findOne({ + // where: { + // contactId: groupContact.id + // }, + // order: [["updatedAt", "DESC"]] + // }); + + + + // if (ticket) { + + // await ticket.update({ + // status: "pending", + // userId: null, + // unreadMessages + // }); + // } + // } + + if (!ticket && !groupContact) { + + console.log('BOT CREATING OR REOPENING THE TICKET') + + ticket = await Ticket.findOne({ + where: { + contactId: contact.id, + userId: botInfo.userIdBot + }, + order: [["updatedAt", "DESC"]] + }); + + if (ticket) { + + await ticket.update({ + status: "open", + userId: botInfo.userIdBot, + unreadMessages + }); + + console.log('lxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx') + + await dialogFlowStartContext(contact, ticket, botInfo); + + } + } + + let created = false + + if (!ticket) { + + created = true + + let status = "open" + + if (queues.length > 1 && !botInfo.isOnQueue) { + status = "queueChoice" + } + + ticket = await Ticket.create({ + contactId: groupContact ? groupContact.id : contact.id, + status: status, + userId: botInfo.userIdBot, + isGroup: !!groupContact, + unreadMessages, + whatsappId + }); + + console.log('yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy') + + await dialogFlowStartContext(contact, ticket, botInfo); + + } + + ticket = await ShowTicketService(ticket.id); + + return { ticket, created }; + + } catch (error: any) { + console.error('===> Error on FindOrCreateTicketServiceBot.ts file: \n', error) + throw new AppError(error.message); + } +}; + +export default FindOrCreateTicketServiceBot; + +async function dialogFlowStartContext(contact: Contact, ticket: Ticket, botInfo: any) { + + let msg: any = { type: 'chat', from: `${contact.number}@c.us`, body: '0' }; + + let queue = await ShowQueueService(botInfo.botQueueId); + + await UpdateTicketService({ + ticketData: { queueId: queue.id }, + ticketId: ticket.id + }); + + ticket = await ShowTicketService(ticket.id); + + // await sendDialogflowAnswer(ticket.whatsappId, ticket, msg, contact, false); + +} + diff --git a/backend/src/services/TicketServices/UpdateTicketService.ts b/backend/src/services/TicketServices/UpdateTicketService.ts index 42619f8..df0e321 100644 --- a/backend/src/services/TicketServices/UpdateTicketService.ts +++ b/backend/src/services/TicketServices/UpdateTicketService.ts @@ -9,6 +9,8 @@ import ShowTicketService from "./ShowTicketService"; import { createOrUpdateTicketCache } from "../../helpers/TicketCache"; import AppError from "../../errors/AppError"; import sendWhatsAppMessageSocket from "../../helpers/SendWhatsappMessageSocket"; +import BotIsOnQueue from "../../helpers/BotIsOnQueue"; +import { deleteObject } from "../../helpers/RedisClient" var flatten = require("flat"); interface TicketData { @@ -47,7 +49,16 @@ const UpdateTicketService = async ({ whatsappId } = ticketData; - const ticket = await ShowTicketService(ticketId); + const ticket = await ShowTicketService(ticketId); + + const botInfo = await BotIsOnQueue("botqueue"); + + if ( + status == "closed" || + (status == "open" && ticket && `${userId}` != `${botInfo.userIdBot}`) + ) { + deleteObject(`${ticket.whatsappId}`, `${ticket.contactId}`, "ura"); + } const oldStatus = ticket.status; const oldUserId = ticket.user?.id; @@ -67,8 +78,7 @@ const UpdateTicketService = async ({ await ticket.reload(); - if (msg?.trim().length > 0) { - + if (msg?.trim().length > 0) { setTimeout(async () => { sendWhatsAppMessageSocket(ticket, msg); }, 2000); diff --git a/backend/src/services/UserServices/DeleteUserService.ts b/backend/src/services/UserServices/DeleteUserService.ts index ef454e3..7209cf2 100644 --- a/backend/src/services/UserServices/DeleteUserService.ts +++ b/backend/src/services/UserServices/DeleteUserService.ts @@ -1,8 +1,8 @@ import User from "../../models/User"; import AppError from "../../errors/AppError"; import Ticket from "../../models/Ticket"; -import UpdateDeletedUserOpenTicketsStatus from "../../helpers/UpdateDeletedUserOpenTicketsStatus"; - +import UpdateDeletedUserOpenTicketsStatus from "../../helpers/UpdateDeletedUserOpenTicketsStatus"; +import { set } from "../../helpers/RedisClient" const DeleteUserService = async (id: string | number): Promise => { const user = await User.findOne({ @@ -13,6 +13,17 @@ const DeleteUserService = async (id: string | number): Promise => { throw new AppError("ERR_NO_USER_FOUND", 404); } + if (user?.name?.trim() == "botqueue") { + let botInfo = JSON.stringify({ + userId: 0, + queueId: 0, + botIsOnQueue: false + }); + botInfo = JSON.parse(botInfo); + + await set("botInfo", botInfo); + } + const userOpenTickets: Ticket[] = await user.$get("tickets", { where: { status: "open" } }); @@ -21,9 +32,7 @@ const DeleteUserService = async (id: string | number): Promise => { UpdateDeletedUserOpenTicketsStatus(userOpenTickets); } - - await user.destroy(); - + await user.destroy(); }; export default DeleteUserService; diff --git a/backend/src/services/WbotServices/wbotMessageListener.ts b/backend/src/services/WbotServices/wbotMessageListener.ts index f781560..8047d02 100644 --- a/backend/src/services/WbotServices/wbotMessageListener.ts +++ b/backend/src/services/WbotServices/wbotMessageListener.ts @@ -88,6 +88,7 @@ import { Op } from "sequelize"; import SettingTicket from "../../models/SettingTicket"; import mostRepeatedPhrase from "../../helpers/MostRepeatedPhrase"; import ListWhatsAppsNumber from "../WhatsappService/ListWhatsAppsNumber"; +import { createObject, findObject, get } from "../../helpers/RedisClient"; var lst: any[] = getWhatsappIds(); @@ -298,8 +299,8 @@ const verifyQueue = async ( 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); @@ -337,9 +338,17 @@ const verifyQueue = async ( ticketId: ticket.id }); - data_ura.forEach((s, index) => { - botOptions += `*${index + 1}* - ${s.option}\n`; + const data = await get("ura"); + + await createObject({ + whatsappId: `${ticket.whatsappId}`, + contactId: `${ticket.contactId}`, + identifier: "ura", + value: data[1].id }); + + botSendMessage(ticket, data[1].value); + return; } // @@ -479,12 +488,35 @@ const queuesOutBot = async (wbot: Session, botId: string | number) => { return { queues, greetingMessage }; }; -const botTransferTicket = async ( - queues: Queue, - ticket: Ticket, - contact: Contact, - wbot: Session -) => { +const transferTicket = async (queueName: any, wbot: any, ticket: Ticket) => { + const botInfo = await BotIsOnQueue("botqueue"); + + console.log("kkkkkkkkkkkkkkkkkkkkk queueName: ", queueName); + + const queuesWhatsGreetingMessage = await queuesOutBot( + wbot, + botInfo.botQueueId + ); + + let queue: any; + + const queues = queuesWhatsGreetingMessage.queues; + + // console.log("queues ---> ", console.log(JSON.stringify(queues, null, 6))); + + if (typeof queueName == "string") { + queue = queues.find( + (q: any) => q?.name?.toLowerCase() == queueName.trim().toLowerCase() + ); + // await deleteObject(wbot.id, `${ticket.contactId}`, "ura"); + } else if (typeof queueName == "number") { + queue = queues[queueName]; + } + + if (queue) await botTransferTicket(queue, ticket); +}; + +const botTransferTicket = async (queues: Queue, ticket: Ticket) => { await ticket.update({ userId: null }); await UpdateTicketService({ @@ -550,7 +582,7 @@ const handleMessage = async ( try { let msgContact: any = wbot.msgContact; - // let groupContact: Contact | undefined; + // let groupContact: Contact | undefined; if (msg.fromMe) { const whatsapp = await whatsappInfo(wbot.id); @@ -683,9 +715,72 @@ 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 - // const botInfo = await BotIsOnQueue('botqueue') + const botInfo = await BotIsOnQueue("botqueue"); // const botInfo = { isOnQueue: false, botQueueId: 0, userIdBot: 0 }; + if ( + botInfo.isOnQueue && + !msg.fromMe && + ticket.userId == botInfo.userIdBot + ) { + const repet: any = await mostRepeatedPhrase(ticket.id); + + console.log("repet.occurrences: ", repet.occurrences); + + if (repet.occurrences > 4) { + await transferTicket(0, wbot, ticket); + + await SendWhatsAppMessage({ + body: `Seu atendimento foi transferido para um agente!\n\nPara voltar ao menu principal digite *0* + `, + ticket, + number: `${contact.number}@c.us` + }); + } else { + console.log("MSG body: ", msg.body); + + const menuMsg: any = await menu(msg.body, wbot.id, contact.id); + + console.log("menuMsg: ", menuMsg); + + await botSendMessage(ticket, menuMsg.value); + + if ( + menuMsg?.transferToQueue && + menuMsg.transferToQueue.trim().length > 0 + ) { + console.log( + "YYYYYYYYYYYYYYYYYYYY menuMsg.transferToQueue: ", + menuMsg.transferToQueue + ); + + transferTicket(menuMsg.transferToQueue.trim(), wbot, ticket); + } + } + + return; + } else if ( + !msg.fromMe && + msg.body == "0" && + ticket.status == "pending" && + ticket.queueId + ) { + let choosenQueue = await ShowQueueService(botInfo.botQueueId); + + await UpdateTicketService({ + ticketData: { + status: "open", + userId: botInfo.userIdBot, + queueId: choosenQueue.id + }, + ticketId: ticket.id + }); + const menuMsg: any = await menu(msg.body, wbot.id, contact.id); + await botSendMessage(ticket, menuMsg.value); + + return; + } + if (msg && !msg.fromMe && ticket.status == "pending") { await setMessageAsRead(ticket); } @@ -720,6 +815,133 @@ const handleMessage = async ( } }; +const menu = async (userTyped: string, whatsappId: any, contactId: any) => { + let lastId = await findObject(whatsappId, contactId, "ura"); + const data: any = await get("ura"); + + console.log("lastId[0]: ", lastId[0]); + + if (!lastId[0]) { + await createObject({ + whatsappId, + contactId, + identifier: "ura", + value: data[1].id + }); + } + + lastId = await findObject(whatsappId, contactId, "ura"); + console.log("LAST ID: ", lastId); + let option: any; + + if ( + lastId && + lastId.length == 4 && + lastId[3] && + lastId[3].trim().length > 0 + ) { + option = data.find( + (o: any) => + o.idmaster == lastId[3] && + o.value.toLowerCase() == userTyped.toLowerCase() + ); + + // TEST DEL + console.log("OPTION: ", option); + + if (!option && userTyped != "0") { + if (!existSubMenu()) { + const response = await mainOptionsMenu(userTyped); + if (response) return response; + else { + console.log("kkkkkkkkkkkkkkkkkkk"); + await createObject({ + whatsappId, + contactId, + identifier: "ura", + value: data[1].id + }); + + return data[1]; + } + } + } + // + + if (option) { + let response: any = data.find((o: any) => o.idmaster == option.id); + + console.log( + "RRRRRRRRRRRRRRRRRRRRRRRRRRRRR response: ", + response, + " | option: ", + option + ); + + await createObject({ + whatsappId, + contactId, + identifier: "ura", + value: response.id + }); + + return response; + } else if (userTyped == "0") { + await createObject({ + whatsappId, + contactId, + identifier: "ura", + value: data[1].id + }); + + return data[1]; + } else { + console.log("INVALID SEARCH"); + + let response = await existSubMenu(); + if (response) return response; + + return { + value: data.find((o: any) => o.id == lastId[3])?.value + }; + + // return { + // value: `Você digitou uma opçao inválida!\n\n${ + // data.find((o: any) => o.id == lastId[3])?.value + // }\n\nDigite 0 para voltar ao menu ` + // }; + } + } + + function existSubMenu() { + let existSubMenu = data.find((o: any) => o.idmaster == lastId[3]); + + if (existSubMenu) true; + + return false; + } + + async function mainOptionsMenu(userTyped: any) { + let menuOption = data.find( + (o: any) => o.value.toLowerCase() == userTyped.toLowerCase() + ); + console.log("============> menuOption OPTION: ", menuOption); + if (menuOption) { + let response = data.find((o: any) => o.idmaster == menuOption.id); + if (response) { + await createObject({ + whatsappId, + contactId, + identifier: "ura", + value: response.id + }); + + return response; + } + } + } +}; + const handleMsgAck = async ( msg_id: any, ack: any, diff --git a/frontend/src/components/TicketsManager/index.js b/frontend/src/components/TicketsManager/index.js index a6f80d5..06ac9c9 100644 --- a/frontend/src/components/TicketsManager/index.js +++ b/frontend/src/components/TicketsManager/index.js @@ -161,7 +161,9 @@ const TicketsManager = () => { let searchContentTimeout; useEffect(() => { - if (user.profile.toUpperCase() === "ADMIN") { + if (user.profile.toUpperCase() === "ADMIN" || + user.profile.toUpperCase() === "SUPERVISOR" || + user.profile.toUpperCase() === "MASTER") { setShowAllTickets(true); } // eslint-disable-next-line react-hooks/exhaustive-deps diff --git a/frontend/src/rules.js b/frontend/src/rules.js index 2f645fc..f853fc2 100644 --- a/frontend/src/rules.js +++ b/frontend/src/rules.js @@ -9,7 +9,8 @@ const rules = { "user-view:show", "user-modal:editQueues", 'dashboard-view:show', - 'ticket-report:show' + 'ticket-report:show', + 'tickets-manager:showall' ] },