Merge branch 'master' of github.com:AdrianoRobson/projeto-hit
commit
e864e0b97f
|
@ -124,22 +124,13 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
|
|
||||||
newContact.number = addStartPhoneNumber(newContact.number);
|
newContact.number = addStartPhoneNumber(newContact.number);
|
||||||
|
|
||||||
const validNumber = await CheckIsValidContact(newContact.number);
|
const validNumber = await CheckIsValidContact(newContact.number);
|
||||||
|
|
||||||
// const validNumber: any = await CheckContactNumber(newContact.number)
|
|
||||||
|
|
||||||
if (!validNumber) {
|
if (!validNumber) {
|
||||||
throw new AppError("ERR_WAPP_CHECK_CONTACT");
|
throw new AppError("ERR_WAPP_CHECK_CONTACT");
|
||||||
}
|
}
|
||||||
|
|
||||||
const profilePicUrl = await GetProfilePicUrl(validNumber);
|
const profilePicUrl = await GetProfilePicUrl(validNumber);
|
||||||
|
|
||||||
console.log("xxxxxxxxxxx profilePicUrl: ", profilePicUrl);
|
|
||||||
|
|
||||||
// console.log(`newContact.name: ${newContact.name}\n
|
|
||||||
// newContact.number: ${newContact.number}\n
|
|
||||||
// newContact.email: ${newContact.email}\n
|
|
||||||
// newContact.extraInfo: ${newContact.extraInfo}`)
|
|
||||||
|
|
||||||
let name = newContact.name;
|
let name = newContact.name;
|
||||||
let number = validNumber;
|
let number = validNumber;
|
||||||
|
|
|
@ -21,6 +21,7 @@ import sendWhatsAppMessageOfficialAPI from "../helpers/sendWhatsAppMessageOffici
|
||||||
import Whatsapp from "../models/Whatsapp";
|
import Whatsapp from "../models/Whatsapp";
|
||||||
import checkLastClientMsg24hs from "../helpers/CheckLastClientMsg24hs";
|
import checkLastClientMsg24hs from "../helpers/CheckLastClientMsg24hs";
|
||||||
import AppError from "../errors/AppError";
|
import AppError from "../errors/AppError";
|
||||||
|
import { get } from "../helpers/RedisClient";
|
||||||
|
|
||||||
type IndexQuery = {
|
type IndexQuery = {
|
||||||
pageNumber: string;
|
pageNumber: string;
|
||||||
|
@ -35,7 +36,7 @@ type MessageData = {
|
||||||
params: any;
|
params: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const index = async (req: Request, res: Response): Promise<Response> => {
|
export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||||
const { ticketId } = req.params;
|
const { ticketId } = req.params;
|
||||||
const { pageNumber } = req.query as IndexQuery;
|
const { pageNumber } = req.query as IndexQuery;
|
||||||
|
|
||||||
|
@ -97,7 +98,8 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const name = params.find((p: any) => p?.template_name);
|
const name = params.find((p: any) => p?.template_name);
|
||||||
const { language }: any = params?.find((p: any) => p?.language) || 'pt_BR'
|
const { language }: any =
|
||||||
|
params?.find((p: any) => p?.language) || "pt_BR";
|
||||||
|
|
||||||
const { template_name } = name;
|
const { template_name } = name;
|
||||||
|
|
||||||
|
|
|
@ -5,14 +5,12 @@ import DeleteQueueService from "../services/QueueService/DeleteQueueService";
|
||||||
import ListQueuesService from "../services/QueueService/ListQueuesService";
|
import ListQueuesService from "../services/QueueService/ListQueuesService";
|
||||||
import ShowQueueService from "../services/QueueService/ShowQueueService";
|
import ShowQueueService from "../services/QueueService/ShowQueueService";
|
||||||
import UpdateQueueService from "../services/QueueService/UpdateQueueService";
|
import UpdateQueueService from "../services/QueueService/UpdateQueueService";
|
||||||
import Queue from "../models/Queue"
|
import Queue from "../models/Queue";
|
||||||
import AppError from "../errors/AppError"
|
import AppError from "../errors/AppError";
|
||||||
import { get, set } from "../helpers/RedisClient";
|
import { del, get, set } from "../helpers/RedisClient";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const index = async (req: Request, res: Response): Promise<Response> => {
|
export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||||
const queues = await ListQueuesService();
|
const queues = await ListQueuesService();
|
||||||
|
|
||||||
return res.status(200).json(queues);
|
return res.status(200).json(queues);
|
||||||
};
|
};
|
||||||
|
@ -125,7 +123,7 @@ export const customization = async (
|
||||||
|
|
||||||
await set("ura", ura);
|
await set("ura", ura);
|
||||||
|
|
||||||
const _ura = await get("ura");
|
const _ura = await get({ key: "ura", parse: true });
|
||||||
console.log("_URA: ", _ura);
|
console.log("_URA: ", _ura);
|
||||||
|
|
||||||
return res.status(200).json({ new_queues });
|
return res.status(200).json({ new_queues });
|
||||||
|
@ -164,6 +162,8 @@ export const remove = async (
|
||||||
|
|
||||||
await DeleteQueueService(queueId);
|
await DeleteQueueService(queueId);
|
||||||
|
|
||||||
|
await del(`queue:${queueId}`);
|
||||||
|
|
||||||
const io = getIO();
|
const io = getIO();
|
||||||
io.emit("queue", {
|
io.emit("queue", {
|
||||||
action: "delete",
|
action: "delete",
|
||||||
|
|
|
@ -75,8 +75,9 @@ import GetProfilePicUrl from "../services/WbotServices/GetProfilePicUrl";
|
||||||
import CreateContactService from "../services/ContactServices/CreateContactService";
|
import CreateContactService from "../services/ContactServices/CreateContactService";
|
||||||
import { botSendMessage } from "../services/WbotServices/wbotMessageListener";
|
import { botSendMessage } from "../services/WbotServices/wbotMessageListener";
|
||||||
import WhatsappQueue from "../models/WhatsappQueue";
|
import WhatsappQueue from "../models/WhatsappQueue";
|
||||||
|
import { get } from "../helpers/RedisClient"
|
||||||
|
|
||||||
export const index = async (req: Request, res: Response): Promise<Response> => {
|
export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||||
const {
|
const {
|
||||||
pageNumber,
|
pageNumber,
|
||||||
status,
|
status,
|
||||||
|
@ -93,9 +94,9 @@ export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||||
|
|
||||||
let queueIds: number[] = [];
|
let queueIds: number[] = [];
|
||||||
|
|
||||||
if (queueIdsStringified) {
|
if (queueIdsStringified && queueIdsStringified.trim().length > 0) {
|
||||||
queueIds = JSON.parse(queueIdsStringified);
|
queueIds = JSON.parse(queueIdsStringified);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { tickets, count, hasMore } = await ListTicketsService({
|
const { tickets, count, hasMore } = await ListTicketsService({
|
||||||
searchParam,
|
searchParam,
|
||||||
|
@ -109,7 +110,7 @@ export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||||
unlimited,
|
unlimited,
|
||||||
searchParamContent
|
searchParamContent
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(200).json({ tickets, count, hasMore });
|
return res.status(200).json({ tickets, count, hasMore });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import DeleteUserService from "../services/UserServices/DeleteUserService";
|
||||||
|
|
||||||
import ListUser from "../services/UserServices/ListUserParamiterService";
|
import ListUser from "../services/UserServices/ListUserParamiterService";
|
||||||
import User from "../models/User";
|
import User from "../models/User";
|
||||||
import { get, set } from "../helpers/RedisClient";
|
import { del, get, set } from "../helpers/RedisClient";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
startWhoIsOnlineMonitor,
|
startWhoIsOnlineMonitor,
|
||||||
|
@ -27,6 +27,7 @@ import { splitDateTime } from "../helpers/SplitDateTime";
|
||||||
import ListUserByWhatsappQueuesService from "../services/UserServices/ListUserByWhatsappQueuesService";
|
import ListUserByWhatsappQueuesService from "../services/UserServices/ListUserByWhatsappQueuesService";
|
||||||
import { json } from "sequelize";
|
import { json } from "sequelize";
|
||||||
import { getSettingValue } from "../helpers/WhaticketSettings";
|
import { getSettingValue } from "../helpers/WhaticketSettings";
|
||||||
|
import { setBotInfo } from "../helpers/SetBotInfo";
|
||||||
|
|
||||||
type IndexQuery = {
|
type IndexQuery = {
|
||||||
searchParam: string;
|
searchParam: string;
|
||||||
|
@ -110,8 +111,7 @@ export const all = async (req: Request, res: Response): Promise<Response> => {
|
||||||
getSettingValue("queueTransferByWhatsappScope")?.value
|
getSettingValue("queueTransferByWhatsappScope")?.value
|
||||||
);
|
);
|
||||||
|
|
||||||
if (getSettingValue("queueTransferByWhatsappScope")?.value == "enabled") {
|
if (getSettingValue("queueTransferByWhatsappScope")?.value == "enabled") {
|
||||||
|
|
||||||
if (!userId) return res.json({ users: [], queues: [] });
|
if (!userId) return res.json({ users: [], queues: [] });
|
||||||
|
|
||||||
const obj = await ListUserByWhatsappQueuesService(
|
const obj = await ListUserByWhatsappQueuesService(
|
||||||
|
@ -122,7 +122,7 @@ export const all = async (req: Request, res: Response): Promise<Response> => {
|
||||||
const usersByWhatsqueue = obj.users;
|
const usersByWhatsqueue = obj.users;
|
||||||
const queues = obj.queues;
|
const queues = obj.queues;
|
||||||
|
|
||||||
let userIds = usersByWhatsqueue.map((w: any) => w.userId);
|
let userIds = usersByWhatsqueue.map((w: any) => w.userId);
|
||||||
|
|
||||||
const users = await ListUser({
|
const users = await ListUser({
|
||||||
userIds
|
userIds
|
||||||
|
@ -167,6 +167,11 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
queueIds
|
queueIds
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (user) {
|
||||||
|
const { id, name } = user;
|
||||||
|
await set(`user:${id}`, { id, name });
|
||||||
|
}
|
||||||
|
|
||||||
const io = getIO();
|
const io = getIO();
|
||||||
io.emit("user", {
|
io.emit("user", {
|
||||||
action: "create",
|
action: "create",
|
||||||
|
@ -270,34 +275,11 @@ export const update = async (
|
||||||
|
|
||||||
let user: any = await UpdateUserService({ userData, userId });
|
let user: any = await UpdateUserService({ userData, userId });
|
||||||
|
|
||||||
if (user?.name?.trim() == "botqueue") {
|
await setBotInfo(user);
|
||||||
let botInfo;
|
|
||||||
|
|
||||||
if (
|
if (user) {
|
||||||
user?.queues?.length > 0 &&
|
const { id, name } = user;
|
||||||
user.queues[0]?.name?.trim() == "botqueue"
|
await set(`user:${id}`, { id, name });
|
||||||
) {
|
|
||||||
botInfo = JSON.stringify({
|
|
||||||
userId: user.id,
|
|
||||||
queueId: user.queues[0].id,
|
|
||||||
botIsOnQueue: true
|
|
||||||
});
|
|
||||||
botInfo = JSON.parse(botInfo);
|
|
||||||
|
|
||||||
await set("botInfo", botInfo);
|
|
||||||
} else if (
|
|
||||||
user?.queues?.length == 0 ||
|
|
||||||
user.queues[0]?.name?.trim() != "botqueue"
|
|
||||||
) {
|
|
||||||
botInfo = JSON.stringify({
|
|
||||||
userId: user.id,
|
|
||||||
queueId: 0,
|
|
||||||
botIsOnQueue: false
|
|
||||||
});
|
|
||||||
botInfo = JSON.parse(botInfo);
|
|
||||||
|
|
||||||
await set("botInfo", botInfo);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const io = getIO();
|
const io = getIO();
|
||||||
|
@ -323,6 +305,8 @@ export const remove = async (
|
||||||
|
|
||||||
await DeleteUserService(userId);
|
await DeleteUserService(userId);
|
||||||
|
|
||||||
|
del(`user:${userId}`);
|
||||||
|
|
||||||
const io = getIO();
|
const io = getIO();
|
||||||
io.emit("user", {
|
io.emit("user", {
|
||||||
action: "delete",
|
action: "delete",
|
||||||
|
|
|
@ -42,6 +42,7 @@ import { getSettingValue } from "../helpers/WhaticketSettings";
|
||||||
import ListWhatsAppsNumber from "../services/WhatsappService/ListWhatsAppsNumber";
|
import ListWhatsAppsNumber from "../services/WhatsappService/ListWhatsAppsNumber";
|
||||||
import SettingTicket from "../models/SettingTicket";
|
import SettingTicket from "../models/SettingTicket";
|
||||||
import { Op } from "sequelize";
|
import { Op } from "sequelize";
|
||||||
|
import { del, get, set } from "../helpers/RedisClient";
|
||||||
|
|
||||||
interface WhatsappData {
|
interface WhatsappData {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -229,6 +230,25 @@ export const weebhook = async (
|
||||||
req.body.entry[0].changes[0].value.metadata.display_phone_number;
|
req.body.entry[0].changes[0].value.metadata.display_phone_number;
|
||||||
let type = message.type;
|
let type = message.type;
|
||||||
|
|
||||||
|
const contact_to_exist = await get({
|
||||||
|
key: "whatsapp:*",
|
||||||
|
value: `${contact_to}`
|
||||||
|
});
|
||||||
|
|
||||||
|
if (contact_to_exist == null) {
|
||||||
|
console.log(
|
||||||
|
"WHATSAPP OFFICIAL",
|
||||||
|
" | CONCTACT_FROM: ",
|
||||||
|
contact_from,
|
||||||
|
" | CONTACT_TO: ",
|
||||||
|
contact_to
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
"NUMBER IGNORED. WHATSAPP NUMBER FROM ANOTHER OMNIHIT APPLICATION!"
|
||||||
|
);
|
||||||
|
return res.status(403).json({ error: "Unauthorized" });
|
||||||
|
}
|
||||||
|
|
||||||
let wbot = {};
|
let wbot = {};
|
||||||
let msg = {};
|
let msg = {};
|
||||||
let contacts = req.body.entry[0].changes[0].value.contacts[0];
|
let contacts = req.body.entry[0].changes[0].value.contacts[0];
|
||||||
|
@ -248,6 +268,10 @@ export const weebhook = async (
|
||||||
});
|
});
|
||||||
|
|
||||||
if (type == "text") {
|
if (type == "text") {
|
||||||
|
if (!message?.text?.body) {
|
||||||
|
return res.status(400).json({ error: "body not found" });
|
||||||
|
}
|
||||||
|
|
||||||
type = "chat";
|
type = "chat";
|
||||||
msg = {
|
msg = {
|
||||||
...msg,
|
...msg,
|
||||||
|
@ -255,6 +279,10 @@ export const weebhook = async (
|
||||||
type
|
type
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
|
if (!message[message?.type]?.id) {
|
||||||
|
return res.status(400).json({ error: "id not found" });
|
||||||
|
}
|
||||||
|
|
||||||
const mediaId = message[message.type].id;
|
const mediaId = message[message.type].id;
|
||||||
const mimetype = message[message.type].mime_type;
|
const mimetype = message[message.type].mime_type;
|
||||||
|
|
||||||
|
@ -382,6 +410,16 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
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}`
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
await set(
|
||||||
|
`whatsapp:${whatsapp.id}`,
|
||||||
|
JSON.stringify({
|
||||||
|
number: whatsapp?.number,
|
||||||
|
id: whatsapp?.id,
|
||||||
|
greetingMessage: whatsapp?.greetingMessage,
|
||||||
|
phoneNumberId: whatsapp?.phoneNumberId
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const io = getIO();
|
const io = getIO();
|
||||||
|
@ -421,13 +459,14 @@ export const update = async (
|
||||||
return res.status(200).json({ message: invalidPhoneName });
|
return res.status(200).json({ message: invalidPhoneName });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { urlApi, isOfficial, phoneNumberId, wabaId } = whatsappData;
|
const { urlApi, isOfficial, phoneNumberId, number, wabaId } = whatsappData;
|
||||||
|
|
||||||
const invalid = checkWhatsAppData({
|
const invalid = checkWhatsAppData({
|
||||||
urlApi,
|
urlApi,
|
||||||
isOfficial,
|
isOfficial,
|
||||||
phoneNumberId,
|
phoneNumberId,
|
||||||
wabaId
|
wabaId,
|
||||||
|
number
|
||||||
});
|
});
|
||||||
|
|
||||||
if (invalid) {
|
if (invalid) {
|
||||||
|
@ -440,6 +479,7 @@ export const update = async (
|
||||||
} else if (!isOfficial) {
|
} else if (!isOfficial) {
|
||||||
whatsappData.phoneNumberId = "";
|
whatsappData.phoneNumberId = "";
|
||||||
whatsappData.wabaId = "";
|
whatsappData.wabaId = "";
|
||||||
|
whatsappData.number = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
const { whatsapp, oldDefaultWhatsapp } = await UpdateWhatsAppService({
|
const { whatsapp, oldDefaultWhatsapp } = await UpdateWhatsAppService({
|
||||||
|
@ -454,6 +494,16 @@ export const update = async (
|
||||||
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}`
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
await set(
|
||||||
|
`whatsapp:${whatsapp.id}`,
|
||||||
|
JSON.stringify({
|
||||||
|
number: whatsapp?.number,
|
||||||
|
id: whatsapp?.id,
|
||||||
|
greetingMessage: whatsapp?.greetingMessage,
|
||||||
|
phoneNumberId: whatsapp?.phoneNumberId
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const io = getIO();
|
const io = getIO();
|
||||||
|
@ -491,6 +541,8 @@ export const remove = async (
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await del(`whatsapp:${whatsappId}`);
|
||||||
|
|
||||||
let whats = await ListWhatsAppsNumber(whatsappId);
|
let whats = await ListWhatsAppsNumber(whatsappId);
|
||||||
|
|
||||||
// Remove tickets business hours config
|
// Remove tickets business hours config
|
||||||
|
@ -572,5 +624,5 @@ const checkWhatsAppData = ({
|
||||||
return { message: "Phone number is required!" };
|
return { message: "Phone number is required!" };
|
||||||
} else if (!isOfficial && (!urlApi || urlApi.trim() == "")) {
|
} else if (!isOfficial && (!urlApi || urlApi.trim() == "")) {
|
||||||
return { message: "urlApi is required!" };
|
return { message: "urlApi is required!" };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { QueryInterface, DataTypes } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.addColumn("Messages", "fromAgent", {
|
||||||
|
type: DataTypes.BOOLEAN,
|
||||||
|
allowNull: false,
|
||||||
|
defaultValue: false
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.removeColumn("Messages", "fromAgent");
|
||||||
|
}
|
||||||
|
};
|
|
@ -4,9 +4,8 @@ const fs = require("fs");
|
||||||
import ListUsersService from "../services/UserServices/ListUsersService";
|
import ListUsersService from "../services/UserServices/ListUsersService";
|
||||||
import { get } from "./RedisClient";
|
import { get } from "./RedisClient";
|
||||||
|
|
||||||
const _botIsOnQueue = async (botName: string) => {
|
const _botIsOnQueue = async (botName: string) => {
|
||||||
|
const botInfo = await get({ key: "botInfo", parse: true });
|
||||||
const botInfo = await get("botInfo");
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
botInfo &&
|
botInfo &&
|
||||||
|
@ -19,8 +18,8 @@ const _botIsOnQueue = async (botName: string) => {
|
||||||
botQueueId: botInfo.queueId,
|
botQueueId: botInfo.queueId,
|
||||||
isOnQueue: botInfo.botIsOnQueue
|
isOnQueue: botInfo.botIsOnQueue
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return { userIdBot: null, botQueueId: null, isOnQueue: false };
|
return { userIdBot: null, botQueueId: null, isOnQueue: false };
|
||||||
};
|
};
|
||||||
|
|
||||||
export default _botIsOnQueue;
|
export default _botIsOnQueue;
|
||||||
|
|
|
@ -6,27 +6,26 @@ import UserQueue from "../models/UserQueue";
|
||||||
|
|
||||||
import { Op, where } from "sequelize";
|
import { Op, where } from "sequelize";
|
||||||
|
|
||||||
import wbotByUserQueue from "../helpers/GetWbotByUserQueue";
|
import wbotByUserQueue from "../helpers/GetWbotByUserQueue";
|
||||||
|
|
||||||
import { WhatsIndex } from "./LoadBalanceWhatsSameQueue";
|
import { WhatsIndex } from "./LoadBalanceWhatsSameQueue";
|
||||||
|
|
||||||
interface Request {
|
interface Request {
|
||||||
userId?: string | number;
|
userId?: string | number;
|
||||||
queueId?: string | number;
|
queueId?: string | number;
|
||||||
|
ignoreNoWhatsappFound?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
//const GetDefaultWhatsApp = async (userId?: string | number): Promise<Whatsapp> => {
|
|
||||||
|
|
||||||
const GetDefaultWhatsApp = async ({
|
const GetDefaultWhatsApp = async ({
|
||||||
userId,
|
userId,
|
||||||
queueId
|
queueId,
|
||||||
}: Request): Promise<any> => {
|
ignoreNoWhatsappFound = false
|
||||||
// test del
|
}: Request): Promise<any> => {
|
||||||
let defaultWhatsapp = await Whatsapp.findOne({
|
let defaultWhatsapp = await Whatsapp.findOne({
|
||||||
where: { isDefault: true }
|
where: { isDefault: true }
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!defaultWhatsapp) {
|
if (!defaultWhatsapp) {
|
||||||
if (userId) {
|
if (userId) {
|
||||||
let whatsapps = await wbotByUserQueue({ userId, queueId });
|
let whatsapps = await wbotByUserQueue({ userId, queueId });
|
||||||
|
|
||||||
|
@ -54,19 +53,18 @@ const GetDefaultWhatsApp = async ({
|
||||||
where: { status: "CONNECTED" }
|
where: { status: "CONNECTED" }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
defaultWhatsapp = await Whatsapp.findOne({
|
defaultWhatsapp = await Whatsapp.findOne({
|
||||||
where: { status: "CONNECTED" }
|
where: { status: "CONNECTED", isOfficial: false }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!defaultWhatsapp) {
|
if (!defaultWhatsapp && !ignoreNoWhatsappFound) {
|
||||||
throw new AppError("ERR_NO_DEF_WAPP_FOUND");
|
throw new AppError("ERR_NO_DEF_WAPP_FOUND");
|
||||||
}
|
}
|
||||||
|
|
||||||
return defaultWhatsapp;
|
return defaultWhatsapp;
|
||||||
//
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default GetDefaultWhatsApp;
|
export default GetDefaultWhatsApp;
|
||||||
|
|
|
@ -6,28 +6,65 @@ type WhatsappData = {
|
||||||
contactId: string;
|
contactId: string;
|
||||||
identifier: string;
|
identifier: string;
|
||||||
value?: string;
|
value?: string;
|
||||||
|
history?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type getData = {
|
||||||
|
key: string;
|
||||||
|
value?: string;
|
||||||
|
parse?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function set(key: string, value: string | object) {
|
export async function set(key: string, value: string | object) {
|
||||||
await redis.set(key, JSON.stringify(value));
|
if (typeof value == "object") await redis.set(key, JSON.stringify(value));
|
||||||
}
|
else {
|
||||||
|
await redis.set(key, value);
|
||||||
export async function get(key: string) {
|
|
||||||
const value: any = await redis.get(key);
|
|
||||||
return JSON.parse(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function clearAllKeys() {
|
|
||||||
// Retrieve all keys matching the pattern '*'
|
|
||||||
const keys = await redis.keys("user:*");
|
|
||||||
|
|
||||||
// If there are keys, delete them
|
|
||||||
if (keys.length > 0) {
|
|
||||||
console.log('keys: ', keys)
|
|
||||||
await redis.del(...keys);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getSimple(key: string) {
|
||||||
|
const value: any = await redis.get(key);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function get({ key, value, parse }: getData) {
|
||||||
|
if (key.includes("*")) {
|
||||||
|
const keys = await redis.keys(key);
|
||||||
|
if (keys.length > 0) {
|
||||||
|
for (const key of keys) {
|
||||||
|
const val = await redis.get(key);
|
||||||
|
if (val.includes(value)) {
|
||||||
|
if (parse) return JSON.parse(val);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
const value: any = await redis.get(key);
|
||||||
|
|
||||||
|
if (parse) return JSON.parse(value);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function del(key: string) {
|
||||||
|
await redis.del(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function clearAllKeys(...keys: string[]) {
|
||||||
|
for (const key of keys) {
|
||||||
|
// Retrieve all keys matching the pattern '*'
|
||||||
|
const del_keys = await redis.keys(key);
|
||||||
|
|
||||||
|
// If there are keys, delete them
|
||||||
|
if (del_keys.length > 0) {
|
||||||
|
console.log("del_keys: ", del_keys);
|
||||||
|
await redis.del(...del_keys);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function findByContain(
|
export async function findByContain(
|
||||||
key: string,
|
key: string,
|
||||||
|
@ -54,7 +91,7 @@ export async function findByContain(
|
||||||
results.push(obj);
|
results.push(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +99,8 @@ export async function createObject({
|
||||||
whatsappId,
|
whatsappId,
|
||||||
contactId,
|
contactId,
|
||||||
identifier,
|
identifier,
|
||||||
value
|
value,
|
||||||
|
history = ""
|
||||||
}: WhatsappData) {
|
}: WhatsappData) {
|
||||||
const key = `whatsappId:${whatsappId}:contactId:${contactId}:identifier:${identifier}`;
|
const key = `whatsappId:${whatsappId}:contactId:${contactId}:identifier:${identifier}`;
|
||||||
const result = await redis.hmset(
|
const result = await redis.hmset(
|
||||||
|
@ -74,7 +112,9 @@ export async function createObject({
|
||||||
"identifier",
|
"identifier",
|
||||||
identifier,
|
identifier,
|
||||||
"value",
|
"value",
|
||||||
value
|
value,
|
||||||
|
"history",
|
||||||
|
history
|
||||||
);
|
);
|
||||||
|
|
||||||
await redis.expire(key, 300);
|
await redis.expire(key, 300);
|
||||||
|
@ -102,7 +142,8 @@ export async function findObject(
|
||||||
"whatsappId",
|
"whatsappId",
|
||||||
"contactId",
|
"contactId",
|
||||||
"identifier",
|
"identifier",
|
||||||
"value"
|
"value",
|
||||||
|
"history"
|
||||||
);
|
);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
import { get, set } from "../helpers/RedisClient";
|
||||||
|
|
||||||
|
export async function setBotInfo(user: any) {
|
||||||
|
if (user?.name?.trim() == "botqueue") {
|
||||||
|
let botInfo;
|
||||||
|
|
||||||
|
if (
|
||||||
|
user?.queues?.length > 0 &&
|
||||||
|
user.queues[0]?.name?.trim() == "botqueue"
|
||||||
|
) {
|
||||||
|
botInfo = JSON.stringify({
|
||||||
|
userId: user.id,
|
||||||
|
queueId: user.queues[0].id,
|
||||||
|
botIsOnQueue: true
|
||||||
|
});
|
||||||
|
botInfo = JSON.parse(botInfo);
|
||||||
|
|
||||||
|
await set("botInfo", botInfo);
|
||||||
|
} else if (
|
||||||
|
user?.queues?.length == 0 ||
|
||||||
|
user.queues[0]?.name?.trim() != "botqueue"
|
||||||
|
) {
|
||||||
|
botInfo = JSON.stringify({
|
||||||
|
userId: user.id,
|
||||||
|
queueId: 0,
|
||||||
|
botIsOnQueue: false
|
||||||
|
});
|
||||||
|
botInfo = JSON.parse(botInfo);
|
||||||
|
|
||||||
|
await set("botInfo", botInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,6 +31,10 @@ class Message extends Model<Message> {
|
||||||
@Column
|
@Column
|
||||||
fromMe: boolean;
|
fromMe: boolean;
|
||||||
|
|
||||||
|
@Default(false)
|
||||||
|
@Column
|
||||||
|
fromAgent: boolean;
|
||||||
|
|
||||||
@Column(DataType.TEXT)
|
@Column(DataType.TEXT)
|
||||||
body: string;
|
body: string;
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,11 @@ import fs from "fs";
|
||||||
import dir from "path";
|
import dir from "path";
|
||||||
import { getSettingValue } from "./helpers/WhaticketSettings";
|
import { getSettingValue } from "./helpers/WhaticketSettings";
|
||||||
import loadSettings from "./helpers/LoadSettings";
|
import loadSettings from "./helpers/LoadSettings";
|
||||||
import { clearAllKeys, set } from "./helpers/RedisClient";
|
import { clearAllKeys, get, set } from "./helpers/RedisClient";
|
||||||
|
import ShowUserService from "./services/UserServices/ShowUserService";
|
||||||
|
import { json } from "sequelize";
|
||||||
|
import { setBotInfo } from "./helpers/SetBotInfo";
|
||||||
|
import Queue from "./models/Queue";
|
||||||
|
|
||||||
const server = app.listen(process.env.PORT, () => {
|
const server = app.listen(process.env.PORT, () => {
|
||||||
logger.info(`Server started on port: ${process.env.PORT}`);
|
logger.info(`Server started on port: ${process.env.PORT}`);
|
||||||
|
@ -39,32 +43,59 @@ const server = app.listen(process.env.PORT, () => {
|
||||||
initIO(server);
|
initIO(server);
|
||||||
|
|
||||||
// StartAllWhatsAppsSessions();
|
// StartAllWhatsAppsSessions();
|
||||||
gracefulShutdown(server);
|
gracefulShutdown(server);
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
console.log("os.tmpdir(): ", os.tmpdir());
|
console.log("os.tmpdir(): ", os.tmpdir());
|
||||||
|
|
||||||
await clearAllKeys();
|
await clearAllKeys("user:*", "whatsapp:*", "queue:*");
|
||||||
|
|
||||||
const users = await User.findAll();
|
const users = await User.findAll();
|
||||||
|
|
||||||
for (const user of users) {
|
for (const user of users) {
|
||||||
const { id, name } = user;
|
const { id, name } = user;
|
||||||
|
|
||||||
|
if (name == "botqueue") {
|
||||||
|
const userService = await ShowUserService(id);
|
||||||
|
await setBotInfo(userService);
|
||||||
|
}
|
||||||
|
|
||||||
await set(`user:${id}`, { id, name });
|
await set(`user:${id}`, { id, name });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// const queues = await Queue.findAll();
|
||||||
|
|
||||||
|
// for (const queue of queues) {
|
||||||
|
// const { id, greetingMessage, name } = queue;
|
||||||
|
// await set(`queue:${id}`, { id, name, greetingMessage });
|
||||||
|
// }
|
||||||
|
|
||||||
loadSettings();
|
loadSettings();
|
||||||
|
|
||||||
let whatsapps: any = await Whatsapp.findAll({
|
let whatsapps: any = await Whatsapp.findAll({
|
||||||
attributes: ["id", "url", "phoneNumberId"]
|
attributes: ["id", "url", "phoneNumberId", "number", "greetingMessage"]
|
||||||
});
|
});
|
||||||
|
|
||||||
if (whatsapps && whatsapps.length > 0) {
|
if (whatsapps && whatsapps.length > 0) {
|
||||||
for (let i = 0; i < whatsapps.length; i++) {
|
for (let i = 0; i < whatsapps.length; i++) {
|
||||||
try {
|
try {
|
||||||
const { phoneNumberId } = whatsapps[i];
|
const { phoneNumberId, id, greetingMessage } = whatsapps[i];
|
||||||
|
|
||||||
if (phoneNumberId) continue;
|
if (phoneNumberId) {
|
||||||
|
await set(
|
||||||
|
`whatsapp:${whatsapps[i].dataValues.id}`,
|
||||||
|
JSON.stringify({
|
||||||
|
number: whatsapps[i].dataValues.number,
|
||||||
|
id,
|
||||||
|
greetingMessage,
|
||||||
|
phoneNumberId
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (phoneNumberId) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
`API URL: ${whatsapps[i].dataValues.url}/api/connection/status`
|
`API URL: ${whatsapps[i].dataValues.url}/api/connection/status`
|
||||||
|
|
|
@ -13,6 +13,7 @@ interface MessageData {
|
||||||
read?: boolean;
|
read?: boolean;
|
||||||
mediaType?: string;
|
mediaType?: string;
|
||||||
mediaUrl?: string;
|
mediaUrl?: string;
|
||||||
|
fromAgent?: boolean;
|
||||||
}
|
}
|
||||||
interface Request {
|
interface Request {
|
||||||
messageData: MessageData;
|
messageData: MessageData;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
import AppError from "../../errors/AppError";
|
import AppError from "../../errors/AppError";
|
||||||
import Queue from "../../models/Queue";
|
import Queue from "../../models/Queue";
|
||||||
|
import { set } from "../../helpers/RedisClient";
|
||||||
|
|
||||||
interface QueueData {
|
interface QueueData {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -9,68 +10,67 @@ interface QueueData {
|
||||||
}
|
}
|
||||||
|
|
||||||
const CreateQueueService = async (queueData: QueueData): Promise<Queue> => {
|
const CreateQueueService = async (queueData: QueueData): Promise<Queue> => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
const { color, name } = queueData;
|
const { color, name } = queueData;
|
||||||
|
|
||||||
const queueSchema = Yup.object().shape({
|
const queueSchema = Yup.object().shape({
|
||||||
name: Yup.string()
|
name: Yup.string()
|
||||||
.min(2, "ERR_QUEUE_INVALID_NAME")
|
.min(2, "ERR_QUEUE_INVALID_NAME")
|
||||||
.required("ERR_QUEUE_INVALID_NAME")
|
.required("ERR_QUEUE_INVALID_NAME")
|
||||||
.test(
|
.test(
|
||||||
"Check-unique-name",
|
"Check-unique-name",
|
||||||
"ERR_QUEUE_NAME_ALREADY_EXISTS",
|
"ERR_QUEUE_NAME_ALREADY_EXISTS",
|
||||||
async value => {
|
async value => {
|
||||||
if (value) {
|
if (value) {
|
||||||
const queueWithSameName = await Queue.findOne({
|
const queueWithSameName = await Queue.findOne({
|
||||||
where: { name: value }
|
where: { name: value }
|
||||||
});
|
});
|
||||||
|
|
||||||
return !queueWithSameName;
|
return !queueWithSameName;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
),
|
||||||
|
color: Yup.string()
|
||||||
|
.required("ERR_QUEUE_INVALID_COLOR")
|
||||||
|
.test("Check-color", "ERR_QUEUE_INVALID_COLOR", async value => {
|
||||||
|
if (value) {
|
||||||
|
const colorTestRegex = /^#[0-9a-f]{3,6}$/i;
|
||||||
|
return colorTestRegex.test(value);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
})
|
||||||
),
|
.test(
|
||||||
color: Yup.string()
|
"Check-color-exists",
|
||||||
.required("ERR_QUEUE_INVALID_COLOR")
|
"ERR_QUEUE_COLOR_ALREADY_EXISTS",
|
||||||
.test("Check-color", "ERR_QUEUE_INVALID_COLOR", async value => {
|
async value => {
|
||||||
if (value) {
|
if (value) {
|
||||||
const colorTestRegex = /^#[0-9a-f]{3,6}$/i;
|
const queueWithSameColor = await Queue.findOne({
|
||||||
return colorTestRegex.test(value);
|
where: { color: value }
|
||||||
}
|
});
|
||||||
return false;
|
return !queueWithSameColor;
|
||||||
})
|
}
|
||||||
.test(
|
return false;
|
||||||
"Check-color-exists",
|
|
||||||
"ERR_QUEUE_COLOR_ALREADY_EXISTS",
|
|
||||||
async value => {
|
|
||||||
if (value) {
|
|
||||||
const queueWithSameColor = await Queue.findOne({
|
|
||||||
where: { color: value }
|
|
||||||
});
|
|
||||||
return !queueWithSameColor;
|
|
||||||
}
|
}
|
||||||
return false;
|
)
|
||||||
}
|
});
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await queueSchema.validate({ color, name });
|
await queueSchema.validate({ color, name });
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
throw new AppError(err.message);
|
throw new AppError(err.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
const queue = await Queue.create(queueData);
|
const queue = await Queue.create(queueData);
|
||||||
|
|
||||||
return queue;
|
// const { id, greetingMessage } = queue;
|
||||||
|
// await set(`queue:${id}`, { id, name, greetingMessage });
|
||||||
|
|
||||||
|
return queue;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('===> Error on CreateQueueService.ts file: \n', error)
|
console.error("===> Error on CreateQueueService.ts file: \n", error);
|
||||||
throw new AppError(error.message);
|
throw new AppError(error.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default CreateQueueService;
|
export default CreateQueueService;
|
||||||
|
|
|
@ -3,6 +3,7 @@ import * as Yup from "yup";
|
||||||
import AppError from "../../errors/AppError";
|
import AppError from "../../errors/AppError";
|
||||||
import Queue from "../../models/Queue";
|
import Queue from "../../models/Queue";
|
||||||
import ShowQueueService from "./ShowQueueService";
|
import ShowQueueService from "./ShowQueueService";
|
||||||
|
import { set } from "../../helpers/RedisClient"
|
||||||
|
|
||||||
interface QueueData {
|
interface QueueData {
|
||||||
name?: string;
|
name?: string;
|
||||||
|
@ -14,9 +15,7 @@ const UpdateQueueService = async (
|
||||||
queueId: number | string,
|
queueId: number | string,
|
||||||
queueData: QueueData
|
queueData: QueueData
|
||||||
): Promise<Queue> => {
|
): Promise<Queue> => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
const { color, name } = queueData;
|
const { color, name } = queueData;
|
||||||
|
|
||||||
const queueSchema = Yup.object().shape({
|
const queueSchema = Yup.object().shape({
|
||||||
|
@ -30,7 +29,7 @@ const UpdateQueueService = async (
|
||||||
const queueWithSameName = await Queue.findOne({
|
const queueWithSameName = await Queue.findOne({
|
||||||
where: { name: value, id: { [Op.not]: queueId } }
|
where: { name: value, id: { [Op.not]: queueId } }
|
||||||
});
|
});
|
||||||
|
|
||||||
return !queueWithSameName;
|
return !queueWithSameName;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -59,24 +58,25 @@ const UpdateQueueService = async (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await queueSchema.validate({ color, name });
|
await queueSchema.validate({ color, name });
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
throw new AppError(err.message);
|
throw new AppError(err.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
const queue = await ShowQueueService(queueId);
|
const queue = await ShowQueueService(queueId);
|
||||||
|
|
||||||
await queue.update(queueData);
|
await queue.update(queueData);
|
||||||
|
|
||||||
|
// const { id, greetingMessage } = queue;
|
||||||
|
// await set(`queue:${id}`, { id, name, greetingMessage });
|
||||||
|
|
||||||
return queue;
|
return queue;
|
||||||
|
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('===> Error on UpdateQueueService.ts file: \n', error)
|
console.error("===> Error on UpdateQueueService.ts file: \n", error);
|
||||||
throw new AppError(error.message);
|
throw new AppError(error.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default UpdateQueueService;
|
export default UpdateQueueService;
|
||||||
|
|
|
@ -29,7 +29,8 @@ const FindOrCreateTicketServiceBot = async (
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const { queues, greetingMessage } = await ShowWhatsAppService(whatsappId);
|
const { queues, greetingMessage, phoneNumberId } =
|
||||||
|
await ShowWhatsAppService(whatsappId);
|
||||||
|
|
||||||
|
|
||||||
//Habilitar esse caso queira usar o bot
|
//Habilitar esse caso queira usar o bot
|
||||||
|
@ -102,12 +103,13 @@ const FindOrCreateTicketServiceBot = async (
|
||||||
}
|
}
|
||||||
|
|
||||||
ticket = await Ticket.create({
|
ticket = await Ticket.create({
|
||||||
contactId: groupContact ? groupContact.id : contact.id,
|
contactId: groupContact ? groupContact.id : contact.id,
|
||||||
status: status,
|
status: status,
|
||||||
userId: botInfo.userIdBot,
|
userId: botInfo.userIdBot,
|
||||||
isGroup: !!groupContact,
|
isGroup: !!groupContact,
|
||||||
unreadMessages,
|
unreadMessages,
|
||||||
whatsappId
|
whatsappId,
|
||||||
|
phoneNumberId
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy')
|
console.log('yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy')
|
||||||
|
|
|
@ -7,14 +7,17 @@ import Queue from "../../models/Queue";
|
||||||
import Message from "../../models/Message";
|
import Message from "../../models/Message";
|
||||||
import { userInfo } from "os";
|
import { userInfo } from "os";
|
||||||
|
|
||||||
import { Op, where } from "sequelize";
|
import { Op, QueryTypes, where } from "sequelize";
|
||||||
|
|
||||||
import { Sequelize } from "sequelize";
|
import { Sequelize } from "sequelize";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
|
const dbConfig = require("../../config/database");
|
||||||
|
const sequelize = new Sequelize(dbConfig);
|
||||||
|
|
||||||
import { startOfDay, endOfDay, parseISO, getDate } from "date-fns";
|
import { startOfDay, endOfDay, parseISO, getDate } from "date-fns";
|
||||||
import { string } from "yup/lib/locale";
|
import { string } from "yup/lib/locale";
|
||||||
import Whatsapp from "../../models/Whatsapp";
|
import Whatsapp from "../../models/Whatsapp";
|
||||||
|
import Query from "mysql2/typings/mysql/lib/protocol/sequences/Query"
|
||||||
|
|
||||||
interface Request {
|
interface Request {
|
||||||
userId: string | number;
|
userId: string | number;
|
||||||
|
@ -41,43 +44,41 @@ const ShowTicketReport = async ({
|
||||||
queueId
|
queueId
|
||||||
}: Request): Promise<Response> => {
|
}: Request): Promise<Response> => {
|
||||||
let where_clause: any = {};
|
let where_clause: any = {};
|
||||||
// let where_clause_msg: any = {};
|
let query = "";
|
||||||
|
|
||||||
if (userId !== "0") {
|
if (userId !== "0") {
|
||||||
where_clause.userid = userId;
|
where_clause.userid = userId;
|
||||||
|
query = `AND t.userId = ${userId}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (createdOrUpdated === "updated") {
|
|
||||||
where_clause = {
|
|
||||||
...where_clause,
|
|
||||||
updatedAt: {
|
|
||||||
[Op.gte]: startDate + " 00:00:00.000000",
|
|
||||||
[Op.lte]: endDate + " 23:59:59.999999"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (createdOrUpdated === "created") {
|
|
||||||
where_clause = {
|
|
||||||
...where_clause,
|
|
||||||
createdAt: {
|
|
||||||
[Op.gte]: startDate + " 00:00:00.000000",
|
|
||||||
[Op.lte]: endDate + " 23:59:59.999999"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
let { userid, ...where_clause_msg } = where_clause;
|
|
||||||
|
|
||||||
if (queueId) {
|
if (queueId) {
|
||||||
where_clause.queueId = queueId;
|
where_clause.queueId = queueId;
|
||||||
|
query = `AND t.queueId = ${queueId}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const limit = 40;
|
const limit = 40;
|
||||||
const offset = limit * (+pageNumber - 1);
|
const offset = limit * (+pageNumber - 1);
|
||||||
|
|
||||||
|
const createdAtOrUpdatedAt =
|
||||||
|
createdOrUpdated == "created" ? "createdAt" : "updatedAt";
|
||||||
|
|
||||||
|
const _ticketsId = await sequelize.query(
|
||||||
|
`SELECT t.id
|
||||||
|
FROM Tickets t
|
||||||
|
INNER JOIN (
|
||||||
|
SELECT DISTINCT ticketId
|
||||||
|
FROM Messages
|
||||||
|
WHERE ${createdAtOrUpdatedAt} >= '${startDate} 00:00:00' AND ${createdAtOrUpdatedAt} <= '${endDate} 23:59:59'
|
||||||
|
) AS m ON m.ticketId = t.id ${query};`,
|
||||||
|
{ type: QueryTypes.SELECT }
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log('QUERY: ', query)
|
||||||
|
|
||||||
const { count, rows: tickets } = await Ticket.findAndCountAll({
|
const { count, rows: tickets } = await Ticket.findAndCountAll({
|
||||||
where: where_clause,
|
where: {
|
||||||
|
id: { [Op.in]: _ticketsId.map((t: any) => t.id) }
|
||||||
|
},
|
||||||
limit,
|
limit,
|
||||||
offset,
|
offset,
|
||||||
|
|
||||||
|
@ -108,7 +109,6 @@ const ShowTicketReport = async ({
|
||||||
model: Message,
|
model: Message,
|
||||||
required: true,
|
required: true,
|
||||||
separate: true,
|
separate: true,
|
||||||
where: where_clause_msg ,
|
|
||||||
|
|
||||||
attributes: [
|
attributes: [
|
||||||
"body",
|
"body",
|
||||||
|
@ -143,10 +143,10 @@ const ShowTicketReport = async ({
|
||||||
model: Whatsapp,
|
model: Whatsapp,
|
||||||
attributes: ["name"]
|
attributes: ["name"]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
order: [["updatedAt", "DESC"]]
|
order: [["updatedAt", "DESC"]]
|
||||||
});
|
});
|
||||||
|
|
||||||
const hasMore = count > offset + tickets.length;
|
const hasMore = count > offset + tickets.length;
|
||||||
|
|
||||||
if (!tickets) {
|
if (!tickets) {
|
||||||
|
|
|
@ -1,27 +1,60 @@
|
||||||
|
import axios from "axios";
|
||||||
import AppError from "../../errors/AppError";
|
import AppError from "../../errors/AppError";
|
||||||
import endPointQuery from "../../helpers/EndPointQuery";
|
import endPointQuery from "../../helpers/EndPointQuery";
|
||||||
import GetDefaultWhatsApp from "../../helpers/GetDefaultWhatsApp";
|
import GetDefaultWhatsApp from "../../helpers/GetDefaultWhatsApp";
|
||||||
import { getWbot } from "../../libs/wbot";
|
import { getWbot } from "../../libs/wbot";
|
||||||
|
|
||||||
const CheckIsValidContact = async (number: string, ignoreThrow?:boolean): Promise<any> => {
|
const CheckIsValidContact = async (
|
||||||
|
number: string,
|
||||||
|
ignoreThrow?: boolean
|
||||||
|
): Promise<any> => {
|
||||||
|
const defaultWhatsapp = await GetDefaultWhatsApp({
|
||||||
|
ignoreNoWhatsappFound: true
|
||||||
|
});
|
||||||
|
|
||||||
const defaultWhatsapp = await GetDefaultWhatsApp({});
|
let isValidNumber;
|
||||||
|
|
||||||
const wbot_url = await getWbot(defaultWhatsapp.id);
|
if (defaultWhatsapp) {
|
||||||
|
const wbot_url = await getWbot(defaultWhatsapp.id);
|
||||||
|
|
||||||
const isValidNumber = await endPointQuery(`${wbot_url}/api/validate`, { mobile: `${number}`, })
|
let { data } = await endPointQuery(`${wbot_url}/api/validate`, {
|
||||||
|
mobile: `${number}`
|
||||||
|
});
|
||||||
|
|
||||||
if(ignoreThrow) return isValidNumber?.data?.number;
|
if (data?.isValid) {
|
||||||
|
isValidNumber = data;
|
||||||
// console.log('isValidNumber.data.number: ', isValidNumber.data.number)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
let _status: any;
|
||||||
|
|
||||||
// const isValidNumber = await wbot.isRegisteredUser(`${number}@c.us`);
|
if (!isValidNumber) {
|
||||||
|
|
||||||
if (!isValidNumber || isValidNumber && !isValidNumber.data.isValid) {
|
const { data, status } = await axios.post(
|
||||||
|
`${process.env.WHATS_NUMBER_VALIDATOR_URL}/api/validate`,
|
||||||
|
{ mobile: number },
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
isValidNumber = data;
|
||||||
|
_status = status;
|
||||||
|
}
|
||||||
|
if (ignoreThrow) return isValidNumber?.number;
|
||||||
|
|
||||||
|
console.log('_status: ', _status)
|
||||||
|
|
||||||
|
if (_status && _status == 422) throw new AppError("ERR_NO_WAPP_FOUND");
|
||||||
|
|
||||||
|
if (!isValidNumber || (isValidNumber && !isValidNumber.isValid)) {
|
||||||
throw new AppError("invalidNumber");
|
throw new AppError("invalidNumber");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isValidNumber && isValidNumber?.isValid) return isValidNumber.number;
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
if (err.message === "invalidNumber") {
|
if (err.message === "invalidNumber") {
|
||||||
throw new AppError("ERR_WAPP_INVALID_CONTACT");
|
throw new AppError("ERR_WAPP_INVALID_CONTACT");
|
||||||
|
@ -29,10 +62,6 @@ const CheckIsValidContact = async (number: string, ignoreThrow?:boolean): Promis
|
||||||
|
|
||||||
throw new AppError("ERR_WAPP_CHECK_CONTACT");
|
throw new AppError("ERR_WAPP_CHECK_CONTACT");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isValidNumber && isValidNumber.data.isValid)
|
|
||||||
return isValidNumber.data.number
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default CheckIsValidContact;
|
export default CheckIsValidContact;
|
||||||
|
|
|
@ -1,23 +1,47 @@
|
||||||
|
import axios from "axios";
|
||||||
import endPointQuery from "../../helpers/EndPointQuery";
|
import endPointQuery from "../../helpers/EndPointQuery";
|
||||||
import GetDefaultWhatsApp from "../../helpers/GetDefaultWhatsApp";
|
import GetDefaultWhatsApp from "../../helpers/GetDefaultWhatsApp";
|
||||||
import { getWbot } from "../../libs/wbot";
|
import { getWbot } from "../../libs/wbot";
|
||||||
|
|
||||||
const GetProfilePicUrl = async (number: string): Promise<any> => {
|
const GetProfilePicUrl = async (number: string): Promise<any> => {
|
||||||
|
const defaultWhatsapp = await GetDefaultWhatsApp({
|
||||||
|
ignoreNoWhatsappFound: true
|
||||||
|
});
|
||||||
|
|
||||||
|
let profilePicUrl;
|
||||||
|
|
||||||
const defaultWhatsapp = await GetDefaultWhatsApp({});
|
if (defaultWhatsapp) {
|
||||||
|
const wbot_url = await getWbot(defaultWhatsapp.id);
|
||||||
|
|
||||||
const wbot_url = await getWbot(defaultWhatsapp.id);
|
const {data} = await endPointQuery(`${wbot_url}/api/GetProfilePicUrl`, {
|
||||||
|
number: `${number}`
|
||||||
|
});
|
||||||
|
|
||||||
let profilePicUrl = await endPointQuery(`${wbot_url}/api/GetProfilePicUrl`, { number: `${number}`, })
|
if (data?.data) {
|
||||||
|
profilePicUrl = data.data;
|
||||||
console.log('profilePicUrl.data.data: ', profilePicUrl.data.data)
|
}
|
||||||
|
|
||||||
if (profilePicUrl && profilePicUrl.data.data) {
|
|
||||||
return profilePicUrl.data.data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!profilePicUrl) {
|
||||||
|
const { data } = await axios.post(
|
||||||
|
`${process.env.WHATS_NUMBER_VALIDATOR_URL}/api/GetProfilePicUrl`,
|
||||||
|
{ number },
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
profilePicUrl = data?.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (profilePicUrl) {
|
||||||
|
return profilePicUrl;
|
||||||
|
}
|
||||||
|
} catch (error) {}
|
||||||
|
|
||||||
return null
|
return null;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default GetProfilePicUrl;
|
export default GetProfilePicUrl;
|
||||||
|
|
|
@ -92,13 +92,14 @@ import {
|
||||||
createObject,
|
createObject,
|
||||||
findByContain,
|
findByContain,
|
||||||
findObject,
|
findObject,
|
||||||
get
|
get,
|
||||||
|
getSimple
|
||||||
} from "../../helpers/RedisClient";
|
} from "../../helpers/RedisClient";
|
||||||
import FindOrCreateTicketServiceBot from "../TicketServices/FindOrCreateTicketServiceBot";
|
import FindOrCreateTicketServiceBot from "../TicketServices/FindOrCreateTicketServiceBot";
|
||||||
import ShowTicketService from "../TicketServices/ShowTicketService";
|
import ShowTicketService from "../TicketServices/ShowTicketService";
|
||||||
import ShowQueuesByUser from "../UserServices/ShowQueuesByUser";
|
import ShowQueuesByUser from "../UserServices/ShowQueuesByUser";
|
||||||
import ListWhatsappQueuesByUserQueue from "../UserServices/ListWhatsappQueuesByUserQueue";
|
import ListWhatsappQueuesByUserQueue from "../UserServices/ListWhatsappQueuesByUserQueue";
|
||||||
import CreateContactService from "../ContactServices/CreateContactService"
|
import CreateContactService from "../ContactServices/CreateContactService";
|
||||||
|
|
||||||
var lst: any[] = getWhatsappIds();
|
var lst: any[] = getWhatsappIds();
|
||||||
|
|
||||||
|
@ -175,9 +176,14 @@ const verifyMediaMessage = async (
|
||||||
mediaUrl: media.filename,
|
mediaUrl: media.filename,
|
||||||
mediaType: media.mimetype.split("/")[0],
|
mediaType: media.mimetype.split("/")[0],
|
||||||
quotedMsgId: quotedMsg,
|
quotedMsgId: quotedMsg,
|
||||||
phoneNumberId: msg?.phoneNumberId
|
phoneNumberId: msg?.phoneNumberId,
|
||||||
|
fromAgent: false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (msg?.fromMe) {
|
||||||
|
messageData = { ...messageData, fromAgent: true };
|
||||||
|
}
|
||||||
|
|
||||||
if (!ticket?.phoneNumberId) {
|
if (!ticket?.phoneNumberId) {
|
||||||
if (!media.filename) {
|
if (!media.filename) {
|
||||||
const ext = media.mimetype.split("/")[1].split(";")[0];
|
const ext = media.mimetype.split("/")[1].split(";")[0];
|
||||||
|
@ -280,18 +286,33 @@ const verifyMessage = async (
|
||||||
contact: Contact,
|
contact: Contact,
|
||||||
quotedMsg?: any
|
quotedMsg?: any
|
||||||
) => {
|
) => {
|
||||||
const messageData = {
|
let messageData = {
|
||||||
id: msg.id.id,
|
id: msg.id.id,
|
||||||
ticketId: ticket.id,
|
ticketId: ticket.id,
|
||||||
contactId: msg.fromMe ? undefined : contact.id,
|
contactId: msg.fromMe ? undefined : contact.id,
|
||||||
body: msg.body,
|
body: msg.body,
|
||||||
fromMe: msg.fromMe,
|
fromMe: msg.fromMe,
|
||||||
|
fromAgent: false,
|
||||||
mediaType: msg.type,
|
mediaType: msg.type,
|
||||||
read: msg.fromMe,
|
read: msg.fromMe,
|
||||||
quotedMsgId: quotedMsg,
|
quotedMsgId: quotedMsg,
|
||||||
phoneNumberId: msg?.phoneNumberId
|
phoneNumberId: msg?.phoneNumberId
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (msg?.fromMe) {
|
||||||
|
const botInfo = await BotIsOnQueue("botqueue");
|
||||||
|
|
||||||
|
if (botInfo.isOnQueue) {
|
||||||
|
const ura: any = await get({ key: "ura" });
|
||||||
|
|
||||||
|
if (ura && !ura.includes(JSON.stringify(msg?.body))) {
|
||||||
|
messageData = { ...messageData, fromAgent: true };
|
||||||
|
}
|
||||||
|
} else if (msg?.body?.trim().length > 0 && !/\u200e/.test(msg.body[0])) {
|
||||||
|
messageData = { ...messageData, fromAgent: true };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await ticket.update({ lastMessage: msg.body });
|
await ticket.update({ lastMessage: msg.body });
|
||||||
|
|
||||||
await CreateMessageService({ messageData });
|
await CreateMessageService({ messageData });
|
||||||
|
@ -318,13 +339,14 @@ const verifyQueue = async (
|
||||||
selectedOption = 1;
|
selectedOption = 1;
|
||||||
choosenQueue = queues[+selectedOption - 1];
|
choosenQueue = queues[+selectedOption - 1];
|
||||||
} else {
|
} else {
|
||||||
selectedOption = msg.body;
|
selectedOption = msg?.body;
|
||||||
|
|
||||||
//////////////// EXTRAIR APENAS O NÚMERO ///////////////////
|
if (selectedOption && selectedOption.trim().length > 0) {
|
||||||
selectedOption = selectedOption.replace(/[^1-9]/g, "");
|
//////////////// EXTRAIR APENAS O NÚMERO ///////////////////
|
||||||
///////////////////////////////////
|
selectedOption = selectedOption.replace(/[^1-9]/g, "");
|
||||||
|
///////////////////////////////////
|
||||||
choosenQueue = queues[+selectedOption - 1];
|
choosenQueue = queues[+selectedOption - 1];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (choosenQueue) {
|
if (choosenQueue) {
|
||||||
|
@ -348,13 +370,14 @@ const verifyQueue = async (
|
||||||
ticketId: ticket.id
|
ticketId: ticket.id
|
||||||
});
|
});
|
||||||
|
|
||||||
const data = await get("ura");
|
const data = await get({ key: "ura", parse: true });
|
||||||
|
|
||||||
await createObject({
|
await createObject({
|
||||||
whatsappId: `${ticket.whatsappId}`,
|
whatsappId: `${ticket.whatsappId}`,
|
||||||
contactId: `${ticket.contactId}`,
|
contactId: `${ticket.contactId}`,
|
||||||
identifier: "ura",
|
identifier: "ura",
|
||||||
value: data[1].id
|
value: data[1].id,
|
||||||
|
history: `|${data[1].id}`
|
||||||
});
|
});
|
||||||
|
|
||||||
botSendMessage(ticket, data[1].value);
|
botSendMessage(ticket, data[1].value);
|
||||||
|
@ -505,9 +528,7 @@ const transferTicket = async (
|
||||||
ticket: Ticket,
|
ticket: Ticket,
|
||||||
sendGreetingMessage?: boolean
|
sendGreetingMessage?: boolean
|
||||||
) => {
|
) => {
|
||||||
const botInfo = await BotIsOnQueue("botqueue");
|
const botInfo = await BotIsOnQueue("botqueue");
|
||||||
|
|
||||||
console.log("kkkkkkkkkkkkkkkkkkkkk queueName: ", queueName);
|
|
||||||
|
|
||||||
const queuesWhatsGreetingMessage = await queuesOutBot(
|
const queuesWhatsGreetingMessage = await queuesOutBot(
|
||||||
wbot,
|
wbot,
|
||||||
|
@ -610,7 +631,7 @@ const handleMessage = async (
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isValidMsg(msg)) {
|
if (!isValidMsg(msg)) {
|
||||||
return;
|
return;
|
||||||
|
@ -780,33 +801,33 @@ const handleMessage = async (
|
||||||
await verifyQueue(wbot, msg, ticket, contact);
|
await verifyQueue(wbot, msg, ticket, contact);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg.type === "vcard") {
|
if (msg.type === "vcard") {
|
||||||
try {
|
try {
|
||||||
const array = msg.body.split("\n");
|
const array = msg.body.split("\n");
|
||||||
const obj = [];
|
const obj = [];
|
||||||
let contact = "";
|
let contact = "";
|
||||||
for (let index = 0; index < array.length; index++) {
|
for (let index = 0; index < array.length; index++) {
|
||||||
const v = array[index];
|
const v = array[index];
|
||||||
const values = v.split(":");
|
const values = v.split(":");
|
||||||
for (let ind = 0; ind < values.length; ind++) {
|
for (let ind = 0; ind < values.length; ind++) {
|
||||||
if (values[ind].indexOf("+") !== -1) {
|
if (values[ind].indexOf("+") !== -1) {
|
||||||
obj.push({ number: values[ind] });
|
obj.push({ number: values[ind] });
|
||||||
}
|
}
|
||||||
if (values[ind].indexOf("FN") !== -1) {
|
if (values[ind].indexOf("FN") !== -1) {
|
||||||
contact = values[ind + 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);
|
|
||||||
}
|
}
|
||||||
|
for await (const ob of obj) {
|
||||||
|
const cont = await CreateContactService({
|
||||||
|
name: contact,
|
||||||
|
number: ob.number.replace(/\D/g, "")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const botInfo = await BotIsOnQueue("botqueue");
|
const botInfo = await BotIsOnQueue("botqueue");
|
||||||
|
|
||||||
|
@ -820,7 +841,7 @@ const handleMessage = async (
|
||||||
ticket.status == "pending" ||
|
ticket.status == "pending" ||
|
||||||
ticket.status == "queueChoice")
|
ticket.status == "queueChoice")
|
||||||
) {
|
) {
|
||||||
const filteredUsers = await findByContain("user:*", "name", msg?.body);
|
const filteredUsers = await findByContain("user:*", "name", msg?.body);
|
||||||
|
|
||||||
if (filteredUsers && filteredUsers.length > 0) {
|
if (filteredUsers && filteredUsers.length > 0) {
|
||||||
if (botInfo.isOnQueue) {
|
if (botInfo.isOnQueue) {
|
||||||
|
@ -964,7 +985,7 @@ const handleMessage = async (
|
||||||
|
|
||||||
const menu = async (userTyped: string, whatsappId: any, contactId: any) => {
|
const menu = async (userTyped: string, whatsappId: any, contactId: any) => {
|
||||||
let lastId = await findObject(whatsappId, contactId, "ura");
|
let lastId = await findObject(whatsappId, contactId, "ura");
|
||||||
const data: any = await get("ura");
|
const data: any = await get({ key: "ura", parse: true });
|
||||||
|
|
||||||
console.log("lastId[0]: ", lastId[0]);
|
console.log("lastId[0]: ", lastId[0]);
|
||||||
|
|
||||||
|
@ -973,7 +994,8 @@ const menu = async (userTyped: string, whatsappId: any, contactId: any) => {
|
||||||
whatsappId,
|
whatsappId,
|
||||||
contactId,
|
contactId,
|
||||||
identifier: "ura",
|
identifier: "ura",
|
||||||
value: data[1].id
|
value: data[1].id,
|
||||||
|
history: `|${data[1].id}`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -983,7 +1005,7 @@ const menu = async (userTyped: string, whatsappId: any, contactId: any) => {
|
||||||
|
|
||||||
if (
|
if (
|
||||||
lastId &&
|
lastId &&
|
||||||
lastId.length == 4 &&
|
(lastId.length == 4 || lastId.length == 5) &&
|
||||||
lastId[3] &&
|
lastId[3] &&
|
||||||
lastId[3].trim().length > 0
|
lastId[3].trim().length > 0
|
||||||
) {
|
) {
|
||||||
|
@ -993,23 +1015,49 @@ const menu = async (userTyped: string, whatsappId: any, contactId: any) => {
|
||||||
o.value.toLowerCase() == userTyped.toLowerCase()
|
o.value.toLowerCase() == userTyped.toLowerCase()
|
||||||
);
|
);
|
||||||
|
|
||||||
// TEST DEL
|
if (!option && userTyped != "0" && userTyped != "#") {
|
||||||
console.log("OPTION: ", option);
|
|
||||||
|
|
||||||
if (!option && userTyped != "0") {
|
|
||||||
if (!existSubMenu()) {
|
if (!existSubMenu()) {
|
||||||
|
|
||||||
const response = await mainOptionsMenu(userTyped);
|
const response = await mainOptionsMenu(userTyped);
|
||||||
if (response) return response;
|
if (response) return response;
|
||||||
else {
|
else {
|
||||||
console.log("kkkkkkkkkkkkkkkkkkk");
|
let uraOptionSelected = await findObject(
|
||||||
await createObject({
|
|
||||||
whatsappId,
|
whatsappId,
|
||||||
contactId,
|
contactId,
|
||||||
identifier: "ura",
|
"ura"
|
||||||
value: data[1].id
|
);
|
||||||
});
|
|
||||||
|
uraOptionSelected = uraOptionSelected[4].split("|");
|
||||||
|
|
||||||
return data[1];
|
if (uraOptionSelected.length == 1) {
|
||||||
|
await createObject({
|
||||||
|
whatsappId,
|
||||||
|
contactId,
|
||||||
|
identifier: "ura",
|
||||||
|
value: data[1].id,
|
||||||
|
history: `|${data[1].id}`
|
||||||
|
});
|
||||||
|
|
||||||
|
return data[1];
|
||||||
|
} else if (uraOptionSelected.length > 1) {
|
||||||
|
const id = uraOptionSelected[uraOptionSelected.length - 1];
|
||||||
|
|
||||||
|
console.log(" ID FROM THE MENU/SUBMENU: ", id);
|
||||||
|
|
||||||
|
const history = await historyUra(whatsappId, contactId, id);
|
||||||
|
|
||||||
|
await createObject({
|
||||||
|
whatsappId,
|
||||||
|
contactId,
|
||||||
|
identifier: "ura",
|
||||||
|
value: id,
|
||||||
|
history
|
||||||
|
});
|
||||||
|
|
||||||
|
let response: any = data.find((o: any) => o.id == id);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1017,19 +1065,16 @@ const menu = async (userTyped: string, whatsappId: any, contactId: any) => {
|
||||||
|
|
||||||
if (option) {
|
if (option) {
|
||||||
let response: any = data.find((o: any) => o.idmaster == option.id);
|
let response: any = data.find((o: any) => o.idmaster == option.id);
|
||||||
|
console.log(" RESPONSE OPTION: ", response, " | OPTION: ", option);
|
||||||
|
|
||||||
console.log(
|
let history: any = await historyUra(whatsappId, contactId, response.id);
|
||||||
"RRRRRRRRRRRRRRRRRRRRRRRRRRRRR response: ",
|
|
||||||
response,
|
|
||||||
" | option: ",
|
|
||||||
option
|
|
||||||
);
|
|
||||||
|
|
||||||
await createObject({
|
await createObject({
|
||||||
whatsappId,
|
whatsappId,
|
||||||
contactId,
|
contactId,
|
||||||
identifier: "ura",
|
identifier: "ura",
|
||||||
value: response.id
|
value: response.id,
|
||||||
|
history
|
||||||
});
|
});
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
|
@ -1038,26 +1083,42 @@ const menu = async (userTyped: string, whatsappId: any, contactId: any) => {
|
||||||
whatsappId,
|
whatsappId,
|
||||||
contactId,
|
contactId,
|
||||||
identifier: "ura",
|
identifier: "ura",
|
||||||
value: data[1].id
|
value: data[1].id,
|
||||||
|
history: `|${data[1].id}`
|
||||||
});
|
});
|
||||||
|
|
||||||
return data[1];
|
return data[1];
|
||||||
} else {
|
} else if (userTyped == "#") {
|
||||||
console.log("INVALID SEARCH");
|
let uraOptionSelected = await findObject(whatsappId, contactId, "ura");
|
||||||
|
|
||||||
let response = await existSubMenu();
|
uraOptionSelected = uraOptionSelected[4].split("|").filter(Boolean);
|
||||||
if (response) return response;
|
|
||||||
|
|
||||||
return {
|
let id = uraOptionSelected[0];
|
||||||
value: data.find((o: any) => o.id == lastId[3])?.value
|
|
||||||
};
|
|
||||||
|
|
||||||
// return {
|
let history = `|${uraOptionSelected[0]}`;
|
||||||
// value: `Você digitou uma opçao inválida!\n\n${
|
|
||||||
// data.find((o: any) => o.id == lastId[3])?.value
|
if (uraOptionSelected.length > 1) {
|
||||||
// }\n\nDigite 0 para voltar ao menu `
|
const idRemove = uraOptionSelected[uraOptionSelected.length - 1];
|
||||||
// };
|
|
||||||
}
|
history = await historyUra(whatsappId, contactId, idRemove, true);
|
||||||
|
|
||||||
|
const lstIds = history.split("|").filter(Boolean);
|
||||||
|
|
||||||
|
id = lstIds[lstIds.length - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
await createObject({
|
||||||
|
whatsappId,
|
||||||
|
contactId,
|
||||||
|
identifier: "ura",
|
||||||
|
value: id,
|
||||||
|
history
|
||||||
|
});
|
||||||
|
|
||||||
|
let response: any = data.find((o: any) => o.id == id);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function existSubMenu() {
|
function existSubMenu() {
|
||||||
|
@ -1069,18 +1130,29 @@ const menu = async (userTyped: string, whatsappId: any, contactId: any) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function mainOptionsMenu(userTyped: any) {
|
async function mainOptionsMenu(userTyped: any) {
|
||||||
|
let currentMenu = await findObject(whatsappId, contactId, "ura");
|
||||||
|
|
||||||
|
const menuValues = data
|
||||||
|
.filter((m: any) => m.idmaster == currentMenu[3])
|
||||||
|
.map((m: any) => m.value);
|
||||||
|
|
||||||
let menuOption = data.find(
|
let menuOption = data.find(
|
||||||
(o: any) => o.value.toLowerCase() == userTyped.toLowerCase()
|
(o: any) =>
|
||||||
|
o.value.toLowerCase() == userTyped.toLowerCase() &&
|
||||||
|
menuValues.includes(userTyped.toLowerCase())
|
||||||
);
|
);
|
||||||
console.log("============> menuOption OPTION: ", menuOption);
|
|
||||||
if (menuOption) {
|
if (menuOption) {
|
||||||
let response = data.find((o: any) => o.idmaster == menuOption.id);
|
let response = data.find((o: any) => o.idmaster == menuOption.id);
|
||||||
if (response) {
|
if (response) {
|
||||||
|
let history = await historyUra(whatsappId, contactId, response.id);
|
||||||
|
|
||||||
await createObject({
|
await createObject({
|
||||||
whatsappId,
|
whatsappId,
|
||||||
contactId,
|
contactId,
|
||||||
identifier: "ura",
|
identifier: "ura",
|
||||||
value: response.id
|
value: response.id,
|
||||||
|
history
|
||||||
});
|
});
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
|
@ -1189,6 +1261,31 @@ export {
|
||||||
mediaTypeWhatsappOfficial,
|
mediaTypeWhatsappOfficial,
|
||||||
botSendMessage
|
botSendMessage
|
||||||
};
|
};
|
||||||
|
async function historyUra(
|
||||||
|
whatsappId: any,
|
||||||
|
contactId: any,
|
||||||
|
id: any,
|
||||||
|
remove?: boolean
|
||||||
|
) {
|
||||||
|
let uraOptionSelected = await findObject(whatsappId, contactId, "ura");
|
||||||
|
let history = "";
|
||||||
|
|
||||||
|
console.log("SELECED OPTION uraOptionSelected: ", uraOptionSelected);
|
||||||
|
|
||||||
|
if (remove) {
|
||||||
|
return uraOptionSelected[4]?.replace(`|${id}`, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uraOptionSelected && uraOptionSelected.length == 5) {
|
||||||
|
if (!uraOptionSelected[4]?.includes(`${id}`))
|
||||||
|
history += `${uraOptionSelected[4]}|${id}`;
|
||||||
|
else history = `${uraOptionSelected[4]}`;
|
||||||
|
} else {
|
||||||
|
history = `|${id}`;
|
||||||
|
}
|
||||||
|
return history;
|
||||||
|
}
|
||||||
|
|
||||||
async function whatsappInfo(whatsappId: string | number) {
|
async function whatsappInfo(whatsappId: string | number) {
|
||||||
return await Whatsapp.findByPk(whatsappId);
|
return await Whatsapp.findByPk(whatsappId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ interface WhatsappData {
|
||||||
greetingMessage?: string;
|
greetingMessage?: string;
|
||||||
farewellMessage?: string;
|
farewellMessage?: string;
|
||||||
queueIds?: number[];
|
queueIds?: number[];
|
||||||
|
number?:string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Request {
|
interface Request {
|
||||||
|
@ -52,6 +53,7 @@ const UpdateWhatsAppService = async ({
|
||||||
phoneNumberId,
|
phoneNumberId,
|
||||||
wabaId,
|
wabaId,
|
||||||
isOfficial,
|
isOfficial,
|
||||||
|
number,
|
||||||
url,
|
url,
|
||||||
urlApi,
|
urlApi,
|
||||||
session,
|
session,
|
||||||
|
@ -116,6 +118,7 @@ const UpdateWhatsAppService = async ({
|
||||||
isOfficial,
|
isOfficial,
|
||||||
phoneNumberId,
|
phoneNumberId,
|
||||||
wabaId,
|
wabaId,
|
||||||
|
number,
|
||||||
classification
|
classification
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
import React, { useState, useEffect, useRef } from "react";
|
import React, { useState, useEffect, useRef } from "react"
|
||||||
|
|
||||||
import * as Yup from "yup";
|
import * as Yup from "yup"
|
||||||
import { Formik, FieldArray, Form, Field } from "formik";
|
import { Formik, FieldArray, Form, Field } from "formik"
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify"
|
||||||
|
|
||||||
import { makeStyles } from "@material-ui/core/styles";
|
import { makeStyles } from "@material-ui/core/styles"
|
||||||
import { green } from "@material-ui/core/colors";
|
import { green } from "@material-ui/core/colors"
|
||||||
import Button from "@material-ui/core/Button";
|
import Button from "@material-ui/core/Button"
|
||||||
import TextField from "@material-ui/core/TextField";
|
import TextField from "@material-ui/core/TextField"
|
||||||
import Dialog from "@material-ui/core/Dialog";
|
import Dialog from "@material-ui/core/Dialog"
|
||||||
import DialogActions from "@material-ui/core/DialogActions";
|
import DialogActions from "@material-ui/core/DialogActions"
|
||||||
import DialogContent from "@material-ui/core/DialogContent";
|
import DialogContent from "@material-ui/core/DialogContent"
|
||||||
import DialogTitle from "@material-ui/core/DialogTitle";
|
import DialogTitle from "@material-ui/core/DialogTitle"
|
||||||
import Typography from "@material-ui/core/Typography";
|
import Typography from "@material-ui/core/Typography"
|
||||||
import IconButton from "@material-ui/core/IconButton";
|
import IconButton from "@material-ui/core/IconButton"
|
||||||
import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline";
|
import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline"
|
||||||
import CircularProgress from "@material-ui/core/CircularProgress";
|
import CircularProgress from "@material-ui/core/CircularProgress"
|
||||||
|
|
||||||
import { i18n } from "../../translate/i18n";
|
import { i18n } from "../../translate/i18n"
|
||||||
|
|
||||||
import api from "../../services/api";
|
import api from "../../services/api"
|
||||||
import toastError from "../../errors/toastError";
|
import toastError from "../../errors/toastError"
|
||||||
|
|
||||||
const useStyles = makeStyles(theme => ({
|
const useStyles = makeStyles(theme => ({
|
||||||
root: {
|
root: {
|
||||||
|
@ -50,7 +50,7 @@ const useStyles = makeStyles(theme => ({
|
||||||
marginTop: -12,
|
marginTop: -12,
|
||||||
marginLeft: -12,
|
marginLeft: -12,
|
||||||
},
|
},
|
||||||
}));
|
}))
|
||||||
|
|
||||||
const ContactSchema = Yup.object().shape({
|
const ContactSchema = Yup.object().shape({
|
||||||
name: Yup.string()
|
name: Yup.string()
|
||||||
|
@ -60,75 +60,77 @@ const ContactSchema = Yup.object().shape({
|
||||||
number: Yup.string().min(8, "Too Short!").max(50, "Too Long!"),
|
number: Yup.string().min(8, "Too Short!").max(50, "Too Long!"),
|
||||||
|
|
||||||
email: Yup.string().min(2, "Too Short!")
|
email: Yup.string().min(2, "Too Short!")
|
||||||
.max(50, "Too Long!"),
|
.max(50, "Too Long!"),
|
||||||
|
|
||||||
// email: Yup.string().email("Invalid email"),
|
// email: Yup.string().email("Invalid email"),
|
||||||
});
|
})
|
||||||
|
|
||||||
const ContactModal = ({ open, onClose, contactId, initialValues, onSave }) => {
|
const ContactModal = ({ open, onClose, contactId, initialValues, onSave }) => {
|
||||||
const classes = useStyles();
|
const classes = useStyles()
|
||||||
const isMounted = useRef(true);
|
const isMounted = useRef(true)
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
name: "",
|
name: "",
|
||||||
number: "",
|
number: "",
|
||||||
email: "",
|
email: "",
|
||||||
useDialogflow: true,
|
useDialogflow: true,
|
||||||
};
|
}
|
||||||
|
|
||||||
const [contact, setContact] = useState(initialState);
|
const [contact, setContact] = useState(initialState)
|
||||||
|
const [isSaving, setSaving] = useState(false)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
isMounted.current = false;
|
isMounted.current = false
|
||||||
};
|
}
|
||||||
}, []);
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchContact = async () => {
|
const fetchContact = async () => {
|
||||||
if (initialValues) {
|
if (initialValues) {
|
||||||
setContact(prevState => {
|
setContact(prevState => {
|
||||||
return { ...prevState, ...initialValues };
|
return { ...prevState, ...initialValues }
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!contactId) return;
|
if (!contactId) return
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { data } = await api.get(`/contacts/${contactId}`);
|
const { data } = await api.get(`/contacts/${contactId}`)
|
||||||
if (isMounted.current) {
|
if (isMounted.current) {
|
||||||
setContact(data);
|
setContact(data)
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
toastError(err);
|
toastError(err)
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
fetchContact();
|
fetchContact()
|
||||||
}, [contactId, open, initialValues]);
|
}, [contactId, open, initialValues])
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
onClose();
|
onClose()
|
||||||
setContact(initialState);
|
setContact(initialState)
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleSaveContact = async values => {
|
const handleSaveContact = async values => {
|
||||||
try {
|
try {
|
||||||
if (contactId) {
|
if (contactId) {
|
||||||
await api.put(`/contacts/${contactId}`, values);
|
await api.put(`/contacts/${contactId}`, values)
|
||||||
handleClose();
|
handleClose()
|
||||||
} else {
|
} else {
|
||||||
const { data } = await api.post("/contacts", values);
|
const { data } = await api.post("/contacts", values)
|
||||||
if (onSave) {
|
if (onSave) {
|
||||||
onSave(data);
|
onSave(data)
|
||||||
}
|
}
|
||||||
handleClose();
|
handleClose()
|
||||||
}
|
}
|
||||||
toast.success(i18n.t("contactModal.success"));
|
toast.success(i18n.t("contactModal.success"))
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
toastError(err);
|
toastError(err)
|
||||||
}
|
}
|
||||||
};
|
setSaving(false)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes.root}>
|
<div className={classes.root}>
|
||||||
|
@ -143,10 +145,11 @@ const ContactModal = ({ open, onClose, contactId, initialValues, onSave }) => {
|
||||||
enableReinitialize={true}
|
enableReinitialize={true}
|
||||||
validationSchema={ContactSchema}
|
validationSchema={ContactSchema}
|
||||||
onSubmit={(values, actions) => {
|
onSubmit={(values, actions) => {
|
||||||
|
setSaving(true)
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
handleSaveContact(values);
|
handleSaveContact(values)
|
||||||
actions.setSubmitting(false);
|
actions.setSubmitting(false)
|
||||||
}, 400);
|
}, 400)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ values, errors, touched, isSubmitting }) => (
|
{({ values, errors, touched, isSubmitting }) => (
|
||||||
|
@ -256,14 +259,14 @@ const ContactModal = ({ open, onClose, contactId, initialValues, onSave }) => {
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
color="primary"
|
color="primary"
|
||||||
disabled={isSubmitting}
|
disabled={isSaving}
|
||||||
variant="contained"
|
variant="contained"
|
||||||
className={classes.btnWrapper}
|
className={classes.btnWrapper}
|
||||||
>
|
>
|
||||||
{contactId
|
{contactId
|
||||||
? `${i18n.t("contactModal.buttons.okEdit")}`
|
? `${i18n.t("contactModal.buttons.okEdit")}`
|
||||||
: `${i18n.t("contactModal.buttons.okAdd")}`}
|
: `${i18n.t("contactModal.buttons.okAdd")}`}
|
||||||
{isSubmitting && (
|
{isSaving && (
|
||||||
<CircularProgress
|
<CircularProgress
|
||||||
size={24}
|
size={24}
|
||||||
className={classes.buttonProgress}
|
className={classes.buttonProgress}
|
||||||
|
@ -276,7 +279,7 @@ const ContactModal = ({ open, onClose, contactId, initialValues, onSave }) => {
|
||||||
</Formik>
|
</Formik>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</div>
|
</div>
|
||||||
);
|
)
|
||||||
};
|
}
|
||||||
|
|
||||||
export default ContactModal;
|
export default ContactModal
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
import React, { useState, useEffect } from "react"
|
||||||
|
import Box from '@mui/material/Box'
|
||||||
|
import Button from '@mui/material/Button'
|
||||||
|
import Dialog from '@mui/material/Dialog'
|
||||||
|
import DialogActions from '@mui/material/DialogActions'
|
||||||
|
import DialogContent from '@mui/material/DialogContent'
|
||||||
|
import DialogContentText from '@mui/material/DialogContentText'
|
||||||
|
import DialogTitle from '@mui/material/DialogTitle'
|
||||||
|
import FormControl from '@mui/material/FormControl'
|
||||||
|
|
||||||
|
import InputLabel from '@mui/material/InputLabel'
|
||||||
|
import MenuItem from '@mui/material/MenuItem'
|
||||||
|
import Select from '@mui/material/Select'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default function MaxWidthDialog(props) {
|
||||||
|
const [open, setOpen] = useState(false)
|
||||||
|
const [fullWidth,] = useState(true)
|
||||||
|
const [currency, setCurrency] = useState(props.reportOption)
|
||||||
|
const [textOption, setTextOption] = useState('')
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
|
||||||
|
// props.func(currency)
|
||||||
|
|
||||||
|
if(currency === '2' || currency === '3'){
|
||||||
|
setTextOption('Retorna apenas tickets com status: fechado')
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
setTextOption('Retorna todos os tickets com status: aberto, fechado, pendente')
|
||||||
|
}
|
||||||
|
|
||||||
|
}, [currency, props])
|
||||||
|
|
||||||
|
|
||||||
|
const handleClickOpen = () => {
|
||||||
|
setOpen(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
|
||||||
|
props.func(currency)
|
||||||
|
|
||||||
|
setOpen(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleMaxWidthChange = (event) => {
|
||||||
|
|
||||||
|
setCurrency(event.target.value)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<Button variant="outlined" onClick={handleClickOpen}>
|
||||||
|
CSV ALL
|
||||||
|
</Button>
|
||||||
|
<Dialog
|
||||||
|
fullWidth={fullWidth}
|
||||||
|
maxWidth={'sm'}
|
||||||
|
open={open}
|
||||||
|
onClose={null}
|
||||||
|
>
|
||||||
|
<DialogTitle>Relatórios</DialogTitle>
|
||||||
|
|
||||||
|
<DialogContent>
|
||||||
|
<DialogContentText>
|
||||||
|
Escolha uma opção do tipo de relatório abaixo
|
||||||
|
</DialogContentText>
|
||||||
|
|
||||||
|
<Box
|
||||||
|
noValidate
|
||||||
|
component="form"
|
||||||
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
m: 'auto',
|
||||||
|
width: 'fit-content',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FormControl sx={{ mt: 2, minWidth: 420 }}>
|
||||||
|
|
||||||
|
<InputLabel htmlFor="opcoes">opcoes</InputLabel>
|
||||||
|
|
||||||
|
<Select
|
||||||
|
autoFocus
|
||||||
|
value={currency}
|
||||||
|
onChange={handleMaxWidthChange}
|
||||||
|
label="opcoes"
|
||||||
|
inputProps={{
|
||||||
|
name: 'opcoes',
|
||||||
|
id: 'opcoes',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
{props.currencies.map((option, index) => (
|
||||||
|
<MenuItem key={index} value={option.value}> {option.label} </MenuItem>
|
||||||
|
))}
|
||||||
|
|
||||||
|
|
||||||
|
</Select>
|
||||||
|
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
{/* <FormControlLabel
|
||||||
|
sx={{ mt: 1 }}
|
||||||
|
control={
|
||||||
|
<Switch checked={fullWidth} onChange={handleFullWidthChange} />
|
||||||
|
}
|
||||||
|
label="Full width"
|
||||||
|
/> */}
|
||||||
|
</Box>
|
||||||
|
</DialogContent>
|
||||||
|
<div style={{ display: 'flex', justifyContent: "center" }}>{textOption}</div>
|
||||||
|
|
||||||
|
<div style={{ display: 'flex', justifyContent: "right" }}>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={() => setOpen(false)}>Cancelar</Button>
|
||||||
|
</DialogActions>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={handleClose}>Ok</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</Dialog>
|
||||||
|
</React.Fragment>
|
||||||
|
)
|
||||||
|
}
|
|
@ -87,7 +87,7 @@ const WhatsAppModal = ({ open, onClose, whatsAppId, whatsAppOfficial }) => {
|
||||||
if (!whatsAppId) return
|
if (!whatsAppId) return
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { data } = await api.get(`whatsapp/${whatsAppId}`)
|
const { data } = await api.get(`whatsapp/${whatsAppId}`)
|
||||||
|
|
||||||
setWhatsApp(data)
|
setWhatsApp(data)
|
||||||
setIsOfficial(data?.isOfficial)
|
setIsOfficial(data?.isOfficial)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState, useEffect, useReducer, useContext } from "react"
|
import React, { useState, useEffect, useReducer, useContext, useCallback } from "react"
|
||||||
import MainContainer from "../../components/MainContainer"
|
import MainContainer from "../../components/MainContainer"
|
||||||
import api from "../../services/api"
|
import api from "../../services/api"
|
||||||
import SelectField from "../../components/Report/SelectField"
|
import SelectField from "../../components/Report/SelectField"
|
||||||
|
@ -17,6 +17,8 @@ import Checkbox from '@mui/material/Checkbox'
|
||||||
import { Button } from "@material-ui/core"
|
import { Button } from "@material-ui/core"
|
||||||
|
|
||||||
import ReportModal from "../../components/ReportModal"
|
import ReportModal from "../../components/ReportModal"
|
||||||
|
import ReportModalType from "../../components/ReportModalType"
|
||||||
|
|
||||||
import MaterialTable from 'material-table'
|
import MaterialTable from 'material-table'
|
||||||
|
|
||||||
import LogoutIcon from '@material-ui/icons/CancelOutlined'
|
import LogoutIcon from '@material-ui/icons/CancelOutlined'
|
||||||
|
@ -34,6 +36,9 @@ import Switch from '@mui/material/Switch'
|
||||||
const label = { inputProps: { 'aria-label': 'Size switch demo' } }
|
const label = { inputProps: { 'aria-label': 'Size switch demo' } }
|
||||||
|
|
||||||
const report = [{ 'value': '1', 'label': 'Atendimento por atendentes' }, { 'value': '2', 'label': 'Usuários online/offline' }]
|
const report = [{ 'value': '1', 'label': 'Atendimento por atendentes' }, { 'value': '2', 'label': 'Usuários online/offline' }]
|
||||||
|
const reportOptType = [{ 'value': '1', 'label': 'Padrão' }, { 'value': '2', 'label': 'Sintético' }, { 'value': '3', 'label': 'Analítico' }]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const reducerQ = (state, action) => {
|
const reducerQ = (state, action) => {
|
||||||
|
@ -276,21 +281,16 @@ const Report = () => {
|
||||||
const [hasMore, setHasMore] = useState(false)
|
const [hasMore, setHasMore] = useState(false)
|
||||||
const [pageNumberTickets, setTicketsPageNumber] = useState(1)
|
const [pageNumberTickets, setTicketsPageNumber] = useState(1)
|
||||||
const [totalCountTickets, setTotalCountTickets] = useState(0)
|
const [totalCountTickets, setTotalCountTickets] = useState(0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const [pageNumber, setPageNumber] = useState(1)
|
const [pageNumber, setPageNumber] = useState(1)
|
||||||
const [users, dispatch] = useReducer(reducer, [])
|
const [users, dispatch] = useReducer(reducer, [])
|
||||||
const [startDate, setDatePicker1] = useState(new Date())
|
const [startDate, setDatePicker1] = useState(new Date())
|
||||||
const [endDate, setDatePicker2] = useState(new Date())
|
const [endDate, setDatePicker2] = useState(new Date())
|
||||||
const [userId, setUser] = useState(null)
|
const [userId, setUser] = useState(null)
|
||||||
const [query, dispatchQ] = useReducer(reducerQ, [])
|
const [query, dispatchQ] = useReducer(reducerQ, [])
|
||||||
|
|
||||||
const [reportOption, setReport] = useState('1')
|
const [reportOption, setReport] = useState('1')
|
||||||
const [reporList,] = useState(report)
|
const [reporList,] = useState(report)
|
||||||
const [profile, setProfile] = useState('')
|
const [profile, setProfile] = useState('')
|
||||||
const [dataRows, setData] = useState([])
|
const [dataRows, setData] = useState([])
|
||||||
|
|
||||||
const [onQueueStatus, setOnQueueProcessStatus] = useState(undefined)
|
const [onQueueStatus, setOnQueueProcessStatus] = useState(undefined)
|
||||||
const [csvFile, setCsvFile] = useState()
|
const [csvFile, setCsvFile] = useState()
|
||||||
const [selectedValue, setSelectedValue] = useState('created')
|
const [selectedValue, setSelectedValue] = useState('created')
|
||||||
|
@ -298,6 +298,11 @@ const Report = () => {
|
||||||
const [queues, setQueues] = useState([])
|
const [queues, setQueues] = useState([])
|
||||||
const [queueId, setQueue] = useState(null)
|
const [queueId, setQueue] = useState(null)
|
||||||
|
|
||||||
|
const [reportTypeList,] = useState(reportOptType)
|
||||||
|
const [reportType, setReportType] = useState('1')
|
||||||
|
const [firstLoad, setFirstLoad] = useState(true);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dispatch({ type: "RESET" })
|
dispatch({ type: "RESET" })
|
||||||
dispatchQ({ type: "RESET" })
|
dispatchQ({ type: "RESET" })
|
||||||
|
@ -306,6 +311,14 @@ const Report = () => {
|
||||||
}, [searchParam, profile])
|
}, [searchParam, profile])
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (firstLoad) {
|
||||||
|
setFirstLoad(false)
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
}, [firstLoad]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
//setLoading(true);
|
//setLoading(true);
|
||||||
|
|
||||||
|
@ -337,16 +350,14 @@ const Report = () => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
||||||
//setLoading(true);
|
//setLoading(true);
|
||||||
|
if (firstLoad) return
|
||||||
|
|
||||||
const delayDebounceFn = setTimeout(() => {
|
const delayDebounceFn = setTimeout(() => {
|
||||||
|
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
const fetchQueries = async () => {
|
const fetchQueries = async () => {
|
||||||
try {
|
try {
|
||||||
if (reportOption === '1') {
|
if (reportOption === '1') {
|
||||||
|
|
||||||
// const { data } = await api.get("/reports/", { params: { userId: userId ? userId : 0, startDate: convertAndFormatDate(startDate), endDate: convertAndFormatDate(endDate), pageNumber: pageNumberTickets }, })
|
|
||||||
|
|
||||||
const { data } = await api.get("/reports/", { params: { userId, startDate, endDate, pageNumber: pageNumberTickets, createdOrUpdated: selectedValue, queueId }, userQueues: userA.queues })
|
const { data } = await api.get("/reports/", { params: { userId, startDate, endDate, pageNumber: pageNumberTickets, createdOrUpdated: selectedValue, queueId }, userQueues: userA.queues })
|
||||||
|
|
||||||
let ticketsQueue = data.tickets
|
let ticketsQueue = data.tickets
|
||||||
|
@ -424,8 +435,21 @@ const Report = () => {
|
||||||
setChecked(true)
|
setChecked(true)
|
||||||
}
|
}
|
||||||
setReport(data)
|
setReport(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get from report type option
|
||||||
|
const reportTypeValue = (data) => {
|
||||||
|
console.log('DATA: ', data)
|
||||||
|
let type = '1'
|
||||||
|
if (data === '1') type = 'default'
|
||||||
|
if (data === '2') type = 'synthetic'
|
||||||
|
if (data === '3') type = 'analytic'
|
||||||
|
|
||||||
|
handleCSVMessages(type)
|
||||||
|
|
||||||
|
setReportType(data)
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
||||||
if (reportOption === '1') {
|
if (reportOption === '1') {
|
||||||
|
@ -500,7 +524,7 @@ const Report = () => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const handleCSVMessages = () => {
|
const handleCSVMessages = (type = 'default') => {
|
||||||
|
|
||||||
const fetchQueries = async () => {
|
const fetchQueries = async () => {
|
||||||
|
|
||||||
|
@ -519,7 +543,8 @@ const Report = () => {
|
||||||
userId: userId,
|
userId: userId,
|
||||||
startDate: startDate,
|
startDate: startDate,
|
||||||
endDate: endDate
|
endDate: endDate
|
||||||
}
|
},
|
||||||
|
query_type: type
|
||||||
})
|
})
|
||||||
|
|
||||||
const onQueueStatus = querySavedOnQueue.data.queueStatus
|
const onQueueStatus = querySavedOnQueue.data.queueStatus
|
||||||
|
@ -639,7 +664,10 @@ const Report = () => {
|
||||||
case 'empty':
|
case 'empty':
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button
|
{query && query.length > 0 &&
|
||||||
|
<ReportModalType currencies={reportTypeList} func={reportTypeValue} reportOption={reportType} />
|
||||||
|
}
|
||||||
|
{/* <Button
|
||||||
disabled={query && query.length > 0 ? false : true}
|
disabled={query && query.length > 0 ? false : true}
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
|
@ -648,7 +676,8 @@ const Report = () => {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{"CSV ALL"}
|
{"CSV ALL"}
|
||||||
</Button>
|
|
||||||
|
</Button> */}
|
||||||
</>)
|
</>)
|
||||||
|
|
||||||
case 'pending' || 'processing':
|
case 'pending' || 'processing':
|
||||||
|
|
Loading…
Reference in New Issue