From 48834af7debf81aa57a9f4261916889dc446572b Mon Sep 17 00:00:00 2001 From: adriano Date: Tue, 6 Jun 2023 14:59:06 -0300 Subject: [PATCH] =?UTF-8?q?Adapta=C3=A7=C3=A3o=20para=20abrir=20links=20de?= =?UTF-8?q?=20whasapp=20wa=20pelo=20brower=20usando=20plugin=20de=20tercei?= =?UTF-8?q?ro=20no=20chrome?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/controllers/TicketController.ts | 27 ++-- backend/src/libs/socket.ts | 4 + backend/src/routes/ticketRoutes.ts | 8 +- .../MessageServices/ListMessagesService.ts | 11 ++ .../TicketServices/CreateTicketService.ts | 11 +- .../TicketServices/UpdateTicketService.ts | 125 +++++++++--------- frontend/src/components/Ticket/index.js | 96 +++++++++++--- frontend/src/components/TicketsList/index.js | 8 +- 8 files changed, 195 insertions(+), 95 deletions(-) diff --git a/backend/src/controllers/TicketController.ts b/backend/src/controllers/TicketController.ts index eb3bc3a..60ef621 100644 --- a/backend/src/controllers/TicketController.ts +++ b/backend/src/controllers/TicketController.ts @@ -19,7 +19,7 @@ import ptBR from 'date-fns/locale/pt-BR'; import { splitDateTime } from "../helpers/SplitDateTime"; import format from 'date-fns/format'; -import ListTicketsServiceCache from "../services/TicketServices/ListTicketServiceCache"; +import ListTicketsServiceCache from "../services/TicketServices/ListTicketServiceCache"; import { searchTicketCache, loadTicketsCache, } from '../helpers/TicketCache' @@ -41,6 +41,7 @@ interface TicketData { status: string; queueId: number; userId: number; + msg?: string, } @@ -51,6 +52,7 @@ import TicketEmiterSumOpenClosedByUser from "../helpers/OnlineReporEmiterInfoByU import CountTicketService from "../services/TicketServices/CountTicketService"; import CountTicketsByUserQueue from "../services/UserServices/CountTicketsByUserQueue"; import ShowUserService from "../services/UserServices/ShowUserService"; +import axios from "axios"; export const index = async (req: Request, res: Response): Promise => { @@ -90,19 +92,19 @@ export const index = async (req: Request, res: Response): Promise => { }; export const store = async (req: Request, res: Response): Promise => { - const { contactId, status, userId }: TicketData = req.body; - + const { contactId, status, userId, msg }: TicketData = req.body; + console.log('TICKET CREATE: ', 'contactId: ', contactId, ' | status: ', status, ' | userId: ', userId) // test del let ticket = await Ticket.findOne({ where: { contactId, status: 'queueChoice' } }); if (ticket) { - await UpdateTicketService({ ticketData: { status: 'open', userId: userId, }, ticketId: ticket.id }); - + await UpdateTicketService({ ticketData: { status: 'open', userId: userId,}, ticketId: ticket.id, msg }); + } else { - ticket = await CreateTicketService({ contactId, status, userId }); + ticket = await CreateTicketService({ contactId, status, userId, msg }); } const io = getIO(); @@ -127,7 +129,7 @@ export const store = async (req: Request, res: Response): Promise => { export const show = async (req: Request, res: Response): Promise => { const { ticketId } = req.params; - + const contact = await ShowTicketService(ticketId); const { statusChatEnd, count, hasMore } = await ListStatusChatEndService({ searchParam: "", pageNumber: "1" }); @@ -138,8 +140,7 @@ export const show = async (req: Request, res: Response): Promise => { return res.status(200).json({ contact, statusChatEnd, schedulesContact }); -}; - +}; export const count = async (req: Request, res: Response): Promise => { @@ -150,10 +151,8 @@ export const count = async (req: Request, res: Response): Promise => { return res.status(200).json(ticketCount); }; - - export const update = async (req: Request, res: Response): Promise => { const { ticketId } = req.params; @@ -190,11 +189,11 @@ export const update = async (req: Request, res: Response): Promise => await SendWhatsAppMessage({ body: farewellMessage, ticket }); } } - + // lembrete // agendamento if (scheduleData.statusChatEndId === '2' || scheduleData.statusChatEndId === '3') { - + if (isScheduling(scheduleData.schedulingDate, scheduleData.schedulingTime)) { console.log('*** É AGENDAMENTO!') @@ -246,7 +245,7 @@ export const update = async (req: Request, res: Response): Promise => const dateToday = splitDateTime(new Date(format(new Date(), 'yyyy-MM-dd HH:mm:ss', { locale: ptBR }))) - if (userOldInfo.userId) { + if (userOldInfo.userId) { TicketEmiterSumOpenClosedByUser(userOldInfo.userId.toString(), dateToday.fullDate, dateToday.fullDate) diff --git a/backend/src/libs/socket.ts b/backend/src/libs/socket.ts index 8eb1464..50ee860 100644 --- a/backend/src/libs/socket.ts +++ b/backend/src/libs/socket.ts @@ -221,6 +221,10 @@ export const initIO = (httpServer: Server): SocketIO => { socket.on("joinChatBox", (ticketId: string) => { logger.info("A client joined a ticket channel"); + + const regex = /^[0-9\b]+$/; // Regular expression to match only numbers + if (ticketId && !ticketId.match(regex)) return + socket.join(ticketId); }); diff --git a/backend/src/routes/ticketRoutes.ts b/backend/src/routes/ticketRoutes.ts index 0524925..2813482 100644 --- a/backend/src/routes/ticketRoutes.ts +++ b/backend/src/routes/ticketRoutes.ts @@ -3,16 +3,16 @@ import isAuth from "../middleware/isAuth"; import * as TicketController from "../controllers/TicketController"; -const ticketRoutes = express.Router(); +const ticketRoutes = express.Router(); // ticketRoutes.get("/tickets/cache", isAuth, TicketController.ticketsCache); -ticketRoutes.get("/tickets/count", isAuth, TicketController.count); +ticketRoutes.get("/tickets/count", isAuth, TicketController.count); -ticketRoutes.get("/tickets", isAuth, TicketController.index); +ticketRoutes.get("/tickets", isAuth, TicketController.index); -ticketRoutes.get("/tickets/:ticketId", isAuth, TicketController.show); +ticketRoutes.get("/tickets/:ticketId", isAuth, TicketController.show); ticketRoutes.post("/tickets", isAuth, TicketController.store); diff --git a/backend/src/services/MessageServices/ListMessagesService.ts b/backend/src/services/MessageServices/ListMessagesService.ts index 459f2a6..a986f16 100644 --- a/backend/src/services/MessageServices/ListMessagesService.ts +++ b/backend/src/services/MessageServices/ListMessagesService.ts @@ -19,6 +19,17 @@ const ListMessagesService = async ({ pageNumber = "1", ticketId }: Request): Promise => { + + if (ticketId && ticketId.includes("&&text=")) { + return { + messages: [], + ticket: new Ticket, + count: 0, + hasMore: false + }; + + } + const ticket = await ShowTicketService(ticketId); if (!ticket) { diff --git a/backend/src/services/TicketServices/CreateTicketService.ts b/backend/src/services/TicketServices/CreateTicketService.ts index f44e00b..75db36f 100644 --- a/backend/src/services/TicketServices/CreateTicketService.ts +++ b/backend/src/services/TicketServices/CreateTicketService.ts @@ -19,6 +19,7 @@ import ShowWhatsAppService from "../WhatsappService/ShowWhatsAppService"; import Whatsapp from "../../models/Whatsapp"; import whatsappQueueMatchingUserQueue from "../../helpers/whatsappQueueMatchingUserQueue"; import User from "../../models/User"; +import sendWhatsAppMessageSocket from "../../helpers/SendWhatsappMessageSocket"; let flatten = require('flat') @@ -27,12 +28,14 @@ interface Request { contactId: number; status: string; userId: number; + msg?: string } const CreateTicketService = async ({ contactId, status, - userId + userId, + msg = '' }: Request): Promise => { try { @@ -72,6 +75,12 @@ const CreateTicketService = async ({ // console.log('CONTACT ticket.id: ', ticket.id) + // console.log('>>>>>>>>>>>>>>>>> msg: ', msg) + + if (msg.length > 0) { + sendWhatsAppMessageSocket(ticket, msg) + } + try { diff --git a/backend/src/services/TicketServices/UpdateTicketService.ts b/backend/src/services/TicketServices/UpdateTicketService.ts index 3cafa11..8855932 100644 --- a/backend/src/services/TicketServices/UpdateTicketService.ts +++ b/backend/src/services/TicketServices/UpdateTicketService.ts @@ -8,20 +8,22 @@ import ShowTicketService from "./ShowTicketService"; import { createOrUpdateTicketCache } from '../../helpers/TicketCache' import AppError from "../../errors/AppError"; +import sendWhatsAppMessageSocket from "../../helpers/SendWhatsappMessageSocket"; var flatten = require('flat') - + interface TicketData { status?: string; userId?: number; queueId?: number; - statusChatEnd?: string + statusChatEnd?: string; } interface Request { ticketData: TicketData; - ticketId: string | number; + ticketId: string | number; + msg?: string } interface Response { @@ -32,83 +34,88 @@ interface Response { const UpdateTicketService = async ({ ticketData, - ticketId + ticketId, + msg='' }: Request): Promise => { try { const { status, userId, queueId, statusChatEnd } = ticketData; - const ticket = await ShowTicketService(ticketId); - // await SetTicketMessagesAsRead(ticket); + const ticket = await ShowTicketService(ticketId); + // await SetTicketMessagesAsRead(ticket); - const oldStatus = ticket.status; - const oldUserId = ticket.user?.id; + const oldStatus = ticket.status; + const oldUserId = ticket.user?.id; - if (oldStatus === "closed") { - await CheckContactOpenTickets(ticket.contact.id); - } - - await ticket.update({ - status, - queueId, - userId, - statusChatEnd - }); + if (oldStatus === "closed") { + await CheckContactOpenTickets(ticket.contact.id); + } - await ticket.reload(); - - // TEST DEL - try { - - // const { name, number } = await ShowContactService(ticket.contactId) - - let jsonString = JSON.stringify(ticket); //convert to string to remove the sequelize specific meta data - let ticket_obj = JSON.parse(jsonString); //to make plain json - delete ticket_obj['contact']['extraInfo'] - delete ticket_obj['user'] - - ticket_obj = flatten(ticket_obj) - - await createOrUpdateTicketCache(`ticket:${ticket.id}`, ticket_obj) - - } catch (error) { - console.log('There was an error on UpdateTicketService.ts on createTicketCache: ', error) - } - // - - let io = getIO(); - - if (ticket.status !== oldStatus || ticket.user?.id !== oldUserId) { - io.to(oldStatus).emit("ticket", { - action: "delete", - ticketId: ticket.id + await ticket.update({ + status, + queueId, + userId, + statusChatEnd }); - } + + await ticket.reload(); + + if (msg.length > 0) { + sendWhatsAppMessageSocket(ticket, msg) + } + + // TEST DEL + try { + + // const { name, number } = await ShowContactService(ticket.contactId) + + let jsonString = JSON.stringify(ticket); //convert to string to remove the sequelize specific meta data + let ticket_obj = JSON.parse(jsonString); //to make plain json + delete ticket_obj['contact']['extraInfo'] + delete ticket_obj['user'] + + ticket_obj = flatten(ticket_obj) + + await createOrUpdateTicketCache(`ticket:${ticket.id}`, ticket_obj) + + } catch (error) { + console.log('There was an error on UpdateTicketService.ts on createTicketCache: ', error) + } + // + + let io = getIO(); + + if (ticket.status !== oldStatus || ticket.user?.id !== oldUserId) { + io.to(oldStatus).emit("ticket", { + action: "delete", + ticketId: ticket.id + }); + } - io.to(ticket.status) - .to("notification") - .to(ticketId.toString()) - .emit("ticket", { + io.to(ticket.status) + .to("notification") + .to(ticketId.toString()) + .emit("ticket", { + action: "update", + ticket + }); + + + io.emit("ticketStatus", { action: "update", - ticket + ticketStatus: { ticketId: ticket.id, status: ticket.status } }); - io.emit("ticketStatus", { - action: "update", - ticketStatus: { ticketId: ticket.id, status: ticket.status } - }); + return { ticket, oldStatus, oldUserId }; - - return { ticket, oldStatus, oldUserId }; - } catch (error: any) { console.error('===> Error on UpdateTicketService.ts file: \n', error) throw new AppError(error.message); } - + }; export default UpdateTicketService; diff --git a/frontend/src/components/Ticket/index.js b/frontend/src/components/Ticket/index.js index 6b4a1cb..33ff6e2 100644 --- a/frontend/src/components/Ticket/index.js +++ b/frontend/src/components/Ticket/index.js @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import React, { useState, useEffect, useContext } from "react"; import { useParams, useHistory } from "react-router-dom"; import { toast } from "react-toastify"; @@ -17,6 +17,8 @@ import api from "../../services/api"; import { ReplyMessageProvider } from "../../context/ReplyingMessage/ReplyingMessageContext"; import toastError from "../../errors/toastError"; +import { AuthContext } from "../../context/Auth/AuthContext" + const drawerWidth = 320; const useStyles = makeStyles((theme) => ({ @@ -74,6 +76,10 @@ const useStyles = makeStyles((theme) => ({ })); const Ticket = () => { + + const { user } = useContext(AuthContext); + + const { ticketId } = useParams(); const history = useHistory(); const classes = useStyles(); @@ -83,38 +89,98 @@ const Ticket = () => { const [contact, setContact] = useState({}); const [ticket, setTicket] = useState({}); - const [statusChatEnd, setStatusChatEnd] = useState({}) + const [statusChatEnd, setStatusChatEnd] = useState({}) useEffect(() => { setLoading(true); const delayDebounceFn = setTimeout(() => { - const fetchTicket = async () => { - try { - - // maria julia + const fetchTicket = async () => { - const { data } = await api.get("/tickets/" + ticketId); + try { - // setContact(data.contact); - // setTicket(data); + let number + let msg + let contactId - setContact(data.contact.contact); - setTicket(data.contact); + if (ticketId && ticketId.includes("&&text=")) { + + number = ticketId.split('&&text=')[0] + msg = ticketId.split('&&text=')[1] + + msg = decodeURIComponent(msg); + + + console.log('NUMBER: ', number) + + const { data: data0 } = await api.get("/contacts/", { params: { searchParam: number, pageNumber: "1" }, }); + + if (data0 && data0.contacts.length > 0) { + console.log('-----> data: ', data0.contacts[0].id) + contactId = data0.contacts[0].id + } + else { + console.log('NO CONTACT whith this NUMBER: ', number) + + const values = { + name: number, + number: number, + }; + + const { data: data1 } = await api.post("/contacts", values); + + console.log('data1: ', data1) + + contactId = data1.id + + } + + const { data: ticket } = await api.post("/tickets", { + contactId: contactId, + userId: user.id, + status: "open", + msg + }); + + window.location.reload(); + history.push(`/tickets/${ticket.id}`); + window.location.reload(); + + } + else { + + console.log('>>>>>>>>>>>>>>>>>>>>>>>>> ticketId: ', ticketId) + + const { data } = await api.get("/tickets/" + ticketId); + + // setContact(data.contact); + // setTicket(data); + + setContact(data.contact.contact); + setTicket(data.contact); + + setStatusChatEnd(data.statusChatEnd) + + setLoading(false); + } - setStatusChatEnd(data.statusChatEnd) - setLoading(false); } catch (err) { setLoading(false); + console.log('ERROR: ', err) + toastError(err); } }; fetchTicket(); }, 500); return () => clearTimeout(delayDebounceFn); - }, [ticketId, history]); + }, [ticketId, history, user.id]); useEffect(() => { + + const regex = /^[0-9\b]+$/; // Regular expression to match only numbers + if (ticketId && !ticketId.match(regex)) return + const socket = openSocket(process.env.REACT_APP_BACKEND_URL); socket.on("connect", () => socket.emit("joinChatBox", ticketId)); @@ -172,7 +238,7 @@ const Ticket = () => { />
- +
diff --git a/frontend/src/components/TicketsList/index.js b/frontend/src/components/TicketsList/index.js index fb2ba3c..13d9994 100644 --- a/frontend/src/components/TicketsList/index.js +++ b/frontend/src/components/TicketsList/index.js @@ -1,4 +1,6 @@ -import React, { useState, useEffect, useReducer, useContext } from "react"; +import React, { useState, useEffect, useReducer, useContext } from "react"; + + import openSocket from "socket.io-client"; import { makeStyles } from "@material-ui/core/styles"; @@ -182,8 +184,10 @@ const TicketsList = (props) => { const { user } = useContext(AuthContext); const { searchTicket } = useContext(SearchTicketContext) + + + useEffect(() => { - useEffect(() => { dispatch({ type: "RESET" }); setPageNumber(1);