mirror of
https://github.com/cheveguerra/whaticket-community.git
synced 2026-04-19 20:29:17 +00:00
feat: added new method to fetch old whatsapp messages
This commit is contained in:
@@ -2,6 +2,7 @@ import { Request, Response } from "express";
|
|||||||
|
|
||||||
import SetTicketMessagesAsRead from "../helpers/SetTicketMessagesAsRead";
|
import SetTicketMessagesAsRead from "../helpers/SetTicketMessagesAsRead";
|
||||||
import { getIO } from "../libs/socket";
|
import { getIO } from "../libs/socket";
|
||||||
|
import Message from "../models/Message";
|
||||||
|
|
||||||
import ListMessagesService from "../services/MessageServices/ListMessagesService";
|
import ListMessagesService from "../services/MessageServices/ListMessagesService";
|
||||||
import ShowTicketService from "../services/TicketServices/ShowTicketService";
|
import ShowTicketService from "../services/TicketServices/ShowTicketService";
|
||||||
@@ -17,6 +18,7 @@ type MessageData = {
|
|||||||
body: string;
|
body: string;
|
||||||
fromMe: boolean;
|
fromMe: boolean;
|
||||||
read: boolean;
|
read: boolean;
|
||||||
|
quotedMsg?: Message;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const index = async (req: Request, res: Response): Promise<Response> => {
|
export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||||
@@ -35,7 +37,7 @@ export const index = async (req: Request, res: Response): Promise<Response> => {
|
|||||||
|
|
||||||
export const store = async (req: Request, res: Response): Promise<Response> => {
|
export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
const { ticketId } = req.params;
|
const { ticketId } = req.params;
|
||||||
const { body }: MessageData = req.body;
|
const { body, quotedMsg }: MessageData = req.body;
|
||||||
const medias = req.files as Express.Multer.File[];
|
const medias = req.files as Express.Multer.File[];
|
||||||
|
|
||||||
const ticket = await ShowTicketService(ticketId);
|
const ticket = await ShowTicketService(ticketId);
|
||||||
@@ -47,7 +49,7 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await SendWhatsAppMessage({ body, ticket });
|
await SendWhatsAppMessage({ body, ticket, quotedMsg });
|
||||||
}
|
}
|
||||||
|
|
||||||
await SetTicketMessagesAsRead(ticket);
|
await SetTicketMessagesAsRead(ticket);
|
||||||
|
|||||||
@@ -13,19 +13,32 @@ export const GetWbotMessage = async (
|
|||||||
`${ticket.contact.number}@${ticket.isGroup ? "g" : "c"}.us`
|
`${ticket.contact.number}@${ticket.isGroup ? "g" : "c"}.us`
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
let limit = 20;
|
||||||
const chatMessages = await wbotChat.fetchMessages({ limit: 20 });
|
|
||||||
|
|
||||||
const msgToDelete = chatMessages.find(msg => msg.id.id === messageId);
|
const fetchWbotMessagesGradually = async (): Promise<void | WbotMessage> => {
|
||||||
|
const chatMessages = await wbotChat.fetchMessages({ limit });
|
||||||
|
|
||||||
if (!msgToDelete) {
|
const msgFound = chatMessages.find(msg => msg.id.id === messageId);
|
||||||
throw new Error();
|
|
||||||
|
if (!msgFound && limit < 100) {
|
||||||
|
limit += 20;
|
||||||
|
return fetchWbotMessagesGradually();
|
||||||
}
|
}
|
||||||
|
|
||||||
return msgToDelete;
|
return msgFound;
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const msgFound = await fetchWbotMessagesGradually();
|
||||||
|
|
||||||
|
if (!msgFound) {
|
||||||
|
throw new Error("Cannot found message within 100 last messages");
|
||||||
|
}
|
||||||
|
|
||||||
|
return msgFound;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
throw new AppError("ERR_DELETE_WAPP_MSG");
|
throw new AppError("ERR_FETCH_WAPP_MSG");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
12
backend/src/helpers/SerializeWbotMsgId.ts
Normal file
12
backend/src/helpers/SerializeWbotMsgId.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import Message from "../models/Message";
|
||||||
|
import Ticket from "../models/Ticket";
|
||||||
|
|
||||||
|
const SerializeWbotMsgId = (ticket: Ticket, message: Message): string => {
|
||||||
|
const serializedMsgId = `${message.fromMe}_${ticket.contact.number}@${
|
||||||
|
ticket.isGroup ? "g" : "c"
|
||||||
|
}.us_${message.id}`;
|
||||||
|
|
||||||
|
return serializedMsgId;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SerializeWbotMsgId;
|
||||||
@@ -28,7 +28,14 @@ const CreateMessageService = async ({
|
|||||||
await Message.upsert(messageData);
|
await Message.upsert(messageData);
|
||||||
|
|
||||||
const message = await Message.findByPk(messageData.id, {
|
const message = await Message.findByPk(messageData.id, {
|
||||||
include: ["contact", "quotedMsg"]
|
include: [
|
||||||
|
"contact",
|
||||||
|
{
|
||||||
|
model: Message,
|
||||||
|
as: "quotedMsg",
|
||||||
|
include: ["contact"]
|
||||||
|
}
|
||||||
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!message) {
|
if (!message) {
|
||||||
|
|||||||
@@ -32,7 +32,14 @@ const ListMessagesService = async ({
|
|||||||
const { count, rows: messages } = await Message.findAndCountAll({
|
const { count, rows: messages } = await Message.findAndCountAll({
|
||||||
where: { ticketId },
|
where: { ticketId },
|
||||||
limit,
|
limit,
|
||||||
include: ["contact", "quotedMsg"],
|
include: [
|
||||||
|
"contact",
|
||||||
|
{
|
||||||
|
model: Message,
|
||||||
|
as: "quotedMsg",
|
||||||
|
include: ["contact"]
|
||||||
|
}
|
||||||
|
],
|
||||||
offset,
|
offset,
|
||||||
order: [["createdAt", "DESC"]]
|
order: [["createdAt", "DESC"]]
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,23 +1,37 @@
|
|||||||
import { Message as WbotMessage } from "whatsapp-web.js";
|
import { Message as WbotMessage } from "whatsapp-web.js";
|
||||||
import AppError from "../../errors/AppError";
|
import AppError from "../../errors/AppError";
|
||||||
import GetTicketWbot from "../../helpers/GetTicketWbot";
|
import GetTicketWbot from "../../helpers/GetTicketWbot";
|
||||||
|
import GetWbotMessage from "../../helpers/GetWbotMessage";
|
||||||
|
import SerializeWbotMsgId from "../../helpers/SerializeWbotMsgId";
|
||||||
|
import Message from "../../models/Message";
|
||||||
import Ticket from "../../models/Ticket";
|
import Ticket from "../../models/Ticket";
|
||||||
|
|
||||||
interface Request {
|
interface Request {
|
||||||
body: string;
|
body: string;
|
||||||
ticket: Ticket;
|
ticket: Ticket;
|
||||||
|
quotedMsg?: Message;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SendWhatsAppMessage = async ({
|
const SendWhatsAppMessage = async ({
|
||||||
body,
|
body,
|
||||||
ticket
|
ticket,
|
||||||
|
quotedMsg
|
||||||
}: Request): Promise<WbotMessage> => {
|
}: Request): Promise<WbotMessage> => {
|
||||||
try {
|
let quotedMsgSerializedId: string | undefined;
|
||||||
const wbot = await GetTicketWbot(ticket);
|
if (quotedMsg) {
|
||||||
|
await GetWbotMessage(ticket, quotedMsg.id);
|
||||||
|
quotedMsgSerializedId = SerializeWbotMsgId(ticket, quotedMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
const wbot = await GetTicketWbot(ticket);
|
||||||
|
|
||||||
|
try {
|
||||||
const sentMessage = await wbot.sendMessage(
|
const sentMessage = await wbot.sendMessage(
|
||||||
`${ticket.contact.number}@${ticket.isGroup ? "g" : "c"}.us`,
|
`${ticket.contact.number}@${ticket.isGroup ? "g" : "c"}.us`,
|
||||||
body
|
body,
|
||||||
|
{
|
||||||
|
quotedMessageId: quotedMsgSerializedId
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
await ticket.update({ lastMessage: body });
|
await ticket.update({ lastMessage: body });
|
||||||
|
|||||||
@@ -344,7 +344,14 @@ const wbotMessageListener = (wbot: Session): void => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const messageToUpdate = await Message.findByPk(msg.id.id, {
|
const messageToUpdate = await Message.findByPk(msg.id.id, {
|
||||||
include: ["contact"]
|
include: [
|
||||||
|
"contact",
|
||||||
|
{
|
||||||
|
model: Message,
|
||||||
|
as: "quotedMsg",
|
||||||
|
include: ["contact"]
|
||||||
|
}
|
||||||
|
]
|
||||||
});
|
});
|
||||||
if (!messageToUpdate) {
|
if (!messageToUpdate) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect, useContext } from "react";
|
import React, { useState, useEffect, useContext, useRef } from "react";
|
||||||
import "emoji-mart/css/emoji-mart.css";
|
import "emoji-mart/css/emoji-mart.css";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import { Picker } from "emoji-mart";
|
import { Picker } from "emoji-mart";
|
||||||
@@ -170,17 +170,24 @@ const MessageInput = ({ ticketStatus }) => {
|
|||||||
const [showEmoji, setShowEmoji] = useState(false);
|
const [showEmoji, setShowEmoji] = useState(false);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [recording, setRecording] = useState(false);
|
const [recording, setRecording] = useState(false);
|
||||||
|
const inputRef = useRef();
|
||||||
const { setReplyingMessage, replyingMessage } = useContext(
|
const { setReplyingMessage, replyingMessage } = useContext(
|
||||||
ReplyMessageContext
|
ReplyMessageContext
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
inputRef.current.focus();
|
||||||
|
}, [replyingMessage]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
inputRef.current.focus();
|
||||||
return () => {
|
return () => {
|
||||||
setInputMessage("");
|
setInputMessage("");
|
||||||
setShowEmoji(false);
|
setShowEmoji(false);
|
||||||
setMedias([]);
|
setMedias([]);
|
||||||
|
setReplyingMessage(null);
|
||||||
};
|
};
|
||||||
}, [ticketId]);
|
}, [ticketId, setReplyingMessage]);
|
||||||
|
|
||||||
const handleChangeInput = e => {
|
const handleChangeInput = e => {
|
||||||
setInputMessage(e.target.value);
|
setInputMessage(e.target.value);
|
||||||
@@ -245,6 +252,7 @@ const MessageInput = ({ ticketStatus }) => {
|
|||||||
fromMe: true,
|
fromMe: true,
|
||||||
mediaUrl: "",
|
mediaUrl: "",
|
||||||
body: `${username}: ${inputMessage.trim()}`,
|
body: `${username}: ${inputMessage.trim()}`,
|
||||||
|
quotedMsg: replyingMessage,
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
await api.post(`/messages/${ticketId}`, message);
|
await api.post(`/messages/${ticketId}`, message);
|
||||||
@@ -264,6 +272,7 @@ const MessageInput = ({ ticketStatus }) => {
|
|||||||
setInputMessage("");
|
setInputMessage("");
|
||||||
setShowEmoji(false);
|
setShowEmoji(false);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
setReplyingMessage(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleStartRecording = async () => {
|
const handleStartRecording = async () => {
|
||||||
@@ -344,7 +353,7 @@ const MessageInput = ({ ticketStatus }) => {
|
|||||||
aria-label="showRecorder"
|
aria-label="showRecorder"
|
||||||
component="span"
|
component="span"
|
||||||
disabled={loading || ticketStatus !== "open"}
|
disabled={loading || ticketStatus !== "open"}
|
||||||
onClick={() => setReplyingMessage({})}
|
onClick={() => setReplyingMessage(null)}
|
||||||
>
|
>
|
||||||
<ClearIcon className={classes.sendMessageIcons} />
|
<ClearIcon className={classes.sendMessageIcons} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
@@ -386,7 +395,7 @@ const MessageInput = ({ ticketStatus }) => {
|
|||||||
else {
|
else {
|
||||||
return (
|
return (
|
||||||
<Paper square elevation={0} className={classes.mainWrapper}>
|
<Paper square elevation={0} className={classes.mainWrapper}>
|
||||||
{replyingMessage.id && renderReplyingMessage(replyingMessage)}
|
{replyingMessage && renderReplyingMessage(replyingMessage)}
|
||||||
<div className={classes.newMessageBox}>
|
<div className={classes.newMessageBox}>
|
||||||
<IconButton
|
<IconButton
|
||||||
aria-label="emojiPicker"
|
aria-label="emojiPicker"
|
||||||
@@ -426,7 +435,10 @@ const MessageInput = ({ ticketStatus }) => {
|
|||||||
</label>
|
</label>
|
||||||
<div className={classes.messageInputWrapper}>
|
<div className={classes.messageInputWrapper}>
|
||||||
<InputBase
|
<InputBase
|
||||||
inputRef={input => input && input.focus()}
|
inputRef={input => {
|
||||||
|
input && input.focus();
|
||||||
|
input && (inputRef.current = input);
|
||||||
|
}}
|
||||||
className={classes.messageInput}
|
className={classes.messageInput}
|
||||||
placeholder={
|
placeholder={
|
||||||
ticketStatus === "open"
|
ticketStatus === "open"
|
||||||
|
|||||||
@@ -65,9 +65,11 @@ const MessageOptionsMenu = ({ message, menuOpen, handleClose, anchorEl }) => {
|
|||||||
open={menuOpen}
|
open={menuOpen}
|
||||||
onClose={handleClose}
|
onClose={handleClose}
|
||||||
>
|
>
|
||||||
<MenuItem onClick={handleOpenConfirmationModal}>
|
{message.fromMe && (
|
||||||
{i18n.t("messageOptionsMenu.delete")}
|
<MenuItem onClick={handleOpenConfirmationModal}>
|
||||||
</MenuItem>
|
{i18n.t("messageOptionsMenu.delete")}
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
<MenuItem onClick={hanldeReplyMessage}>
|
<MenuItem onClick={hanldeReplyMessage}>
|
||||||
{i18n.t("messageOptionsMenu.reply")}
|
{i18n.t("messageOptionsMenu.reply")}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ const useStyles = makeStyles(theme => ({
|
|||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
},
|
},
|
||||||
|
|
||||||
quotedSideLeft: {
|
quotedSideColorLeft: {
|
||||||
flex: "none",
|
flex: "none",
|
||||||
width: "4px",
|
width: "4px",
|
||||||
backgroundColor: "#6bcbef",
|
backgroundColor: "#6bcbef",
|
||||||
@@ -158,7 +158,7 @@ const useStyles = makeStyles(theme => ({
|
|||||||
whiteSpace: "pre-wrap",
|
whiteSpace: "pre-wrap",
|
||||||
},
|
},
|
||||||
|
|
||||||
quotedSideRight: {
|
quotedSideColorRight: {
|
||||||
flex: "none",
|
flex: "none",
|
||||||
width: "4px",
|
width: "4px",
|
||||||
backgroundColor: "#35cd96",
|
backgroundColor: "#35cd96",
|
||||||
@@ -170,6 +170,7 @@ const useStyles = makeStyles(theme => ({
|
|||||||
color: "#999",
|
color: "#999",
|
||||||
zIndex: 1,
|
zIndex: 1,
|
||||||
backgroundColor: "inherit",
|
backgroundColor: "inherit",
|
||||||
|
opacity: "90%",
|
||||||
"&:hover, &.Mui-focusVisible": { backgroundColor: "inherit" },
|
"&:hover, &.Mui-focusVisible": { backgroundColor: "inherit" },
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -534,14 +535,14 @@ const MessagesList = ({ ticketId, isGroup, setReplyingMessage }) => {
|
|||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className={clsx(classes.quotedSideLeft, {
|
className={clsx(classes.quotedSideColorLeft, {
|
||||||
[classes.quotedSideRight]: message.quotedMsg?.fromMe,
|
[classes.quotedSideColorRight]: message.quotedMsg?.fromMe,
|
||||||
})}
|
})}
|
||||||
></span>
|
></span>
|
||||||
<div className={classes.quotedMsg}>
|
<div className={classes.quotedMsg}>
|
||||||
{!message.quotedMsg?.fromMe && (
|
{!message.quotedMsg?.fromMe && (
|
||||||
<span className={classes.messageContactName}>
|
<span className={classes.messageContactName}>
|
||||||
{message.contact?.name}
|
{message.quotedMsg?.contact?.name}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{message.quotedMsg?.body}
|
{message.quotedMsg?.body}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import React, { useState, createContext } from "react";
|
|||||||
const ReplyMessageContext = createContext();
|
const ReplyMessageContext = createContext();
|
||||||
|
|
||||||
const ReplyMessageProvider = ({ children }) => {
|
const ReplyMessageProvider = ({ children }) => {
|
||||||
const [replyingMessage, setReplyingMessage] = useState({});
|
const [replyingMessage, setReplyingMessage] = useState(null);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ReplyMessageContext.Provider
|
<ReplyMessageContext.Provider
|
||||||
|
|||||||
@@ -335,8 +335,7 @@ const messages = {
|
|||||||
ERR_INVALID_CREDENTIALS: "Authentication error. Please try again.",
|
ERR_INVALID_CREDENTIALS: "Authentication error. Please try again.",
|
||||||
ERR_SENDING_WAPP_MSG:
|
ERR_SENDING_WAPP_MSG:
|
||||||
"Error sending WhatsApp message. Check connections page.",
|
"Error sending WhatsApp message. Check connections page.",
|
||||||
ERR_DELETE_WAPP_MSG:
|
ERR_DELETE_WAPP_MSG: "Couldn't delete message from WhatsApp.",
|
||||||
"Couldn't delete message from WhatsApp. Check connections page.",
|
|
||||||
ERR_OTHER_OPEN_TICKET:
|
ERR_OTHER_OPEN_TICKET:
|
||||||
"There's already an open ticket for this contact.",
|
"There's already an open ticket for this contact.",
|
||||||
ERR_SESSION_EXPIRED: "Session expired. Please login.",
|
ERR_SESSION_EXPIRED: "Session expired. Please login.",
|
||||||
@@ -351,6 +350,8 @@ const messages = {
|
|||||||
ERR_NO_WAPP_FOUND: "No WhatsApp found with this ID.",
|
ERR_NO_WAPP_FOUND: "No WhatsApp found with this ID.",
|
||||||
ERR_CREATING_MESSAGE: "Error while creating message on database.",
|
ERR_CREATING_MESSAGE: "Error while creating message on database.",
|
||||||
ERR_CREATING_TICKET: "Error while creating ticket on database.",
|
ERR_CREATING_TICKET: "Error while creating ticket on database.",
|
||||||
|
ERR_FETCH_WAPP_MSG:
|
||||||
|
"Error fetching the message in WhtasApp, maybe it is too old.",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -341,8 +341,7 @@ const messages = {
|
|||||||
ERR_INVALID_CREDENTIALS: "Error de autenticación. Vuelva a intentarlo.",
|
ERR_INVALID_CREDENTIALS: "Error de autenticación. Vuelva a intentarlo.",
|
||||||
ERR_SENDING_WAPP_MSG:
|
ERR_SENDING_WAPP_MSG:
|
||||||
"Error al enviar el mensaje de WhatsApp. Verifique la página de conexiones.",
|
"Error al enviar el mensaje de WhatsApp. Verifique la página de conexiones.",
|
||||||
ERR_DELETE_WAPP_MSG:
|
ERR_DELETE_WAPP_MSG: "No se pudo borrar el mensaje de WhatsApp.",
|
||||||
"No se pudo borrar el mensaje de WhatsApp. Verifique la página de conexiones.",
|
|
||||||
ERR_OTHER_OPEN_TICKET: "Ya hay un ticket abierto para este contacto.",
|
ERR_OTHER_OPEN_TICKET: "Ya hay un ticket abierto para este contacto.",
|
||||||
ERR_SESSION_EXPIRED: "Sesión caducada. Inicie sesión.",
|
ERR_SESSION_EXPIRED: "Sesión caducada. Inicie sesión.",
|
||||||
ERR_USER_CREATION_DISABLED:
|
ERR_USER_CREATION_DISABLED:
|
||||||
@@ -357,6 +356,8 @@ const messages = {
|
|||||||
ERR_NO_WAPP_FOUND: "No se encontró WhatsApp con este ID.",
|
ERR_NO_WAPP_FOUND: "No se encontró WhatsApp con este ID.",
|
||||||
ERR_CREATING_MESSAGE: "Error al crear el mensaje en la base de datos.",
|
ERR_CREATING_MESSAGE: "Error al crear el mensaje en la base de datos.",
|
||||||
ERR_CREATING_TICKET: "Error al crear el ticket en la base de datos.",
|
ERR_CREATING_TICKET: "Error al crear el ticket en la base de datos.",
|
||||||
|
ERR_FETCH_WAPP_MSG:
|
||||||
|
"Error al obtener el mensaje en WhtasApp, tal vez sea demasiado antiguo.",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -340,8 +340,7 @@ const messages = {
|
|||||||
"Erro de autenticação. Por favor, tente novamente.",
|
"Erro de autenticação. Por favor, tente novamente.",
|
||||||
ERR_SENDING_WAPP_MSG:
|
ERR_SENDING_WAPP_MSG:
|
||||||
"Erro ao enviar mensagem do WhatsApp. Verifique a página de conexões.",
|
"Erro ao enviar mensagem do WhatsApp. Verifique a página de conexões.",
|
||||||
ERR_DELETE_WAPP_MSG:
|
ERR_DELETE_WAPP_MSG: "Não foi possível excluir a mensagem do WhatsApp.",
|
||||||
"Não foi possível excluir a mensagem do WhatsApp. Verifique a página de conexões.",
|
|
||||||
ERR_OTHER_OPEN_TICKET: "Já existe um tíquete aberto para este contato.",
|
ERR_OTHER_OPEN_TICKET: "Já existe um tíquete aberto para este contato.",
|
||||||
ERR_SESSION_EXPIRED: "Sessão expirada. Por favor entre.",
|
ERR_SESSION_EXPIRED: "Sessão expirada. Por favor entre.",
|
||||||
ERR_USER_CREATION_DISABLED:
|
ERR_USER_CREATION_DISABLED:
|
||||||
@@ -355,6 +354,8 @@ const messages = {
|
|||||||
ERR_NO_WAPP_FOUND: "Nenhum WhatsApp encontrado com este ID.",
|
ERR_NO_WAPP_FOUND: "Nenhum WhatsApp encontrado com este ID.",
|
||||||
ERR_CREATING_MESSAGE: "Erro ao criar mensagem no banco de dados.",
|
ERR_CREATING_MESSAGE: "Erro ao criar mensagem no banco de dados.",
|
||||||
ERR_CREATING_TICKET: "Erro ao criar tíquete no banco de dados.",
|
ERR_CREATING_TICKET: "Erro ao criar tíquete no banco de dados.",
|
||||||
|
ERR_FETCH_WAPP_MSG:
|
||||||
|
"Erro ao buscar a mensagem no WhtasApp, talvez ela seja muito antiga.",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user