whatsapp oficial em desenvolvimento
parent
bfad9fc0b2
commit
42535f2e6c
|
@ -1,4 +1,5 @@
|
||||||
import { Request, Response } from "express";
|
import { Request, Response } from "express";
|
||||||
|
import whatsappOfficialAPI from "../helpers/WhatsappOfficialAPI";
|
||||||
|
|
||||||
import SetTicketMessagesAsRead from "../helpers/SetTicketMessagesAsRead";
|
import SetTicketMessagesAsRead from "../helpers/SetTicketMessagesAsRead";
|
||||||
import { getIO } from "../libs/socket";
|
import { getIO } from "../libs/socket";
|
||||||
|
@ -9,6 +10,13 @@ import ShowTicketService from "../services/TicketServices/ShowTicketService";
|
||||||
import DeleteWhatsAppMessage from "../services/WbotServices/DeleteWhatsAppMessage";
|
import DeleteWhatsAppMessage from "../services/WbotServices/DeleteWhatsAppMessage";
|
||||||
import SendWhatsAppMedia from "../services/WbotServices/SendWhatsAppMedia";
|
import SendWhatsAppMedia from "../services/WbotServices/SendWhatsAppMedia";
|
||||||
import SendWhatsAppMessage from "../services/WbotServices/SendWhatsAppMessage";
|
import SendWhatsAppMessage from "../services/WbotServices/SendWhatsAppMessage";
|
||||||
|
import axios from "axios";
|
||||||
|
import Contact from "../models/Contact";
|
||||||
|
import {
|
||||||
|
isValidMsg,
|
||||||
|
verifyMessage
|
||||||
|
} from "../services/WbotServices/wbotMessageListener";
|
||||||
|
import CreateOrUpdateContactService from "../services/ContactServices/CreateOrUpdateContactService";
|
||||||
|
|
||||||
type IndexQuery = {
|
type IndexQuery = {
|
||||||
pageNumber: string;
|
pageNumber: string;
|
||||||
|
@ -36,22 +44,102 @@ 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, quotedMsg }: 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);
|
||||||
|
|
||||||
console.log('TICKET ID: ', ticketId)
|
const { queueId } = ticket;
|
||||||
|
console.log("-----------> queueId: ", queueId);
|
||||||
|
|
||||||
// SetTicketMessagesAsRead(ticket);
|
// TEST FILA DE ATENDIMENTO 42 WHATSAPP OFFICIAL
|
||||||
|
if (queueId == 42) {
|
||||||
|
const { contactId } = ticket;
|
||||||
|
|
||||||
|
const contact: any = await Contact.findByPk(contactId);
|
||||||
|
|
||||||
|
const { number } = contact;
|
||||||
|
|
||||||
|
console.log("NUMBER: ", number);
|
||||||
|
console.log("CONTACT ID: ", contactId);
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
messaging_product: "whatsapp",
|
||||||
|
recipient_type: "individual",
|
||||||
|
to: number,
|
||||||
|
type: "text",
|
||||||
|
text: {
|
||||||
|
preview_url: true,
|
||||||
|
body
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!isValidMsg({ type: data.type })) {
|
||||||
|
return res.status(400).json({ message: "Wrong message type" });
|
||||||
|
}
|
||||||
|
|
||||||
|
whatsappOfficialAPI
|
||||||
|
.post("/v17.0/105394365522185/messagess", data)
|
||||||
|
.then(response => {
|
||||||
|
console.log("Response:", response.data);
|
||||||
|
|
||||||
|
if (response.status == 200) {
|
||||||
|
console.log("STATUS 200");
|
||||||
|
}
|
||||||
|
|
||||||
|
let msg = {};
|
||||||
|
|
||||||
|
msg = {
|
||||||
|
...msg,
|
||||||
|
id: { id: response.data.messages[0].id },
|
||||||
|
fromMe: true,
|
||||||
|
type: "chat",
|
||||||
|
read: false,
|
||||||
|
body
|
||||||
|
};
|
||||||
|
|
||||||
|
verifyMessage(msg, ticket, contact, quotedMsg);
|
||||||
|
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.log(
|
||||||
|
"Error on try request: ",
|
||||||
|
error.response.data.error.message
|
||||||
|
);
|
||||||
|
|
||||||
|
// return res
|
||||||
|
// .status(500)
|
||||||
|
// .json({ error: error.response.data.error.message });
|
||||||
|
|
||||||
|
if (error?.response?.data?.error?.message && error.response?.status) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error.response) {
|
||||||
|
// The request was made and the server responded with a non-2xx status code
|
||||||
|
throw new Error(
|
||||||
|
`Request failed with status ${error.response.status}`
|
||||||
|
);
|
||||||
|
} else if (error.request) {
|
||||||
|
// The request was made but no response was received (e.g., network error)
|
||||||
|
throw new Error("No response received from the server");
|
||||||
|
} else {
|
||||||
|
// Something happened in setting up the request that triggered an error
|
||||||
|
throw new Error("Request configuration error");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// return res.status(500).json({ error: "Internal server error" });
|
||||||
|
|
||||||
|
return res.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ORIGINAL
|
||||||
if (medias) {
|
if (medias) {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
medias.map(async (media: Express.Multer.File) => {
|
medias.map(async (media: Express.Multer.File) => {
|
||||||
|
console.log(
|
||||||
console.log(`\n >>>>>>>>>> SENDING MESSAGE MEDIA
|
`\n >>>>>>>>>> SENDING MESSAGE MEDIA
|
||||||
Parcial ticket info and media:
|
Parcial ticket info and media:
|
||||||
ticket.id: ${ticket.id}
|
ticket.id: ${ticket.id}
|
||||||
ticket.status: ${ticket.status}
|
ticket.status: ${ticket.status}
|
||||||
|
@ -61,13 +149,15 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
ticket.contact.profilePicUrl: ${ticket.contact.profilePicUrl}
|
ticket.contact.profilePicUrl: ${ticket.contact.profilePicUrl}
|
||||||
ticket.user.id: ${ticket.user.id}
|
ticket.user.id: ${ticket.user.id}
|
||||||
ticket.user.name: ${ticket.user.name}
|
ticket.user.name: ${ticket.user.name}
|
||||||
media:`, media,'\n')
|
media:`,
|
||||||
|
media,
|
||||||
|
"\n"
|
||||||
|
);
|
||||||
|
|
||||||
await SendWhatsAppMedia({ media, ticket });
|
await SendWhatsAppMedia({ media, ticket });
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
console.log(`\n >>>>>>>>>> SENDING MESSAGE
|
console.log(`\n >>>>>>>>>> SENDING MESSAGE
|
||||||
Parcial ticket info:
|
Parcial ticket info:
|
||||||
ticket.id: ${ticket.id}
|
ticket.id: ${ticket.id}
|
||||||
|
@ -78,8 +168,7 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
ticket.contact.name: ${ticket.contact.name}
|
ticket.contact.name: ${ticket.contact.name}
|
||||||
ticket.contact.profilePicUrl: ${ticket.contact.profilePicUrl}
|
ticket.contact.profilePicUrl: ${ticket.contact.profilePicUrl}
|
||||||
ticket.user.id: ${ticket.user.id}
|
ticket.user.id: ${ticket.user.id}
|
||||||
ticket.user.name: ${ticket.user.name}\n`)
|
ticket.user.name: ${ticket.user.name}\n`);
|
||||||
|
|
||||||
|
|
||||||
await SendWhatsAppMessage({ body, ticket, quotedMsg });
|
await SendWhatsAppMessage({ body, ticket, quotedMsg });
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,8 +105,6 @@ 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 { contactId, status, userId, msg, queueId }: TicketData = req.body;
|
const { contactId, status, userId, msg, queueId }: TicketData = req.body;
|
||||||
|
|
||||||
// const botInfo = await BotIsOnQueue("botqueue");
|
|
||||||
|
|
||||||
let ticket = await Ticket.findOne({
|
let ticket = await Ticket.findOne({
|
||||||
where: {
|
where: {
|
||||||
[Op.or]: [
|
[Op.or]: [
|
||||||
|
|
|
@ -14,13 +14,21 @@ import UpdateWhatsAppService from "../services/WhatsappService/UpdateWhatsAppSer
|
||||||
import AppError from "../errors/AppError";
|
import AppError from "../errors/AppError";
|
||||||
|
|
||||||
import getNumberFromName from "../helpers/GetNumberSequence";
|
import getNumberFromName from "../helpers/GetNumberSequence";
|
||||||
import phoneNumberStart from "../helpers/PhoneNumberStatusCode"
|
import phoneNumberStart from "../helpers/PhoneNumberStatusCode";
|
||||||
|
|
||||||
import path from 'path';
|
import path from "path";
|
||||||
import validatePhoneName from "../helpers/ValidatePhoneName";
|
import validatePhoneName from "../helpers/ValidatePhoneName";
|
||||||
import postData from "../helpers/AxiosPost";
|
import postData from "../helpers/AxiosPost";
|
||||||
import Whatsapp from "../models/Whatsapp";
|
import Whatsapp from "../models/Whatsapp";
|
||||||
|
import Message from "../models/Message";
|
||||||
|
import FindOrCreateTicketService from "../services/TicketServices/FindOrCreateTicketService";
|
||||||
|
import {
|
||||||
|
handleMsgAck,
|
||||||
|
verifyContact,
|
||||||
|
verifyMessage
|
||||||
|
} from "../services/WbotServices/wbotMessageListener";
|
||||||
|
import Contact from "../models/Contact";
|
||||||
|
import CreateOrUpdateContactService from "../services/ContactServices/CreateOrUpdateContactService";
|
||||||
|
|
||||||
interface WhatsappData {
|
interface WhatsappData {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -39,6 +47,72 @@ export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||||
return res.status(200).json(whatsapps);
|
return res.status(200).json(whatsapps);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const weebhook = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response> => {
|
||||||
|
// console.log(JSON.stringify(req.body, null, 2));
|
||||||
|
|
||||||
|
// MESSAGE
|
||||||
|
if (req.body.object) {
|
||||||
|
if (
|
||||||
|
req.body.entry &&
|
||||||
|
req.body.entry[0].changes &&
|
||||||
|
req.body.entry[0].changes[0] &&
|
||||||
|
req.body.entry[0].changes[0].value.messages &&
|
||||||
|
req.body.entry[0].changes[0].value.messages[0]
|
||||||
|
) {
|
||||||
|
const contact_from = req.body.entry[0].changes[0].value.messages[0].from; // extract the phone number from the webhook payload
|
||||||
|
const msg_body = req.body.entry[0].changes[0].value.messages[0].text.body; // extract the message text from the webhook payload
|
||||||
|
const type = req.body.entry[0].changes[0].value.messages[0].type;
|
||||||
|
const contact_to =
|
||||||
|
req.body.entry[0].changes[0].value.metadata.display_phone_number;
|
||||||
|
|
||||||
|
console.log("from: ", contact_from);
|
||||||
|
console.log("to: ", contact_to);
|
||||||
|
console.log("msg_body: ", msg_body);
|
||||||
|
console.log("msg type: ", type);
|
||||||
|
|
||||||
|
const contact: any = await verifyContact(null, { number: contact_from });
|
||||||
|
|
||||||
|
const whatsapp: any = await Whatsapp.findOne({
|
||||||
|
where: { number: contact_to }
|
||||||
|
});
|
||||||
|
|
||||||
|
const ticket = await FindOrCreateTicketService(contact, whatsapp.id, 1);
|
||||||
|
|
||||||
|
let msg = {};
|
||||||
|
|
||||||
|
msg = {
|
||||||
|
...msg,
|
||||||
|
id: { id: req.body.entry[0].changes[0].value.messages[0].id },
|
||||||
|
fromMe: false,
|
||||||
|
type: type === "text" ? "chat" : type,
|
||||||
|
read: false,
|
||||||
|
body: req.body.entry[0].changes[0].value.messages[0].text.body
|
||||||
|
};
|
||||||
|
|
||||||
|
await verifyMessage(msg, ticket, contact, undefined);
|
||||||
|
|
||||||
|
return res.sendStatus(200);
|
||||||
|
}
|
||||||
|
// STATUS MESSAGE SENT
|
||||||
|
else if (
|
||||||
|
req.body.entry &&
|
||||||
|
req.body.entry[0].changes &&
|
||||||
|
req.body.entry[0].changes[0] &&
|
||||||
|
req.body.entry[0].changes[0].value.statuses &&
|
||||||
|
req.body.entry[0].changes[0].value.statuses[0]
|
||||||
|
) {
|
||||||
|
const id = req.body.entry[0].changes[0].value.statuses[0].id;
|
||||||
|
const ack = req.body.entry[0].changes[0].value.statuses[0].status;
|
||||||
|
handleMsgAck(id, ack, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.sendStatus(200);
|
||||||
|
};
|
||||||
|
|
||||||
export const store = async (req: Request, res: Response): Promise<Response> => {
|
export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
|
@ -51,25 +125,11 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
urlApi
|
urlApi
|
||||||
}: WhatsappData = req.body;
|
}: WhatsappData = req.body;
|
||||||
|
|
||||||
// console.log( name,
|
|
||||||
// status,
|
|
||||||
// isDefault,
|
|
||||||
// greetingMessage,
|
|
||||||
// farewellMessage,
|
|
||||||
// queueIds,
|
|
||||||
// url,
|
|
||||||
// urlApi)
|
|
||||||
|
|
||||||
// console.log('getNumberFromName: ', getNumberFromName(name))
|
|
||||||
|
|
||||||
// return res.status(200);
|
|
||||||
|
|
||||||
|
|
||||||
if (req.user.profile !== "master") {
|
if (req.user.profile !== "master") {
|
||||||
throw new AppError("ERR_NO_PERMISSION", 403);
|
throw new AppError("ERR_NO_PERMISSION", 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
let validate = validatePhoneName(name)
|
let validate = validatePhoneName(name);
|
||||||
|
|
||||||
if (validate) {
|
if (validate) {
|
||||||
return res.status(200).json({ message: validate });
|
return res.status(200).json({ message: validate });
|
||||||
|
@ -86,14 +146,14 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
queueIds
|
queueIds
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('whatsapp.id: ', whatsapp.id)
|
console.log("whatsapp.id: ", whatsapp.id);
|
||||||
|
|
||||||
postData( `${whatsapp.urlApi}/api/session`, {
|
postData(`${whatsapp.urlApi}/api/session`, {
|
||||||
"app_name": process.env.APP_NAME,
|
app_name: process.env.APP_NAME,
|
||||||
"whatsappId": whatsapp.id,
|
whatsappId: whatsapp.id,
|
||||||
"number": getNumberFromName(name),
|
number: getNumberFromName(name),
|
||||||
"client_url": `${process.env.BACKEND_URL_RAW}:${process.env.PORT}`
|
client_url: `${process.env.BACKEND_URL_RAW}:${process.env.PORT}`
|
||||||
})
|
});
|
||||||
|
|
||||||
// StartWhatsAppSession(whatsapp);
|
// StartWhatsAppSession(whatsapp);
|
||||||
|
|
||||||
|
@ -128,10 +188,9 @@ export const update = async (
|
||||||
const { whatsappId } = req.params;
|
const { whatsappId } = req.params;
|
||||||
const whatsappData = req.body;
|
const whatsappData = req.body;
|
||||||
|
|
||||||
|
let validate = validatePhoneName(whatsappData.name);
|
||||||
|
|
||||||
let validate = validatePhoneName(whatsappData.name)
|
console.log("validate", validate);
|
||||||
|
|
||||||
console.log('validate', validate)
|
|
||||||
|
|
||||||
if (validate) {
|
if (validate) {
|
||||||
return res.status(200).json({ message: validate });
|
return res.status(200).json({ message: validate });
|
||||||
|
@ -142,13 +201,12 @@ export const update = async (
|
||||||
whatsappId
|
whatsappId
|
||||||
});
|
});
|
||||||
|
|
||||||
|
postData(`${whatsapp.urlApi}/api/session`, {
|
||||||
postData( `${whatsapp.urlApi}/api/session`, {
|
app_name: process.env.APP_NAME,
|
||||||
"app_name": process.env.APP_NAME,
|
whatsappId: whatsapp.id,
|
||||||
"whatsappId": whatsapp.id,
|
number: getNumberFromName(whatsapp.name),
|
||||||
"number": getNumberFromName(whatsapp.name),
|
client_url: `${process.env.BACKEND_URL_RAW}:${process.env.PORT}`
|
||||||
"client_url": `${process.env.BACKEND_URL_RAW}:${process.env.PORT}`
|
});
|
||||||
})
|
|
||||||
|
|
||||||
const io = getIO();
|
const io = getIO();
|
||||||
io.emit("whatsapp", {
|
io.emit("whatsapp", {
|
||||||
|
@ -170,26 +228,33 @@ export const remove = async (
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response
|
res: Response
|
||||||
): Promise<Response> => {
|
): Promise<Response> => {
|
||||||
|
|
||||||
if (req.user.profile !== "master") {
|
if (req.user.profile !== "master") {
|
||||||
throw new AppError("ERR_NO_PERMISSION", 403);
|
throw new AppError("ERR_NO_PERMISSION", 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { whatsappId } = req.params;
|
const { whatsappId } = req.params;
|
||||||
|
|
||||||
const whatsapp: any = await Whatsapp.findByPk(whatsappId, { raw: true })
|
const whatsapp: any = await Whatsapp.findByPk(whatsappId, { raw: true });
|
||||||
|
|
||||||
postData( `${whatsapp.urlApi}/api/session/del`, {
|
postData(`${whatsapp.urlApi}/api/session/del`, {
|
||||||
"app_name": process.env.APP_NAME,
|
app_name: process.env.APP_NAME,
|
||||||
"whatsappId": whatsappId
|
whatsappId: whatsappId
|
||||||
})
|
});
|
||||||
|
|
||||||
await DeleteWhatsAppService(whatsappId);
|
await DeleteWhatsAppService(whatsappId);
|
||||||
|
|
||||||
removeDir(path.join(process.cwd(), '.wwebjs_auth', `session-bd_${whatsappId}`))
|
removeDir(
|
||||||
|
path.join(process.cwd(), ".wwebjs_auth", `session-bd_${whatsappId}`)
|
||||||
removeDir(path.join(process.cwd(), '.wwebjs_auth', 'sessions', `session-bd_${whatsappId}`))
|
);
|
||||||
|
|
||||||
|
removeDir(
|
||||||
|
path.join(
|
||||||
|
process.cwd(),
|
||||||
|
".wwebjs_auth",
|
||||||
|
"sessions",
|
||||||
|
`session-bd_${whatsappId}`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
removeWbot(+whatsappId);
|
removeWbot(+whatsappId);
|
||||||
|
|
||||||
|
@ -201,3 +266,5 @@ export const remove = async (
|
||||||
|
|
||||||
return res.status(200).json({ message: "Whatsapp deleted." });
|
return res.status(200).json({ message: "Whatsapp deleted." });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { QueryInterface, DataTypes } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.addColumn("Whatsapps", "official", {
|
||||||
|
type: DataTypes.BOOLEAN,
|
||||||
|
defaultValue: false
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.removeColumn("Whatsapps", "official");
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { QueryInterface } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.bulkInsert(
|
||||||
|
"Settings",
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: "whatsaAppCloudApi",
|
||||||
|
value: "disabled",
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date()
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.bulkDelete("Settings", {});
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,14 @@
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
const token =
|
||||||
|
"EAADwEiQkJqABOZBOuvnVZAywgKUw8wPETCcleXWDqKN3X2W1LZC5UMEnSjBIVjBavZBxwVTD4WnpDmoEFN9HZCOt842XZCTSPm1ShnnUB2iJca3nZC6gS8GLIKqP78kkW5EtllhWrg4I8JnbllrLNKa2B066Wwh0G3uySYgcA7WnKyZAmPOGEZB8UiljBaqhg";
|
||||||
|
|
||||||
|
const api = axios.create({
|
||||||
|
baseURL: "https://graph.facebook.com",
|
||||||
|
headers: {
|
||||||
|
Accept: "application/json",
|
||||||
|
Authorization: `Bearer ${token}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default api;
|
|
@ -5,12 +5,12 @@ import * as WhatsAppController from "../controllers/WhatsAppController";
|
||||||
|
|
||||||
const whatsappRoutes = express.Router();
|
const whatsappRoutes = express.Router();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
whatsappRoutes.get("/whatsapp/", isAuth, WhatsAppController.index);
|
whatsappRoutes.get("/whatsapp/", isAuth, WhatsAppController.index);
|
||||||
|
|
||||||
whatsappRoutes.post("/whatsapp/", isAuth, WhatsAppController.store);
|
whatsappRoutes.post("/whatsapp/", isAuth, WhatsAppController.store);
|
||||||
|
|
||||||
|
whatsappRoutes.post("/whatsapp/webhook", WhatsAppController.weebhook);
|
||||||
|
|
||||||
whatsappRoutes.get("/whatsapp/:whatsappId", isAuth, WhatsAppController.show);
|
whatsappRoutes.get("/whatsapp/:whatsappId", isAuth, WhatsAppController.show);
|
||||||
|
|
||||||
whatsappRoutes.put("/whatsapp/:whatsappId", isAuth, WhatsAppController.update);
|
whatsappRoutes.put("/whatsapp/:whatsappId", isAuth, WhatsAppController.update);
|
||||||
|
|
|
@ -18,73 +18,58 @@ interface Request {
|
||||||
messageData: MessageData;
|
messageData: MessageData;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CreateMessageService = async ({ messageData }: Request): Promise<Message> => {
|
const CreateMessageService = async ({
|
||||||
|
messageData
|
||||||
// console.log('UPSERT MESSAGE messageData: ', messageData)
|
}: Request): Promise<Message> => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
await Message.upsert(messageData);
|
await Message.upsert(messageData);
|
||||||
|
|
||||||
const message = await Message.findByPk(messageData.id, {
|
const message = await Message.findByPk(messageData.id, {
|
||||||
include: [
|
include: [
|
||||||
"contact",
|
"contact",
|
||||||
{
|
{
|
||||||
model: Ticket,
|
model: Ticket,
|
||||||
as: "ticket",
|
as: "ticket",
|
||||||
include: ["contact", "queue"]
|
include: ["contact", "queue"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
model: Message,
|
model: Message,
|
||||||
as: "quotedMsg",
|
as: "quotedMsg",
|
||||||
include: ["contact"]
|
include: ["contact"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!message) {
|
if (!message) {
|
||||||
throw new Error("ERR_CREATING_MESSAGE");
|
throw new Error("ERR_CREATING_MESSAGE");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (message.ticket.status != "queueChoice") {
|
||||||
if (message.ticket.status != 'queueChoice') {
|
await updateTicketCacheByTicketId(message.ticket.id, {
|
||||||
|
|
||||||
|
|
||||||
// TEST DEL
|
|
||||||
await updateTicketCacheByTicketId(message.ticket.id,
|
|
||||||
{
|
|
||||||
lastMessage: message.body,
|
lastMessage: message.body,
|
||||||
updatedAt: new Date(message.ticket.updatedAt).toISOString(),
|
updatedAt: new Date(message.ticket.updatedAt).toISOString(),
|
||||||
'contact.profilePicUrl': message.ticket.contact.profilePicUrl,
|
"contact.profilePicUrl": message.ticket.contact.profilePicUrl,
|
||||||
unreadMessages: message.ticket.unreadMessages
|
unreadMessages: message.ticket.unreadMessages
|
||||||
})
|
|
||||||
//
|
|
||||||
|
|
||||||
console.log('message.ticketId.toString(): ', message.ticketId.toString())
|
|
||||||
console.log('message.ticket.status: ',message.ticket.status)
|
|
||||||
|
|
||||||
const io = getIO();
|
|
||||||
io.to(message.ticketId.toString())
|
|
||||||
.to(message.ticket.status)
|
|
||||||
.to("notification")
|
|
||||||
.emit("appMessage", {
|
|
||||||
action: "create",
|
|
||||||
message,
|
|
||||||
ticket: message.ticket,
|
|
||||||
contact: message.ticket.contact
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
const io = getIO();
|
||||||
|
io.to(message.ticketId.toString())
|
||||||
|
.to(message.ticket.status)
|
||||||
return message;
|
.to("notification")
|
||||||
|
.emit("appMessage", {
|
||||||
|
action: "create",
|
||||||
|
message,
|
||||||
|
ticket: message.ticket,
|
||||||
|
contact: message.ticket.contact
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return message;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('===> Error on CreateMessageService.ts file: \n', error)
|
console.error("===> Error on CreateMessageService.ts file: \n", error);
|
||||||
throw new AppError(error.message);
|
throw new AppError(error.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default CreateMessageService;
|
export default CreateMessageService;
|
||||||
|
|
|
@ -18,6 +18,10 @@ const FindOrCreateTicketService = async (
|
||||||
try {
|
try {
|
||||||
let ticket;
|
let ticket;
|
||||||
|
|
||||||
|
// else if (getSettingValue("whatsaAppCloudApi")?.value == "enabled") {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
if (getSettingValue("oneContactChatWithManyWhats")?.value == "enabled") {
|
if (getSettingValue("oneContactChatWithManyWhats")?.value == "enabled") {
|
||||||
let whats = await ListWhatsAppsNumber(whatsappId);
|
let whats = await ListWhatsAppsNumber(whatsappId);
|
||||||
|
|
||||||
|
@ -43,8 +47,6 @@ const FindOrCreateTicketService = async (
|
||||||
|
|
||||||
const { queues, greetingMessage } = await ShowWhatsAppService(whatsappId);
|
const { queues, greetingMessage } = await ShowWhatsAppService(whatsappId);
|
||||||
|
|
||||||
//Habilitar esse caso queira usar o bot
|
|
||||||
// const botInfo = await BotIsOnQueue('botqueue')
|
|
||||||
const botInfo = { isOnQueue: false };
|
const botInfo = { isOnQueue: false };
|
||||||
|
|
||||||
if (ticket) {
|
if (ticket) {
|
||||||
|
@ -72,8 +74,6 @@ const FindOrCreateTicketService = async (
|
||||||
ticket = await Ticket.findOne({
|
ticket = await Ticket.findOne({
|
||||||
where: {
|
where: {
|
||||||
updatedAt: {
|
updatedAt: {
|
||||||
//[Op.between]: [+subHours(new Date(), 2), +new Date()]
|
|
||||||
|
|
||||||
// Tempo osioso para a ura responder thuanny
|
// Tempo osioso para a ura responder thuanny
|
||||||
//[Op.between]: [+subMinutes(new Date(), 30), +new Date()]
|
//[Op.between]: [+subMinutes(new Date(), 30), +new Date()]
|
||||||
|
|
||||||
|
@ -108,13 +108,6 @@ const FindOrCreateTicketService = async (
|
||||||
unreadMessages,
|
unreadMessages,
|
||||||
whatsappId
|
whatsappId
|
||||||
});
|
});
|
||||||
|
|
||||||
// TEST DEL
|
|
||||||
|
|
||||||
// const { name } = await ShowContactService(contact.id);
|
|
||||||
// console.log('FIND OR CREATE TICKET SERVICE NAME: ', contact.name, ' STATUS: ', status)
|
|
||||||
|
|
||||||
//
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ticket = await ShowTicketService(ticket.id);
|
ticket = await ShowTicketService(ticket.id);
|
||||||
|
|
|
@ -96,16 +96,25 @@ interface Session extends Client {
|
||||||
|
|
||||||
const writeFileAsync = promisify(writeFile);
|
const writeFileAsync = promisify(writeFile);
|
||||||
|
|
||||||
const verifyContact = async (msgContact: any): Promise<Contact> => {
|
const verifyContact = async (
|
||||||
// const profilePicUrl = await msgContact.getProfilePicUrl();
|
msgContact: any,
|
||||||
const profilePicUrl = msgContact.getProfilePicUrl;
|
whatsAppOfficial?: any
|
||||||
|
): Promise<Contact> => {
|
||||||
const contactData = {
|
let contactData: any = {};
|
||||||
name: msgContact.name || msgContact.pushname || msgContact.id.user,
|
if (msgContact) {
|
||||||
number: msgContact.id.user,
|
contactData = {
|
||||||
profilePicUrl,
|
name: msgContact.name || msgContact.pushname || msgContact.id.user,
|
||||||
isGroup: msgContact.isGroup
|
number: msgContact.id.user,
|
||||||
};
|
profilePicUrl: msgContact.getProfilePicUrl,
|
||||||
|
isGroup: msgContact.isGroup
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
contactData = {
|
||||||
|
name: whatsAppOfficial.number,
|
||||||
|
number: whatsAppOfficial.number,
|
||||||
|
isGroup: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const contact = CreateOrUpdateContactService(contactData);
|
const contact = CreateOrUpdateContactService(contactData);
|
||||||
|
|
||||||
|
@ -138,37 +147,16 @@ const verifyMediaMessage = async (
|
||||||
media: any,
|
media: any,
|
||||||
quotedMsg?: any
|
quotedMsg?: any
|
||||||
): Promise<Message | any> => {
|
): Promise<Message | any> => {
|
||||||
// const quotedMsg = await verifyQuotedMessage(msg);
|
|
||||||
|
|
||||||
// const media = await msg.downloadMedia();
|
|
||||||
|
|
||||||
if (!media) {
|
if (!media) {
|
||||||
throw new Error("ERR_WAPP_DOWNLOAD_MEDIA");
|
throw new Error("ERR_WAPP_DOWNLOAD_MEDIA");
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(
|
|
||||||
"MEDIA.FILENAME: ",
|
|
||||||
media.fileName,
|
|
||||||
" | msg.fromMe: ",
|
|
||||||
msg.fromMe
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!media.filename) {
|
if (!media.filename) {
|
||||||
console.log("No file name -----------------------------------------");
|
|
||||||
|
|
||||||
const ext = media.mimetype.split("/")[1].split(";")[0];
|
const ext = media.mimetype.split("/")[1].split(";")[0];
|
||||||
media.filename = `${new Date().getTime()}.${ext}`;
|
media.filename = `${new Date().getTime()}.${ext}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// await writeFileAsync(
|
|
||||||
// join(__dirname, "..", "..", "..", "public", media.filename),
|
|
||||||
// media.data,
|
|
||||||
// "base64"
|
|
||||||
// );
|
|
||||||
|
|
||||||
console.log("FROM wbotMessageListener.ts media.filename: ", media.filename);
|
|
||||||
|
|
||||||
await writeFileAsync(
|
await writeFileAsync(
|
||||||
join(__dirname, "..", "..", "..", "..", "..", "public", media.filename),
|
join(__dirname, "..", "..", "..", "..", "..", "public", media.filename),
|
||||||
media.data,
|
media.data,
|
||||||
|
@ -199,15 +187,11 @@ const verifyMediaMessage = async (
|
||||||
};
|
};
|
||||||
|
|
||||||
const verifyMessage = async (
|
const verifyMessage = async (
|
||||||
msg: WbotMessage,
|
msg: any,
|
||||||
ticket: Ticket,
|
ticket: Ticket,
|
||||||
contact: Contact,
|
contact: Contact,
|
||||||
quotedMsg?: any
|
quotedMsg?: any
|
||||||
) => {
|
) => {
|
||||||
// const quotedMsg = await verifyQuotedMessage(msg);
|
|
||||||
|
|
||||||
// const quotedMsg = await verifyQuotedMessage(msg);
|
|
||||||
|
|
||||||
const messageData = {
|
const messageData = {
|
||||||
id: msg.id.id,
|
id: msg.id.id,
|
||||||
ticketId: ticket.id,
|
ticketId: ticket.id,
|
||||||
|
@ -217,7 +201,6 @@ const verifyMessage = async (
|
||||||
mediaType: msg.type,
|
mediaType: msg.type,
|
||||||
read: msg.fromMe,
|
read: msg.fromMe,
|
||||||
quotedMsgId: quotedMsg
|
quotedMsgId: quotedMsg
|
||||||
// quotedMsgId: quotedMsg?.id
|
|
||||||
};
|
};
|
||||||
|
|
||||||
await ticket.update({ lastMessage: msg.body });
|
await ticket.update({ lastMessage: msg.body });
|
||||||
|
@ -233,14 +216,6 @@ const verifyQueue = async (
|
||||||
) => {
|
) => {
|
||||||
const { queues, greetingMessage } = await ShowWhatsAppService(wbot.id!);
|
const { queues, greetingMessage } = await ShowWhatsAppService(wbot.id!);
|
||||||
|
|
||||||
/*if (queues.length === 1) {
|
|
||||||
await UpdateTicketService({
|
|
||||||
ticketData: { queueId: queues[0].id },
|
|
||||||
ticketId: ticket.id
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
let selectedOption = null;
|
let selectedOption = null;
|
||||||
let choosenQueue = null;
|
let choosenQueue = null;
|
||||||
|
|
||||||
|
@ -343,9 +318,11 @@ const verifyQueue = async (
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const isValidMsg = (msg: WbotMessage): boolean => {
|
const isValidMsg = (msg: any): boolean => {
|
||||||
if (msg.from === "status@broadcast") return false;
|
if (msg.from === "status@broadcast") return false;
|
||||||
if (
|
if (
|
||||||
|
msg.type === "text" ||
|
||||||
|
msg.type === "hsm" ||
|
||||||
msg.type === "chat" ||
|
msg.type === "chat" ||
|
||||||
msg.type === "audio" ||
|
msg.type === "audio" ||
|
||||||
msg.type === "ptt" ||
|
msg.type === "ptt" ||
|
||||||
|
@ -446,8 +423,6 @@ const handleMessage = async (msg: any, wbot: any): Promise<void> => {
|
||||||
console.log("INDEX: ", index);
|
console.log("INDEX: ", index);
|
||||||
|
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
// console.log('-----------------> LST: ', lst):q
|
|
||||||
|
|
||||||
lst.push({ id: msg.id.id });
|
lst.push({ id: msg.id.id });
|
||||||
|
|
||||||
setWhatsappId(msg.id.id);
|
setWhatsappId(msg.id.id);
|
||||||
|
@ -456,9 +431,6 @@ const handleMessage = async (msg: any, wbot: any): Promise<void> => {
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log('LIST OF ID MESSAGE lst: ', lst)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isValidMsg(msg)) {
|
if (!isValidMsg(msg)) {
|
||||||
|
@ -483,31 +455,15 @@ const handleMessage = async (msg: any, wbot: any): Promise<void> => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log('FROM ME: ', msg.fromMe, ' | /\u200e/.test(msg.body[0]: ', (/\u200e/.test(msg.body[0])))
|
|
||||||
|
|
||||||
// messages sent automatically by wbot have a special character in front of it
|
// messages sent automatically by wbot have a special character in front of it
|
||||||
// if so, this message was already been stored in database;
|
// if so, this message was already been stored in database;
|
||||||
// if (/\u200e/.test(msg.body[0])) return;
|
// if (/\u200e/.test(msg.body[0])) return;
|
||||||
|
|
||||||
// console.log('PASSOU 1')
|
|
||||||
|
|
||||||
// media messages sent from me from cell phone, first comes with "hasMedia = false" and type = "image/ptt/etc"
|
// 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"
|
// 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") return;
|
||||||
|
|
||||||
// console.log('PASSOU 2')
|
|
||||||
|
|
||||||
// msgContact = await wbot.getContactById(msg.to);
|
|
||||||
|
|
||||||
// console.log('1 --------------> msgContat: ', JSON.parse(JSON.stringify(msgContact)))
|
|
||||||
// console.log(' # msg.type: ', msg.type )
|
|
||||||
} else {
|
} else {
|
||||||
// msgContact = await msg.getContact();
|
|
||||||
|
|
||||||
// console.log('2 --------------> msgContat: ', JSON.parse(JSON.stringify(msgContact)))
|
|
||||||
|
|
||||||
//
|
|
||||||
console.log(`\n <<<<<<<<<< RECEIVING MESSAGE:
|
console.log(`\n <<<<<<<<<< RECEIVING MESSAGE:
|
||||||
Parcial msg and msgContact info:
|
Parcial msg and msgContact info:
|
||||||
msgContact.name: ${msgContact.name}
|
msgContact.name: ${msgContact.name}
|
||||||
|
@ -520,7 +476,6 @@ const handleMessage = async (msg: any, wbot: any): Promise<void> => {
|
||||||
msg.from: ${msg.from}
|
msg.from: ${msg.from}
|
||||||
msg.to: ${msg.to}\n`);
|
msg.to: ${msg.to}\n`);
|
||||||
}
|
}
|
||||||
// const chat = await msg.getChat();
|
|
||||||
const chat = wbot.chat;
|
const chat = wbot.chat;
|
||||||
|
|
||||||
// if(chat.isGroup){
|
// if(chat.isGroup){
|
||||||
|
@ -545,14 +500,10 @@ const handleMessage = async (msg: any, wbot: any): Promise<void> => {
|
||||||
|
|
||||||
const whatsapp = await ShowWhatsAppService(wbot.id!);
|
const whatsapp = await ShowWhatsAppService(wbot.id!);
|
||||||
|
|
||||||
// const whatsapp = await ShowWhatsAppService(46);
|
|
||||||
|
|
||||||
const unreadMessages = msg.fromMe ? 0 : chat.unreadCount;
|
const unreadMessages = msg.fromMe ? 0 : chat.unreadCount;
|
||||||
|
|
||||||
const contact = await verifyContact(msgContact);
|
const contact = await verifyContact(msgContact);
|
||||||
|
|
||||||
// console.log('----------> contact: ', JSON.parse(JSON.stringify(contact)))
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
unreadMessages === 0 &&
|
unreadMessages === 0 &&
|
||||||
whatsapp.farewellMessage &&
|
whatsapp.farewellMessage &&
|
||||||
|
@ -567,9 +518,6 @@ const handleMessage = async (msg: any, wbot: any): Promise<void> => {
|
||||||
// groupContact
|
// groupContact
|
||||||
);
|
);
|
||||||
|
|
||||||
//
|
|
||||||
// await updateTicketCacheByTicketId(ticket.id, {'contact.profilePicUrl': ticket.contact.profilePicUrl})
|
|
||||||
|
|
||||||
if (getSettingValue("oneContactChatWithManyWhats")?.value == "disabled") {
|
if (getSettingValue("oneContactChatWithManyWhats")?.value == "disabled") {
|
||||||
// Para responder para o cliente pelo mesmo whatsapp que ele enviou a mensagen
|
// Para responder para o cliente pelo mesmo whatsapp que ele enviou a mensagen
|
||||||
if (wbot.id != ticket.whatsappId) {
|
if (wbot.id != ticket.whatsappId) {
|
||||||
|
@ -675,8 +623,16 @@ const handleMessage = async (msg: any, wbot: any): Promise<void> => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMsgAck = async (msg_id: any, ack: any) => {
|
const handleMsgAck = async (
|
||||||
await new Promise(r => setTimeout(r, 4000));
|
msg_id: any,
|
||||||
|
ack: any,
|
||||||
|
whatsAppOfficial?: boolean
|
||||||
|
) => {
|
||||||
|
if (whatsAppOfficial) {
|
||||||
|
if (ack == "sent") ack = 1;
|
||||||
|
else if (ack == "delivered") ack = 2;
|
||||||
|
else if (ack == "read") ack = 3;
|
||||||
|
} else await new Promise(r => setTimeout(r, 4000));
|
||||||
|
|
||||||
const io = getIO();
|
const io = getIO();
|
||||||
|
|
||||||
|
@ -723,4 +679,12 @@ const wbotMessageListener = (wbot: Session): void => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export { wbotMessageListener, handleMessage, handleMsgAck, lst };
|
export {
|
||||||
|
wbotMessageListener,
|
||||||
|
handleMessage,
|
||||||
|
handleMsgAck,
|
||||||
|
lst,
|
||||||
|
verifyMessage,
|
||||||
|
verifyContact,
|
||||||
|
isValidMsg,
|
||||||
|
};
|
||||||
|
|
|
@ -130,8 +130,6 @@ const NotificationsPopOver = () => {
|
||||||
|
|
||||||
if (data.action === "logout") {
|
if (data.action === "logout") {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (`${user.id}` === data.userOnlineTime['userId']) {
|
if (`${user.id}` === data.userOnlineTime['userId']) {
|
||||||
|
|
||||||
socket.emit("online", { logoutUserId: user.id })
|
socket.emit("online", { logoutUserId: user.id })
|
||||||
|
|
|
@ -226,6 +226,37 @@ const Settings = () => {
|
||||||
</Paper>
|
</Paper>
|
||||||
</Container>
|
</Container>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div className={classes.root}>
|
||||||
|
<Container className={classes.container} maxWidth="sm">
|
||||||
|
<Paper className={classes.paper}>
|
||||||
|
<Typography variant="body1">
|
||||||
|
Whatsapp Cloud API
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Select
|
||||||
|
margin="dense"
|
||||||
|
variant="outlined"
|
||||||
|
native
|
||||||
|
id="whatsaAppCloudApi-setting"
|
||||||
|
name="whatsaAppCloudApi"
|
||||||
|
value={
|
||||||
|
settings &&
|
||||||
|
settings.length > 0 &&
|
||||||
|
getSettingValue('whatsaAppCloudApi')
|
||||||
|
}
|
||||||
|
className={classes.settingOption}
|
||||||
|
onChange={handleChangeSetting}
|
||||||
|
>
|
||||||
|
<option value="enabled">Ativado</option>
|
||||||
|
<option value="disabled">Desativado</option>
|
||||||
|
</Select>
|
||||||
|
</Paper>
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
Loading…
Reference in New Issue