From fec4f8295716e80dcdb4841e4e985729479de890 Mon Sep 17 00:00:00 2001 From: Danilo Alves Date: Fri, 7 Jan 2022 16:19:58 -0300 Subject: [PATCH] Corrigido problema ao renderizar VCards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolvido problema ao renderizar VCards. Não consegui realizar a renderização de Multi_VCards mas deixei comentado a rotina quando for resolvido o problema de retornar body vazio ao enviar ou receber Multi_VCards --- backend/src/controllers/ContactController.ts | 17 +++ backend/src/routes/contactRoutes.ts | 2 + .../ContactServices/GetContactService.ts | 29 +++++ .../WbotServices/wbotMessageListener.ts | 114 ++++++++++++++---- .../src/components/MarkdownWrapper/index.js | 10 +- frontend/src/components/MessageInput/index.js | 2 +- frontend/src/components/MessagesList/index.js | 57 +++++++-- .../components/NotificationsPopOver/index.js | 4 +- frontend/src/components/VcardPreview/index.js | 89 ++++++++++++++ 9 files changed, 285 insertions(+), 39 deletions(-) create mode 100644 backend/src/services/ContactServices/GetContactService.ts create mode 100644 frontend/src/components/VcardPreview/index.js diff --git a/backend/src/controllers/ContactController.ts b/backend/src/controllers/ContactController.ts index 536ba3a..767863a 100644 --- a/backend/src/controllers/ContactController.ts +++ b/backend/src/controllers/ContactController.ts @@ -12,12 +12,18 @@ import CheckContactNumber from "../services/WbotServices/CheckNumber" import CheckIsValidContact from "../services/WbotServices/CheckIsValidContact"; import GetProfilePicUrl from "../services/WbotServices/GetProfilePicUrl"; import AppError from "../errors/AppError"; +import GetContactService from "../services/ContactServices/GetContactService"; type IndexQuery = { searchParam: string; pageNumber: string; }; +type IndexGetContactQuery = { + name: string; + number: string; +}; + interface ExtraInfo { name: string; value: string; @@ -40,6 +46,17 @@ export const index = async (req: Request, res: Response): Promise => { return res.json({ contacts, count, hasMore }); }; +export const getContact = async (req: Request, res: Response): Promise => { + const { name, number } = req.body as IndexGetContactQuery; + + const contact = await GetContactService({ + name, + number + }); + + return res.status(200).json(contact); +}; + export const store = async (req: Request, res: Response): Promise => { const newContact: ContactData = req.body; newContact.number = newContact.number.replace("-", "").replace(" ", ""); diff --git a/backend/src/routes/contactRoutes.ts b/backend/src/routes/contactRoutes.ts index 5bbc100..1e8ff2b 100644 --- a/backend/src/routes/contactRoutes.ts +++ b/backend/src/routes/contactRoutes.ts @@ -18,6 +18,8 @@ contactRoutes.get("/contacts/:contactId", isAuth, ContactController.show); contactRoutes.post("/contacts", isAuth, ContactController.store); +contactRoutes.post("/contact", isAuth, ContactController.getContact); + contactRoutes.put("/contacts/:contactId", isAuth, ContactController.update); contactRoutes.delete("/contacts/:contactId", isAuth, ContactController.remove); diff --git a/backend/src/services/ContactServices/GetContactService.ts b/backend/src/services/ContactServices/GetContactService.ts new file mode 100644 index 0000000..93b12e3 --- /dev/null +++ b/backend/src/services/ContactServices/GetContactService.ts @@ -0,0 +1,29 @@ +import AppError from "../../errors/AppError"; +import Contact from "../../models/Contact"; + +interface ExtraInfo { + name: string; + value: string; +} + +interface Request { + name: string; + number: string; + email?: string; + profilePicUrl?: string; + extraInfo?: ExtraInfo[]; +} + +const GetContactService = async ({ name, number }: Request): Promise => { + const numberExists = await Contact.findOne({ + where: { number } + }); + + if (!numberExists) { + throw new AppError("CONTACT_NOT_FIND"); + } + + return numberExists; +}; + +export default GetContactService; \ No newline at end of file diff --git a/backend/src/services/WbotServices/wbotMessageListener.ts b/backend/src/services/WbotServices/wbotMessageListener.ts index c443ebc..ea5eb0d 100644 --- a/backend/src/services/WbotServices/wbotMessageListener.ts +++ b/backend/src/services/WbotServices/wbotMessageListener.ts @@ -22,6 +22,8 @@ import FindOrCreateTicketService from "../TicketServices/FindOrCreateTicketServi import ShowWhatsAppService from "../WhatsappService/ShowWhatsAppService"; import { debounce } from "../../helpers/Debounce"; import UpdateTicketService from "../TicketServices/UpdateTicketService"; +import CreateContactService from "../ContactServices/CreateContactService"; +import GetContactService from "../ContactServices/GetContactService"; interface Session extends Client { id?: number; @@ -196,6 +198,7 @@ const isValidMsg = (msg: WbotMessage): boolean => { msg.type === "image" || msg.type === "document" || msg.type === "vcard" || + //msg.type === "multi_vcard" || msg.type === "sticker" ) return true; @@ -222,7 +225,9 @@ const handleMessage = async ( // media messages sent from me from cell phone, first comes with "hasMedia = false" and type = "image/ptt/etc" // in this case, return and let this message be handled by "media_uploaded" event, when it will have "hasMedia = true" - if (!msg.hasMedia && msg.type !== "chat" && msg.type !== "vcard") return; + if (!msg.hasMedia && msg.type !== "chat" && msg.type !== "vcard" + //&& msg.type !== "multi_vcard" + ) return; msgContact = await wbot.getContactById(msg.to); } else { @@ -249,32 +254,93 @@ const handleMessage = async ( const contact = await verifyContact(msgContact); - if ( unreadMessages === 0 && whatsapp.farewellMessage && whatsapp.farewellMessage === msg.body) return; + if (unreadMessages === 0 && whatsapp.farewellMessage && whatsapp.farewellMessage === msg.body) return; - const ticket = await FindOrCreateTicketService( - contact, - wbot.id!, - unreadMessages, - groupContact - ); + const ticket = await FindOrCreateTicketService( + contact, + wbot.id!, + unreadMessages, + groupContact + ); - if (msg.hasMedia) { - await verifyMediaMessage(msg, ticket, contact); - } else { - await verifyMessage(msg, ticket, contact); + if (msg.hasMedia) { + await verifyMediaMessage(msg, ticket, contact); + } else { + await verifyMessage(msg, ticket, contact); + } + + if ( + !ticket.queue && + !chat.isGroup && + !msg.fromMe && + !ticket.userId && + whatsapp.queues.length >= 1 + ) { + await verifyQueue(wbot, msg, ticket, contact); + } + + if (msg.type === "vcard") { try { const array = msg.body.split("\n"); const obj = []; let contact = ""; for (let index = 0; index < array.length; index++) { const v = array[index]; const values = v.split(":"); for (let ind = 0; ind < values.length; ind++) { if (values[ind].indexOf("+") !== -1) { obj.push({ number: values[ind] }); } if (values[ind].indexOf("FN") !== -1) { contact = values[ind + 1]; } } } for await (const ob of obj) { const cont = await CreateContactService({ name: contact, number: ob.number.replace(/\D/g, "") }); } } catch (error) { console.log(error); } } + + /*if (msg.type === "multi_vcard") { + try { + const array = msg.vCards.toString().split("\n"); + let name = ""; + let number = ""; + const obj = []; + const conts = []; + for (let index = 0; index < array.length; index++) { + const v = array[index]; + const values = v.split(":"); + for (let ind = 0; ind < values.length; ind++) { + if (values[ind].indexOf("+") !== -1) { + number = values[ind]; + } + if (values[ind].indexOf("FN") !== -1) { + name = values[ind + 1]; + } + if (name !== "" && number !== "") { + obj.push({ + name, + number + }); + name = ""; + number = ""; + } + } + } + + // eslint-disable-next-line no-restricted-syntax + for await (const ob of obj) { + try { + const cont = await CreateContactService({ + name: ob.name, + number: ob.number.replace(/\D/g, "") + }); + conts.push({ + id: cont.id, + name: cont.name, + number: cont.number + }); + } catch (error) { + if (error.message === "ERR_DUPLICATED_CONTACT") { + const cont = await GetContactService({ + name: ob.name, + number: ob.number.replace(/\D/g, ""), + email: "" + }); + conts.push({ + id: cont.id, + name: cont.name, + number: cont.number + }); + } + } + } + msg.body = JSON.stringify(conts); + } catch (error) { + console.log(error); } - - if ( - !ticket.queue && - !chat.isGroup && - !msg.fromMe && - !ticket.userId && - whatsapp.queues.length >= 1 - ) { - await verifyQueue(wbot, msg, ticket, contact); - } - - + }*/ } catch (err) { Sentry.captureException(err); diff --git a/frontend/src/components/MarkdownWrapper/index.js b/frontend/src/components/MarkdownWrapper/index.js index 64764b2..29ea445 100644 --- a/frontend/src/components/MarkdownWrapper/index.js +++ b/frontend/src/components/MarkdownWrapper/index.js @@ -152,7 +152,11 @@ const CustomLink = ({ children, ...props }) => ( const MarkdownWrapper = ({ children }) => { const boldRegex = /\*(.*?)\*/g; const tildaRegex = /~(.*?)~/g; - + + if(children.includes('BEGIN:VCARD')) + //children = "Diga olá ao seu novo contato clicando em *conversar*!"; + children = null; + if (children && boldRegex.test(children)) { children = children.replace(boldRegex, "**$1**"); } @@ -179,8 +183,8 @@ const MarkdownWrapper = ({ children }) => { }, []); if (!children) return null; - + return {children}; }; -export default MarkdownWrapper; +export default MarkdownWrapper; \ No newline at end of file diff --git a/frontend/src/components/MessageInput/index.js b/frontend/src/components/MessageInput/index.js index 3a33829..6de3d9f 100644 --- a/frontend/src/components/MessageInput/index.js +++ b/frontend/src/components/MessageInput/index.js @@ -584,7 +584,7 @@ const MessageInput = ({ ticketStatus }) => { : i18n.t("messagesInput.placeholderClosed") } multiline - rowsMax={5} + maxRows={5} value={inputMessage} onChange={handleChangeInput} disabled={recording || loading || ticketStatus !== "open"} diff --git a/frontend/src/components/MessagesList/index.js b/frontend/src/components/MessagesList/index.js index ef91b81..5a9cf21 100644 --- a/frontend/src/components/MessagesList/index.js +++ b/frontend/src/components/MessagesList/index.js @@ -22,6 +22,7 @@ import { } from "@material-ui/icons"; import MarkdownWrapper from "../MarkdownWrapper"; +import VcardPreview from "../VcardPreview"; import ModalImageCors from "../ModalImageCors"; import MessageOptionsMenu from "../MessageOptionsMenu"; import whatsBackground from "../../assets/wa-background.png"; @@ -413,18 +414,52 @@ const MessagesList = ({ ticketId, isGroup }) => { }; const checkMessageMedia = (message) => { - if (message.mediaType === "image") { + if (message.mediaType === "vcard") { + //console.log("vcard") + //console.log(message) + let array = message.body.split("\n"); + let obj = []; + let contact = ""; + for (let index = 0; index < array.length; index++) { + const v = array[index]; + let values = v.split(":"); + for (let ind = 0; ind < values.length; ind++) { + if (values[ind].indexOf("+") !== -1) { + obj.push({ number: values[ind] }); + } + if (values[ind].indexOf("FN") !== -1) { + contact = values[ind + 1]; + } + } + } + return + } + /*else if (message.mediaType === "multi_vcard") { + console.log("multi_vcard") + console.log(message) + + if(message.body !== null && message.body !== "") { + let newBody = JSON.parse(message.body) + return ( + <> + { + newBody.map(v => ( + + )) + } + + ) + } else return (<>) + }*/ + else if (message.mediaType === "image") { return ; - } - if (message.mediaType === "audio") { + } else if (message.mediaType === "audio") { return ( ); - } - - if (message.mediaType === "video") { + } else if (message.mediaType === "video") { return (