From 2e1785ea150c8bb837aef71794e4f2a7503d0a04 Mon Sep 17 00:00:00 2001 From: canove Date: Sun, 27 Sep 2020 20:10:52 -0300 Subject: [PATCH] feat: start delete whatsapp messages backend --- backend/src/controllers/MessageController.ts | 19 +++++++++- ...220708-add-isDeleted-column-to-messages.ts | 15 ++++++++ backend/src/helpers/GetWbotMessage.ts | 37 +++++++++++++++++++ backend/src/models/Message.ts | 5 ++- backend/src/routes/messageRoutes.ts | 2 + .../MessageServices/UpdateMessageService.ts | 20 ++++++++++ .../WbotServices/DeleteWhatsAppMessage.ts | 36 ++++++++++++++++++ .../components/MessageOptionsMenu/index.js | 14 +++---- 8 files changed, 138 insertions(+), 10 deletions(-) create mode 100644 backend/src/database/migrations/20200927220708-add-isDeleted-column-to-messages.ts create mode 100644 backend/src/helpers/GetWbotMessage.ts create mode 100644 backend/src/services/MessageServices/UpdateMessageService.ts create mode 100644 backend/src/services/WbotServices/DeleteWhatsAppMessage.ts diff --git a/backend/src/controllers/MessageController.ts b/backend/src/controllers/MessageController.ts index fb63e7f..273386a 100644 --- a/backend/src/controllers/MessageController.ts +++ b/backend/src/controllers/MessageController.ts @@ -6,7 +6,9 @@ import { getIO } from "../libs/socket"; import CreateMessageService from "../services/MessageServices/CreateMessageService"; import ListMessagesService from "../services/MessageServices/ListMessagesService"; +import UpdateMessageService from "../services/MessageServices/UpdateMessageService"; import ShowTicketService from "../services/TicketServices/ShowTicketService"; +import DeleteWhatsAppMessage from "../services/WbotServices/DeleteWhatsAppMessage"; import SendWhatsAppMedia from "../services/WbotServices/SendWhatsAppMedia"; import SendWhatsAppMessage from "../services/WbotServices/SendWhatsAppMessage"; @@ -43,8 +45,6 @@ export const store = async (req: Request, res: Response): Promise => { const ticket = await ShowTicketService(ticketId); - console.log(body); - let sentMessage: WbotMessage; if (media) { @@ -79,3 +79,18 @@ export const store = async (req: Request, res: Response): Promise => { return res.status(200).json(message); }; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { messageId } = req.params; + + const messageDeleted = await DeleteWhatsAppMessage(messageId); + + await UpdateMessageService({ messageData: { isDeleted: true }, messageId }); + + console.log(messageDeleted); + + return res.json({ ok: true }); +}; diff --git a/backend/src/database/migrations/20200927220708-add-isDeleted-column-to-messages.ts b/backend/src/database/migrations/20200927220708-add-isDeleted-column-to-messages.ts new file mode 100644 index 0000000..a3ffa86 --- /dev/null +++ b/backend/src/database/migrations/20200927220708-add-isDeleted-column-to-messages.ts @@ -0,0 +1,15 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Messages", "isDeleted", { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Messages", "isDeleted"); + } +}; diff --git a/backend/src/helpers/GetWbotMessage.ts b/backend/src/helpers/GetWbotMessage.ts new file mode 100644 index 0000000..918f42e --- /dev/null +++ b/backend/src/helpers/GetWbotMessage.ts @@ -0,0 +1,37 @@ +import { Message as WbotMessage } from "whatsapp-web.js"; +import Ticket from "../models/Ticket"; +import GetTicketWbot from "./GetTicketWbot"; +import AppError from "../errors/AppError"; + +export const GetWbotMessage = async ( + ticket: Ticket, + messageId: string +): Promise => { + const wbot = await GetTicketWbot(ticket); + + const wbotChat = await wbot.getChatById(`${ticket.contact.number}@c.us`); + + try { + const chatMessages = await wbotChat.fetchMessages({ limit: 20 }); + + const msgToDelete = chatMessages.find(msg => msg.id.id === messageId); + + if (!msgToDelete) { + throw new AppError("msgNotFound"); + } + + return msgToDelete; + } catch (err) { + console.log(err); + if (err.message === "msgNotFound") { + throw new AppError( + "Could not find a message witht this ID in WhatsApp chat." + ); + } + throw new AppError( + "Could not valid WhatsApp contact. Check connections page" + ); + } +}; + +export default GetWbotMessage; diff --git a/backend/src/models/Message.ts b/backend/src/models/Message.ts index b187fb4..bc2b03c 100644 --- a/backend/src/models/Message.ts +++ b/backend/src/models/Message.ts @@ -6,7 +6,6 @@ import { Model, DataType, PrimaryKey, - AutoIncrement, Default, BelongsTo, ForeignKey @@ -47,6 +46,10 @@ class Message extends Model { @Column mediaType: string; + @Default(false) + @Column + isDeleted: boolean; + @CreatedAt @Column(DataType.DATE(6)) createdAt: Date; diff --git a/backend/src/routes/messageRoutes.ts b/backend/src/routes/messageRoutes.ts index 808ac6d..554672c 100644 --- a/backend/src/routes/messageRoutes.ts +++ b/backend/src/routes/messageRoutes.ts @@ -9,4 +9,6 @@ messageRoutes.get("/messages/:ticketId", isAuth, MessageController.index); messageRoutes.post("/messages/:ticketId", isAuth, MessageController.store); +messageRoutes.delete("/messages/:messageId", isAuth, MessageController.remove); + export default messageRoutes; diff --git a/backend/src/services/MessageServices/UpdateMessageService.ts b/backend/src/services/MessageServices/UpdateMessageService.ts new file mode 100644 index 0000000..06a4aa8 --- /dev/null +++ b/backend/src/services/MessageServices/UpdateMessageService.ts @@ -0,0 +1,20 @@ +import Message from "../../models/Message"; + +interface MessageData { + isDeleted?: boolean; +} + +interface Request { + messageData: MessageData; + messageId: string; +} + +const UpdateMessageService = async ({ + messageData, + messageId +}: Request): Promise => { + const { isDeleted } = messageData; + const message = Message.update({ where: {messageId}, { isDeleted: true } } ); +}; + +export default UpdateMessageService; diff --git a/backend/src/services/WbotServices/DeleteWhatsAppMessage.ts b/backend/src/services/WbotServices/DeleteWhatsAppMessage.ts new file mode 100644 index 0000000..fdbdbd3 --- /dev/null +++ b/backend/src/services/WbotServices/DeleteWhatsAppMessage.ts @@ -0,0 +1,36 @@ +import AppError from "../../errors/AppError"; +import GetWbotMessage from "../../helpers/GetWbotMessage"; +import Message from "../../models/Message"; +import Ticket from "../../models/Ticket"; + +const DeleteWhatsAppMessage = async (messageId: string): Promise => { + const message = await Message.findByPk(messageId, { + include: [ + { + model: Ticket, + as: "ticket", + include: ["contact"] + } + ] + }); + + if (!message) { + throw new AppError("No message found with this ID."); + } + + const { ticket } = message; + + const messageToDelete = await GetWbotMessage(ticket, messageId); + + try { + await messageToDelete.delete(true); + } catch (err) { + throw new AppError( + "Couldn't delete message from WhatsApp. Check connections page." + ); + } + + return message; +}; + +export default DeleteWhatsAppMessage; diff --git a/frontend/src/components/MessageOptionsMenu/index.js b/frontend/src/components/MessageOptionsMenu/index.js index 6af3537..ae72204 100644 --- a/frontend/src/components/MessageOptionsMenu/index.js +++ b/frontend/src/components/MessageOptionsMenu/index.js @@ -1,12 +1,12 @@ import React, { useState } from "react"; -// import { toast } from "react-toastify"; +import { toast } from "react-toastify"; import MenuItem from "@material-ui/core/MenuItem"; import Menu from "@material-ui/core/Menu"; // import { i18n } from "../../translate/i18n"; -// import api from "../../services/api"; +import api from "../../services/api"; import ConfirmationModal from "../ConfirmationModal"; const MessageOptionsMenu = ({ messageId, menuOpen, handleClose, anchorEl }) => { @@ -15,11 +15,11 @@ const MessageOptionsMenu = ({ messageId, menuOpen, handleClose, anchorEl }) => { const handleDeleteMessage = async () => { console.log("message deleted", messageId); - // try { - // await api.delete(`/messages/${message.id}`); - // } catch (err) { - // toast.error("Erro ao deletar o message"); - // } + try { + await api.delete(`/messages/${messageId}`); + } catch (err) { + toast.error("Erro ao deletar o message"); + } }; const handleOpenConfirmationModal = e => {