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);
|
||||
|
||||
const validNumber = await CheckIsValidContact(newContact.number);
|
||||
|
||||
// const validNumber: any = await CheckContactNumber(newContact.number)
|
||||
const validNumber = await CheckIsValidContact(newContact.number);
|
||||
|
||||
if (!validNumber) {
|
||||
throw new AppError("ERR_WAPP_CHECK_CONTACT");
|
||||
}
|
||||
|
||||
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}`)
|
||||
const profilePicUrl = await GetProfilePicUrl(validNumber);
|
||||
|
||||
let name = newContact.name;
|
||||
let number = validNumber;
|
||||
|
|
|
@ -21,6 +21,7 @@ import sendWhatsAppMessageOfficialAPI from "../helpers/sendWhatsAppMessageOffici
|
|||
import Whatsapp from "../models/Whatsapp";
|
||||
import checkLastClientMsg24hs from "../helpers/CheckLastClientMsg24hs";
|
||||
import AppError from "../errors/AppError";
|
||||
import { get } from "../helpers/RedisClient";
|
||||
|
||||
type IndexQuery = {
|
||||
pageNumber: string;
|
||||
|
@ -35,7 +36,7 @@ type MessageData = {
|
|||
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 { 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 { 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;
|
||||
|
||||
|
|
|
@ -5,14 +5,12 @@ import DeleteQueueService from "../services/QueueService/DeleteQueueService";
|
|||
import ListQueuesService from "../services/QueueService/ListQueuesService";
|
||||
import ShowQueueService from "../services/QueueService/ShowQueueService";
|
||||
import UpdateQueueService from "../services/QueueService/UpdateQueueService";
|
||||
import Queue from "../models/Queue"
|
||||
import AppError from "../errors/AppError"
|
||||
import { get, set } from "../helpers/RedisClient";
|
||||
|
||||
|
||||
import Queue from "../models/Queue";
|
||||
import AppError from "../errors/AppError";
|
||||
import { del, get, set } from "../helpers/RedisClient";
|
||||
|
||||
export const index = async (req: Request, res: Response): Promise<Response> => {
|
||||
const queues = await ListQueuesService();
|
||||
const queues = await ListQueuesService();
|
||||
|
||||
return res.status(200).json(queues);
|
||||
};
|
||||
|
@ -125,7 +123,7 @@ export const customization = async (
|
|||
|
||||
await set("ura", ura);
|
||||
|
||||
const _ura = await get("ura");
|
||||
const _ura = await get({ key: "ura", parse: true });
|
||||
console.log("_URA: ", _ura);
|
||||
|
||||
return res.status(200).json({ new_queues });
|
||||
|
@ -164,6 +162,8 @@ export const remove = async (
|
|||
|
||||
await DeleteQueueService(queueId);
|
||||
|
||||
await del(`queue:${queueId}`);
|
||||
|
||||
const io = getIO();
|
||||
io.emit("queue", {
|
||||
action: "delete",
|
||||
|
|
|
@ -75,8 +75,9 @@ import GetProfilePicUrl from "../services/WbotServices/GetProfilePicUrl";
|
|||
import CreateContactService from "../services/ContactServices/CreateContactService";
|
||||
import { botSendMessage } from "../services/WbotServices/wbotMessageListener";
|
||||
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 {
|
||||
pageNumber,
|
||||
status,
|
||||
|
@ -93,9 +94,9 @@ export const index = async (req: Request, res: Response): Promise<Response> => {
|
|||
|
||||
let queueIds: number[] = [];
|
||||
|
||||
if (queueIdsStringified) {
|
||||
if (queueIdsStringified && queueIdsStringified.trim().length > 0) {
|
||||
queueIds = JSON.parse(queueIdsStringified);
|
||||
}
|
||||
}
|
||||
|
||||
const { tickets, count, hasMore } = await ListTicketsService({
|
||||
searchParam,
|
||||
|
@ -109,7 +110,7 @@ export const index = async (req: Request, res: Response): Promise<Response> => {
|
|||
unlimited,
|
||||
searchParamContent
|
||||
});
|
||||
|
||||
|
||||
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 User from "../models/User";
|
||||
import { get, set } from "../helpers/RedisClient";
|
||||
import { del, get, set } from "../helpers/RedisClient";
|
||||
|
||||
import {
|
||||
startWhoIsOnlineMonitor,
|
||||
|
@ -27,6 +27,7 @@ import { splitDateTime } from "../helpers/SplitDateTime";
|
|||
import ListUserByWhatsappQueuesService from "../services/UserServices/ListUserByWhatsappQueuesService";
|
||||
import { json } from "sequelize";
|
||||
import { getSettingValue } from "../helpers/WhaticketSettings";
|
||||
import { setBotInfo } from "../helpers/SetBotInfo";
|
||||
|
||||
type IndexQuery = {
|
||||
searchParam: string;
|
||||
|
@ -110,8 +111,7 @@ export const all = async (req: Request, res: Response): Promise<Response> => {
|
|||
getSettingValue("queueTransferByWhatsappScope")?.value
|
||||
);
|
||||
|
||||
if (getSettingValue("queueTransferByWhatsappScope")?.value == "enabled") {
|
||||
|
||||
if (getSettingValue("queueTransferByWhatsappScope")?.value == "enabled") {
|
||||
if (!userId) return res.json({ users: [], queues: [] });
|
||||
|
||||
const obj = await ListUserByWhatsappQueuesService(
|
||||
|
@ -122,7 +122,7 @@ export const all = async (req: Request, res: Response): Promise<Response> => {
|
|||
const usersByWhatsqueue = obj.users;
|
||||
const queues = obj.queues;
|
||||
|
||||
let userIds = usersByWhatsqueue.map((w: any) => w.userId);
|
||||
let userIds = usersByWhatsqueue.map((w: any) => w.userId);
|
||||
|
||||
const users = await ListUser({
|
||||
userIds
|
||||
|
@ -167,6 +167,11 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
|||
queueIds
|
||||
});
|
||||
|
||||
if (user) {
|
||||
const { id, name } = user;
|
||||
await set(`user:${id}`, { id, name });
|
||||
}
|
||||
|
||||
const io = getIO();
|
||||
io.emit("user", {
|
||||
action: "create",
|
||||
|
@ -270,34 +275,11 @@ export const update = async (
|
|||
|
||||
let user: any = await UpdateUserService({ userData, userId });
|
||||
|
||||
if (user?.name?.trim() == "botqueue") {
|
||||
let botInfo;
|
||||
await setBotInfo(user);
|
||||
|
||||
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);
|
||||
}
|
||||
if (user) {
|
||||
const { id, name } = user;
|
||||
await set(`user:${id}`, { id, name });
|
||||
}
|
||||
|
||||
const io = getIO();
|
||||
|
@ -323,6 +305,8 @@ export const remove = async (
|
|||
|
||||
await DeleteUserService(userId);
|
||||
|
||||
del(`user:${userId}`);
|
||||
|
||||
const io = getIO();
|
||||
io.emit("user", {
|
||||
action: "delete",
|
||||
|
|
|
@ -42,6 +42,7 @@ import { getSettingValue } from "../helpers/WhaticketSettings";
|
|||
import ListWhatsAppsNumber from "../services/WhatsappService/ListWhatsAppsNumber";
|
||||
import SettingTicket from "../models/SettingTicket";
|
||||
import { Op } from "sequelize";
|
||||
import { del, get, set } from "../helpers/RedisClient";
|
||||
|
||||
interface WhatsappData {
|
||||
name: string;
|
||||
|
@ -229,6 +230,25 @@ export const weebhook = async (
|
|||
req.body.entry[0].changes[0].value.metadata.display_phone_number;
|
||||
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 msg = {};
|
||||
let contacts = req.body.entry[0].changes[0].value.contacts[0];
|
||||
|
@ -248,6 +268,10 @@ export const weebhook = async (
|
|||
});
|
||||
|
||||
if (type == "text") {
|
||||
if (!message?.text?.body) {
|
||||
return res.status(400).json({ error: "body not found" });
|
||||
}
|
||||
|
||||
type = "chat";
|
||||
msg = {
|
||||
...msg,
|
||||
|
@ -255,6 +279,10 @@ export const weebhook = async (
|
|||
type
|
||||
};
|
||||
} else {
|
||||
if (!message[message?.type]?.id) {
|
||||
return res.status(400).json({ error: "id not found" });
|
||||
}
|
||||
|
||||
const mediaId = message[message.type].id;
|
||||
const mimetype = message[message.type].mime_type;
|
||||
|
||||
|
@ -382,6 +410,16 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
|
|||
number: getNumberFromName(name),
|
||||
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();
|
||||
|
@ -421,13 +459,14 @@ export const update = async (
|
|||
return res.status(200).json({ message: invalidPhoneName });
|
||||
}
|
||||
|
||||
const { urlApi, isOfficial, phoneNumberId, wabaId } = whatsappData;
|
||||
const { urlApi, isOfficial, phoneNumberId, number, wabaId } = whatsappData;
|
||||
|
||||
const invalid = checkWhatsAppData({
|
||||
urlApi,
|
||||
isOfficial,
|
||||
phoneNumberId,
|
||||
wabaId
|
||||
wabaId,
|
||||
number
|
||||
});
|
||||
|
||||
if (invalid) {
|
||||
|
@ -440,6 +479,7 @@ export const update = async (
|
|||
} else if (!isOfficial) {
|
||||
whatsappData.phoneNumberId = "";
|
||||
whatsappData.wabaId = "";
|
||||
whatsappData.number = "";
|
||||
}
|
||||
|
||||
const { whatsapp, oldDefaultWhatsapp } = await UpdateWhatsAppService({
|
||||
|
@ -454,6 +494,16 @@ export const update = async (
|
|||
number: getNumberFromName(whatsapp.name),
|
||||
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();
|
||||
|
@ -491,6 +541,8 @@ export const remove = async (
|
|||
});
|
||||
}
|
||||
|
||||
await del(`whatsapp:${whatsappId}`);
|
||||
|
||||
let whats = await ListWhatsAppsNumber(whatsappId);
|
||||
|
||||
// Remove tickets business hours config
|
||||
|
@ -572,5 +624,5 @@ const checkWhatsAppData = ({
|
|||
return { message: "Phone number is required!" };
|
||||
} else if (!isOfficial && (!urlApi || urlApi.trim() == "")) {
|
||||
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 { get } from "./RedisClient";
|
||||
|
||||
const _botIsOnQueue = async (botName: string) => {
|
||||
|
||||
const botInfo = await get("botInfo");
|
||||
const _botIsOnQueue = async (botName: string) => {
|
||||
const botInfo = await get({ key: "botInfo", parse: true });
|
||||
|
||||
if (
|
||||
botInfo &&
|
||||
|
@ -19,8 +18,8 @@ const _botIsOnQueue = async (botName: string) => {
|
|||
botQueueId: botInfo.queueId,
|
||||
isOnQueue: botInfo.botIsOnQueue
|
||||
};
|
||||
}
|
||||
return { userIdBot: null, botQueueId: null, isOnQueue: false };
|
||||
}
|
||||
return { userIdBot: null, botQueueId: null, isOnQueue: false };
|
||||
};
|
||||
|
||||
export default _botIsOnQueue;
|
||||
|
|
|
@ -6,27 +6,26 @@ import UserQueue from "../models/UserQueue";
|
|||
|
||||
import { Op, where } from "sequelize";
|
||||
|
||||
import wbotByUserQueue from "../helpers/GetWbotByUserQueue";
|
||||
import wbotByUserQueue from "../helpers/GetWbotByUserQueue";
|
||||
|
||||
import { WhatsIndex } from "./LoadBalanceWhatsSameQueue";
|
||||
|
||||
interface Request {
|
||||
userId?: string | number;
|
||||
queueId?: string | number;
|
||||
ignoreNoWhatsappFound?: boolean
|
||||
}
|
||||
|
||||
//const GetDefaultWhatsApp = async (userId?: string | number): Promise<Whatsapp> => {
|
||||
|
||||
|
||||
const GetDefaultWhatsApp = async ({
|
||||
userId,
|
||||
queueId
|
||||
}: Request): Promise<any> => {
|
||||
// test del
|
||||
queueId,
|
||||
ignoreNoWhatsappFound = false
|
||||
}: Request): Promise<any> => {
|
||||
let defaultWhatsapp = await Whatsapp.findOne({
|
||||
where: { isDefault: true }
|
||||
});
|
||||
|
||||
if (!defaultWhatsapp) {
|
||||
if (!defaultWhatsapp) {
|
||||
if (userId) {
|
||||
let whatsapps = await wbotByUserQueue({ userId, queueId });
|
||||
|
||||
|
@ -54,19 +53,18 @@ const GetDefaultWhatsApp = async ({
|
|||
where: { status: "CONNECTED" }
|
||||
});
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
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");
|
||||
}
|
||||
|
||||
return defaultWhatsapp;
|
||||
//
|
||||
return defaultWhatsapp;
|
||||
};
|
||||
|
||||
export default GetDefaultWhatsApp;
|
||||
|
|
|
@ -6,28 +6,65 @@ type WhatsappData = {
|
|||
contactId: string;
|
||||
identifier: string;
|
||||
value?: string;
|
||||
history?: string;
|
||||
};
|
||||
|
||||
type getData = {
|
||||
key: string;
|
||||
value?: string;
|
||||
parse?: boolean;
|
||||
};
|
||||
|
||||
export async function set(key: string, value: string | object) {
|
||||
await redis.set(key, JSON.stringify(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);
|
||||
if (typeof value == "object") await redis.set(key, JSON.stringify(value));
|
||||
else {
|
||||
await redis.set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
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(
|
||||
key: string,
|
||||
|
@ -54,7 +91,7 @@ export async function findByContain(
|
|||
results.push(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
|
@ -62,7 +99,8 @@ export async function createObject({
|
|||
whatsappId,
|
||||
contactId,
|
||||
identifier,
|
||||
value
|
||||
value,
|
||||
history = ""
|
||||
}: WhatsappData) {
|
||||
const key = `whatsappId:${whatsappId}:contactId:${contactId}:identifier:${identifier}`;
|
||||
const result = await redis.hmset(
|
||||
|
@ -74,7 +112,9 @@ export async function createObject({
|
|||
"identifier",
|
||||
identifier,
|
||||
"value",
|
||||
value
|
||||
value,
|
||||
"history",
|
||||
history
|
||||
);
|
||||
|
||||
await redis.expire(key, 300);
|
||||
|
@ -102,7 +142,8 @@ export async function findObject(
|
|||
"whatsappId",
|
||||
"contactId",
|
||||
"identifier",
|
||||
"value"
|
||||
"value",
|
||||
"history"
|
||||
);
|
||||
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
|
||||
fromMe: boolean;
|
||||
|
||||
@Default(false)
|
||||
@Column
|
||||
fromAgent: boolean;
|
||||
|
||||
@Column(DataType.TEXT)
|
||||
body: string;
|
||||
|
||||
|
|
|
@ -23,7 +23,11 @@ import fs from "fs";
|
|||
import dir from "path";
|
||||
import { getSettingValue } from "./helpers/WhaticketSettings";
|
||||
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, () => {
|
||||
logger.info(`Server started on port: ${process.env.PORT}`);
|
||||
|
@ -39,32 +43,59 @@ const server = app.listen(process.env.PORT, () => {
|
|||
initIO(server);
|
||||
|
||||
// StartAllWhatsAppsSessions();
|
||||
gracefulShutdown(server);
|
||||
gracefulShutdown(server);
|
||||
|
||||
(async () => {
|
||||
console.log("os.tmpdir(): ", os.tmpdir());
|
||||
|
||||
await clearAllKeys();
|
||||
await clearAllKeys("user:*", "whatsapp:*", "queue:*");
|
||||
|
||||
const users = await User.findAll();
|
||||
|
||||
for (const user of users) {
|
||||
const { id, name } = user;
|
||||
|
||||
if (name == "botqueue") {
|
||||
const userService = await ShowUserService(id);
|
||||
await setBotInfo(userService);
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
let whatsapps: any = await Whatsapp.findAll({
|
||||
attributes: ["id", "url", "phoneNumberId"]
|
||||
attributes: ["id", "url", "phoneNumberId", "number", "greetingMessage"]
|
||||
});
|
||||
|
||||
if (whatsapps && whatsapps.length > 0) {
|
||||
for (let i = 0; i < whatsapps.length; i++) {
|
||||
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(
|
||||
`API URL: ${whatsapps[i].dataValues.url}/api/connection/status`
|
||||
|
|
|
@ -13,6 +13,7 @@ interface MessageData {
|
|||
read?: boolean;
|
||||
mediaType?: string;
|
||||
mediaUrl?: string;
|
||||
fromAgent?: boolean;
|
||||
}
|
||||
interface Request {
|
||||
messageData: MessageData;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import * as Yup from "yup";
|
||||
import AppError from "../../errors/AppError";
|
||||
import Queue from "../../models/Queue";
|
||||
import { set } from "../../helpers/RedisClient";
|
||||
|
||||
interface QueueData {
|
||||
name: string;
|
||||
|
@ -9,68 +10,67 @@ interface QueueData {
|
|||
}
|
||||
|
||||
const CreateQueueService = async (queueData: QueueData): Promise<Queue> => {
|
||||
|
||||
try {
|
||||
|
||||
const { color, name } = queueData;
|
||||
|
||||
const queueSchema = Yup.object().shape({
|
||||
name: Yup.string()
|
||||
.min(2, "ERR_QUEUE_INVALID_NAME")
|
||||
.required("ERR_QUEUE_INVALID_NAME")
|
||||
.test(
|
||||
"Check-unique-name",
|
||||
"ERR_QUEUE_NAME_ALREADY_EXISTS",
|
||||
async value => {
|
||||
if (value) {
|
||||
const queueWithSameName = await Queue.findOne({
|
||||
where: { name: value }
|
||||
});
|
||||
const queueSchema = Yup.object().shape({
|
||||
name: Yup.string()
|
||||
.min(2, "ERR_QUEUE_INVALID_NAME")
|
||||
.required("ERR_QUEUE_INVALID_NAME")
|
||||
.test(
|
||||
"Check-unique-name",
|
||||
"ERR_QUEUE_NAME_ALREADY_EXISTS",
|
||||
async value => {
|
||||
if (value) {
|
||||
const queueWithSameName = await Queue.findOne({
|
||||
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;
|
||||
}
|
||||
),
|
||||
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;
|
||||
})
|
||||
.test(
|
||||
"Check-color-exists",
|
||||
"ERR_QUEUE_COLOR_ALREADY_EXISTS",
|
||||
async value => {
|
||||
if (value) {
|
||||
const queueWithSameColor = await Queue.findOne({
|
||||
where: { color: value }
|
||||
});
|
||||
return !queueWithSameColor;
|
||||
})
|
||||
.test(
|
||||
"Check-color-exists",
|
||||
"ERR_QUEUE_COLOR_ALREADY_EXISTS",
|
||||
async value => {
|
||||
if (value) {
|
||||
const queueWithSameColor = await Queue.findOne({
|
||||
where: { color: value }
|
||||
});
|
||||
return !queueWithSameColor;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
)
|
||||
});
|
||||
)
|
||||
});
|
||||
|
||||
try {
|
||||
await queueSchema.validate({ color, name });
|
||||
} catch (err: any) {
|
||||
throw new AppError(err.message);
|
||||
}
|
||||
try {
|
||||
await queueSchema.validate({ color, name });
|
||||
} catch (err: any) {
|
||||
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) {
|
||||
console.error('===> Error on CreateQueueService.ts file: \n', error)
|
||||
console.error("===> Error on CreateQueueService.ts file: \n", error);
|
||||
throw new AppError(error.message);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export default CreateQueueService;
|
||||
|
|
|
@ -3,6 +3,7 @@ import * as Yup from "yup";
|
|||
import AppError from "../../errors/AppError";
|
||||
import Queue from "../../models/Queue";
|
||||
import ShowQueueService from "./ShowQueueService";
|
||||
import { set } from "../../helpers/RedisClient"
|
||||
|
||||
interface QueueData {
|
||||
name?: string;
|
||||
|
@ -14,9 +15,7 @@ const UpdateQueueService = async (
|
|||
queueId: number | string,
|
||||
queueData: QueueData
|
||||
): Promise<Queue> => {
|
||||
|
||||
try {
|
||||
|
||||
const { color, name } = queueData;
|
||||
|
||||
const queueSchema = Yup.object().shape({
|
||||
|
@ -30,7 +29,7 @@ const UpdateQueueService = async (
|
|||
const queueWithSameName = await Queue.findOne({
|
||||
where: { name: value, id: { [Op.not]: queueId } }
|
||||
});
|
||||
|
||||
|
||||
return !queueWithSameName;
|
||||
}
|
||||
return true;
|
||||
|
@ -59,24 +58,25 @@ const UpdateQueueService = async (
|
|||
}
|
||||
)
|
||||
});
|
||||
|
||||
|
||||
try {
|
||||
await queueSchema.validate({ color, name });
|
||||
} catch (err: any) {
|
||||
throw new AppError(err.message);
|
||||
}
|
||||
|
||||
|
||||
const queue = await ShowQueueService(queueId);
|
||||
|
||||
|
||||
await queue.update(queueData);
|
||||
|
||||
|
||||
// const { id, greetingMessage } = queue;
|
||||
// await set(`queue:${id}`, { id, name, greetingMessage });
|
||||
|
||||
return queue;
|
||||
|
||||
} 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);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
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
|
||||
|
@ -102,12 +103,13 @@ const FindOrCreateTicketServiceBot = async (
|
|||
}
|
||||
|
||||
ticket = await Ticket.create({
|
||||
contactId: groupContact ? groupContact.id : contact.id,
|
||||
status: status,
|
||||
userId: botInfo.userIdBot,
|
||||
isGroup: !!groupContact,
|
||||
unreadMessages,
|
||||
whatsappId
|
||||
contactId: groupContact ? groupContact.id : contact.id,
|
||||
status: status,
|
||||
userId: botInfo.userIdBot,
|
||||
isGroup: !!groupContact,
|
||||
unreadMessages,
|
||||
whatsappId,
|
||||
phoneNumberId
|
||||
});
|
||||
|
||||
console.log('yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy')
|
||||
|
|
|
@ -7,14 +7,17 @@ import Queue from "../../models/Queue";
|
|||
import Message from "../../models/Message";
|
||||
import { userInfo } from "os";
|
||||
|
||||
import { Op, where } from "sequelize";
|
||||
import { Op, QueryTypes, where } from "sequelize";
|
||||
|
||||
import { Sequelize } from "sequelize";
|
||||
import moment from "moment";
|
||||
const dbConfig = require("../../config/database");
|
||||
const sequelize = new Sequelize(dbConfig);
|
||||
|
||||
import { startOfDay, endOfDay, parseISO, getDate } from "date-fns";
|
||||
import { string } from "yup/lib/locale";
|
||||
import Whatsapp from "../../models/Whatsapp";
|
||||
import Query from "mysql2/typings/mysql/lib/protocol/sequences/Query"
|
||||
|
||||
interface Request {
|
||||
userId: string | number;
|
||||
|
@ -41,43 +44,41 @@ const ShowTicketReport = async ({
|
|||
queueId
|
||||
}: Request): Promise<Response> => {
|
||||
let where_clause: any = {};
|
||||
// let where_clause_msg: any = {};
|
||||
let query = "";
|
||||
|
||||
if (userId !== "0") {
|
||||
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) {
|
||||
where_clause.queueId = queueId;
|
||||
query = `AND t.queueId = ${queueId}`;
|
||||
}
|
||||
|
||||
const limit = 40;
|
||||
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({
|
||||
where: where_clause,
|
||||
where: {
|
||||
id: { [Op.in]: _ticketsId.map((t: any) => t.id) }
|
||||
},
|
||||
limit,
|
||||
offset,
|
||||
|
||||
|
@ -108,7 +109,6 @@ const ShowTicketReport = async ({
|
|||
model: Message,
|
||||
required: true,
|
||||
separate: true,
|
||||
where: where_clause_msg ,
|
||||
|
||||
attributes: [
|
||||
"body",
|
||||
|
@ -143,10 +143,10 @@ const ShowTicketReport = async ({
|
|||
model: Whatsapp,
|
||||
attributes: ["name"]
|
||||
}
|
||||
],
|
||||
],
|
||||
order: [["updatedAt", "DESC"]]
|
||||
});
|
||||
|
||||
|
||||
const hasMore = count > offset + tickets.length;
|
||||
|
||||
if (!tickets) {
|
||||
|
|
|
@ -1,27 +1,60 @@
|
|||
import axios from "axios";
|
||||
import AppError from "../../errors/AppError";
|
||||
import endPointQuery from "../../helpers/EndPointQuery";
|
||||
import GetDefaultWhatsApp from "../../helpers/GetDefaultWhatsApp";
|
||||
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;
|
||||
|
||||
// console.log('isValidNumber.data.number: ', isValidNumber.data.number)
|
||||
if (data?.isValid) {
|
||||
isValidNumber = data;
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
if (isValidNumber && isValidNumber?.isValid) return isValidNumber.number;
|
||||
} catch (err: any) {
|
||||
if (err.message === "invalidNumber") {
|
||||
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");
|
||||
}
|
||||
|
||||
if (isValidNumber && isValidNumber.data.isValid)
|
||||
return isValidNumber.data.number
|
||||
|
||||
};
|
||||
|
||||
export default CheckIsValidContact;
|
||||
|
|
|
@ -1,23 +1,47 @@
|
|||
import axios from "axios";
|
||||
import endPointQuery from "../../helpers/EndPointQuery";
|
||||
import GetDefaultWhatsApp from "../../helpers/GetDefaultWhatsApp";
|
||||
import { getWbot } from "../../libs/wbot";
|
||||
|
||||
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}`, })
|
||||
|
||||
console.log('profilePicUrl.data.data: ', profilePicUrl.data.data)
|
||||
|
||||
if (profilePicUrl && profilePicUrl.data.data) {
|
||||
return profilePicUrl.data.data;
|
||||
if (data?.data) {
|
||||
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;
|
||||
|
|
|
@ -92,13 +92,14 @@ import {
|
|||
createObject,
|
||||
findByContain,
|
||||
findObject,
|
||||
get
|
||||
get,
|
||||
getSimple
|
||||
} from "../../helpers/RedisClient";
|
||||
import FindOrCreateTicketServiceBot from "../TicketServices/FindOrCreateTicketServiceBot";
|
||||
import ShowTicketService from "../TicketServices/ShowTicketService";
|
||||
import ShowQueuesByUser from "../UserServices/ShowQueuesByUser";
|
||||
import ListWhatsappQueuesByUserQueue from "../UserServices/ListWhatsappQueuesByUserQueue";
|
||||
import CreateContactService from "../ContactServices/CreateContactService"
|
||||
import CreateContactService from "../ContactServices/CreateContactService";
|
||||
|
||||
var lst: any[] = getWhatsappIds();
|
||||
|
||||
|
@ -175,9 +176,14 @@ const verifyMediaMessage = async (
|
|||
mediaUrl: media.filename,
|
||||
mediaType: media.mimetype.split("/")[0],
|
||||
quotedMsgId: quotedMsg,
|
||||
phoneNumberId: msg?.phoneNumberId
|
||||
phoneNumberId: msg?.phoneNumberId,
|
||||
fromAgent: false
|
||||
};
|
||||
|
||||
if (msg?.fromMe) {
|
||||
messageData = { ...messageData, fromAgent: true };
|
||||
}
|
||||
|
||||
if (!ticket?.phoneNumberId) {
|
||||
if (!media.filename) {
|
||||
const ext = media.mimetype.split("/")[1].split(";")[0];
|
||||
|
@ -280,18 +286,33 @@ const verifyMessage = async (
|
|||
contact: Contact,
|
||||
quotedMsg?: any
|
||||
) => {
|
||||
const messageData = {
|
||||
let messageData = {
|
||||
id: msg.id.id,
|
||||
ticketId: ticket.id,
|
||||
contactId: msg.fromMe ? undefined : contact.id,
|
||||
body: msg.body,
|
||||
fromMe: msg.fromMe,
|
||||
fromAgent: false,
|
||||
mediaType: msg.type,
|
||||
read: msg.fromMe,
|
||||
quotedMsgId: quotedMsg,
|
||||
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 CreateMessageService({ messageData });
|
||||
|
@ -318,13 +339,14 @@ const verifyQueue = async (
|
|||
selectedOption = 1;
|
||||
choosenQueue = queues[+selectedOption - 1];
|
||||
} else {
|
||||
selectedOption = msg.body;
|
||||
selectedOption = msg?.body;
|
||||
|
||||
//////////////// EXTRAIR APENAS O NÚMERO ///////////////////
|
||||
selectedOption = selectedOption.replace(/[^1-9]/g, "");
|
||||
///////////////////////////////////
|
||||
|
||||
choosenQueue = queues[+selectedOption - 1];
|
||||
if (selectedOption && selectedOption.trim().length > 0) {
|
||||
//////////////// EXTRAIR APENAS O NÚMERO ///////////////////
|
||||
selectedOption = selectedOption.replace(/[^1-9]/g, "");
|
||||
///////////////////////////////////
|
||||
choosenQueue = queues[+selectedOption - 1];
|
||||
}
|
||||
}
|
||||
|
||||
if (choosenQueue) {
|
||||
|
@ -348,13 +370,14 @@ const verifyQueue = async (
|
|||
ticketId: ticket.id
|
||||
});
|
||||
|
||||
const data = await get("ura");
|
||||
const data = await get({ key: "ura", parse: true });
|
||||
|
||||
await createObject({
|
||||
whatsappId: `${ticket.whatsappId}`,
|
||||
contactId: `${ticket.contactId}`,
|
||||
identifier: "ura",
|
||||
value: data[1].id
|
||||
value: data[1].id,
|
||||
history: `|${data[1].id}`
|
||||
});
|
||||
|
||||
botSendMessage(ticket, data[1].value);
|
||||
|
@ -505,9 +528,7 @@ const transferTicket = async (
|
|||
ticket: Ticket,
|
||||
sendGreetingMessage?: boolean
|
||||
) => {
|
||||
const botInfo = await BotIsOnQueue("botqueue");
|
||||
|
||||
console.log("kkkkkkkkkkkkkkkkkkkkk queueName: ", queueName);
|
||||
const botInfo = await BotIsOnQueue("botqueue");
|
||||
|
||||
const queuesWhatsGreetingMessage = await queuesOutBot(
|
||||
wbot,
|
||||
|
@ -610,7 +631,7 @@ const handleMessage = async (
|
|||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isValidMsg(msg)) {
|
||||
return;
|
||||
|
@ -780,33 +801,33 @@ const handleMessage = async (
|
|||
await verifyQueue(wbot, msg, ticket, contact);
|
||||
}
|
||||
|
||||
if (msg.type === "vcard") {
|
||||
try {
|
||||
const array = msg.body.split("\n");
|
||||
const obj = [];
|
||||
let contact = "";
|
||||
for (let index = 0; index < array.length; index++) {
|
||||
const v = array[index];
|
||||
const values = v.split(":");
|
||||
for (let ind = 0; ind < values.length; ind++) {
|
||||
if (values[ind].indexOf("+") !== -1) {
|
||||
obj.push({ number: values[ind] });
|
||||
}
|
||||
if (values[ind].indexOf("FN") !== -1) {
|
||||
contact = values[ind + 1];
|
||||
}
|
||||
if (msg.type === "vcard") {
|
||||
try {
|
||||
const array = msg.body.split("\n");
|
||||
const obj = [];
|
||||
let contact = "";
|
||||
for (let index = 0; index < array.length; index++) {
|
||||
const v = array[index];
|
||||
const values = v.split(":");
|
||||
for (let ind = 0; ind < values.length; ind++) {
|
||||
if (values[ind].indexOf("+") !== -1) {
|
||||
obj.push({ number: values[ind] });
|
||||
}
|
||||
if (values[ind].indexOf("FN") !== -1) {
|
||||
contact = values[ind + 1];
|
||||
}
|
||||
}
|
||||
for await (const ob of obj) {
|
||||
const cont = await CreateContactService({
|
||||
name: contact,
|
||||
number: ob.number.replace(/\D/g, "")
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
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");
|
||||
|
||||
|
@ -820,7 +841,7 @@ const handleMessage = async (
|
|||
ticket.status == "pending" ||
|
||||
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 (botInfo.isOnQueue) {
|
||||
|
@ -964,7 +985,7 @@ const handleMessage = async (
|
|||
|
||||
const menu = async (userTyped: string, whatsappId: any, contactId: any) => {
|
||||
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]);
|
||||
|
||||
|
@ -973,7 +994,8 @@ const menu = async (userTyped: string, whatsappId: any, contactId: any) => {
|
|||
whatsappId,
|
||||
contactId,
|
||||
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 (
|
||||
lastId &&
|
||||
lastId.length == 4 &&
|
||||
(lastId.length == 4 || lastId.length == 5) &&
|
||||
lastId[3] &&
|
||||
lastId[3].trim().length > 0
|
||||
) {
|
||||
|
@ -993,23 +1015,49 @@ const menu = async (userTyped: string, whatsappId: any, contactId: any) => {
|
|||
o.value.toLowerCase() == userTyped.toLowerCase()
|
||||
);
|
||||
|
||||
// TEST DEL
|
||||
console.log("OPTION: ", option);
|
||||
|
||||
if (!option && userTyped != "0") {
|
||||
if (!option && userTyped != "0" && userTyped != "#") {
|
||||
if (!existSubMenu()) {
|
||||
|
||||
const response = await mainOptionsMenu(userTyped);
|
||||
if (response) return response;
|
||||
else {
|
||||
console.log("kkkkkkkkkkkkkkkkkkk");
|
||||
await createObject({
|
||||
let uraOptionSelected = await findObject(
|
||||
whatsappId,
|
||||
contactId,
|
||||
identifier: "ura",
|
||||
value: data[1].id
|
||||
});
|
||||
"ura"
|
||||
);
|
||||
|
||||
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) {
|
||||
let response: any = data.find((o: any) => o.idmaster == option.id);
|
||||
console.log(" RESPONSE OPTION: ", response, " | OPTION: ", option);
|
||||
|
||||
console.log(
|
||||
"RRRRRRRRRRRRRRRRRRRRRRRRRRRRR response: ",
|
||||
response,
|
||||
" | option: ",
|
||||
option
|
||||
);
|
||||
let history: any = await historyUra(whatsappId, contactId, response.id);
|
||||
|
||||
await createObject({
|
||||
whatsappId,
|
||||
contactId,
|
||||
identifier: "ura",
|
||||
value: response.id
|
||||
value: response.id,
|
||||
history
|
||||
});
|
||||
|
||||
return response;
|
||||
|
@ -1038,26 +1083,42 @@ const menu = async (userTyped: string, whatsappId: any, contactId: any) => {
|
|||
whatsappId,
|
||||
contactId,
|
||||
identifier: "ura",
|
||||
value: data[1].id
|
||||
value: data[1].id,
|
||||
history: `|${data[1].id}`
|
||||
});
|
||||
|
||||
return data[1];
|
||||
} else {
|
||||
console.log("INVALID SEARCH");
|
||||
} else if (userTyped == "#") {
|
||||
let uraOptionSelected = await findObject(whatsappId, contactId, "ura");
|
||||
|
||||
let response = await existSubMenu();
|
||||
if (response) return response;
|
||||
uraOptionSelected = uraOptionSelected[4].split("|").filter(Boolean);
|
||||
|
||||
return {
|
||||
value: data.find((o: any) => o.id == lastId[3])?.value
|
||||
};
|
||||
let id = uraOptionSelected[0];
|
||||
|
||||
// return {
|
||||
// value: `Você digitou uma opçao inválida!\n\n${
|
||||
// data.find((o: any) => o.id == lastId[3])?.value
|
||||
// }\n\nDigite 0 para voltar ao menu `
|
||||
// };
|
||||
}
|
||||
let history = `|${uraOptionSelected[0]}`;
|
||||
|
||||
if (uraOptionSelected.length > 1) {
|
||||
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() {
|
||||
|
@ -1069,18 +1130,29 @@ const menu = async (userTyped: string, whatsappId: any, contactId: 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(
|
||||
(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) {
|
||||
let response = data.find((o: any) => o.idmaster == menuOption.id);
|
||||
if (response) {
|
||||
let history = await historyUra(whatsappId, contactId, response.id);
|
||||
|
||||
await createObject({
|
||||
whatsappId,
|
||||
contactId,
|
||||
identifier: "ura",
|
||||
value: response.id
|
||||
value: response.id,
|
||||
history
|
||||
});
|
||||
|
||||
return response;
|
||||
|
@ -1189,6 +1261,31 @@ export {
|
|||
mediaTypeWhatsappOfficial,
|
||||
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) {
|
||||
return await Whatsapp.findByPk(whatsappId);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ interface WhatsappData {
|
|||
greetingMessage?: string;
|
||||
farewellMessage?: string;
|
||||
queueIds?: number[];
|
||||
number?:string;
|
||||
}
|
||||
|
||||
interface Request {
|
||||
|
@ -52,6 +53,7 @@ const UpdateWhatsAppService = async ({
|
|||
phoneNumberId,
|
||||
wabaId,
|
||||
isOfficial,
|
||||
number,
|
||||
url,
|
||||
urlApi,
|
||||
session,
|
||||
|
@ -116,6 +118,7 @@ const UpdateWhatsAppService = async ({
|
|||
isOfficial,
|
||||
phoneNumberId,
|
||||
wabaId,
|
||||
number,
|
||||
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 { Formik, FieldArray, Form, Field } from "formik";
|
||||
import { toast } from "react-toastify";
|
||||
import * as Yup from "yup"
|
||||
import { Formik, FieldArray, Form, Field } from "formik"
|
||||
import { toast } from "react-toastify"
|
||||
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import { green } from "@material-ui/core/colors";
|
||||
import Button from "@material-ui/core/Button";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import Dialog from "@material-ui/core/Dialog";
|
||||
import DialogActions from "@material-ui/core/DialogActions";
|
||||
import DialogContent from "@material-ui/core/DialogContent";
|
||||
import DialogTitle from "@material-ui/core/DialogTitle";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import IconButton from "@material-ui/core/IconButton";
|
||||
import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline";
|
||||
import CircularProgress from "@material-ui/core/CircularProgress";
|
||||
import { makeStyles } from "@material-ui/core/styles"
|
||||
import { green } from "@material-ui/core/colors"
|
||||
import Button from "@material-ui/core/Button"
|
||||
import TextField from "@material-ui/core/TextField"
|
||||
import Dialog from "@material-ui/core/Dialog"
|
||||
import DialogActions from "@material-ui/core/DialogActions"
|
||||
import DialogContent from "@material-ui/core/DialogContent"
|
||||
import DialogTitle from "@material-ui/core/DialogTitle"
|
||||
import Typography from "@material-ui/core/Typography"
|
||||
import IconButton from "@material-ui/core/IconButton"
|
||||
import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline"
|
||||
import CircularProgress from "@material-ui/core/CircularProgress"
|
||||
|
||||
import { i18n } from "../../translate/i18n";
|
||||
import { i18n } from "../../translate/i18n"
|
||||
|
||||
import api from "../../services/api";
|
||||
import toastError from "../../errors/toastError";
|
||||
import api from "../../services/api"
|
||||
import toastError from "../../errors/toastError"
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
root: {
|
||||
|
@ -50,7 +50,7 @@ const useStyles = makeStyles(theme => ({
|
|||
marginTop: -12,
|
||||
marginLeft: -12,
|
||||
},
|
||||
}));
|
||||
}))
|
||||
|
||||
const ContactSchema = Yup.object().shape({
|
||||
name: Yup.string()
|
||||
|
@ -60,75 +60,77 @@ const ContactSchema = Yup.object().shape({
|
|||
number: Yup.string().min(8, "Too Short!").max(50, "Too Long!"),
|
||||
|
||||
email: Yup.string().min(2, "Too Short!")
|
||||
.max(50, "Too Long!"),
|
||||
.max(50, "Too Long!"),
|
||||
|
||||
// email: Yup.string().email("Invalid email"),
|
||||
});
|
||||
})
|
||||
|
||||
const ContactModal = ({ open, onClose, contactId, initialValues, onSave }) => {
|
||||
const classes = useStyles();
|
||||
const isMounted = useRef(true);
|
||||
const classes = useStyles()
|
||||
const isMounted = useRef(true)
|
||||
|
||||
const initialState = {
|
||||
name: "",
|
||||
number: "",
|
||||
email: "",
|
||||
useDialogflow: true,
|
||||
};
|
||||
}
|
||||
|
||||
const [contact, setContact] = useState(initialState);
|
||||
const [contact, setContact] = useState(initialState)
|
||||
const [isSaving, setSaving] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
isMounted.current = false;
|
||||
};
|
||||
}, []);
|
||||
isMounted.current = false
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
const fetchContact = async () => {
|
||||
if (initialValues) {
|
||||
setContact(prevState => {
|
||||
return { ...prevState, ...initialValues };
|
||||
});
|
||||
return { ...prevState, ...initialValues }
|
||||
})
|
||||
}
|
||||
|
||||
if (!contactId) return;
|
||||
if (!contactId) return
|
||||
|
||||
try {
|
||||
const { data } = await api.get(`/contacts/${contactId}`);
|
||||
const { data } = await api.get(`/contacts/${contactId}`)
|
||||
if (isMounted.current) {
|
||||
setContact(data);
|
||||
setContact(data)
|
||||
}
|
||||
} catch (err) {
|
||||
toastError(err);
|
||||
toastError(err)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fetchContact();
|
||||
}, [contactId, open, initialValues]);
|
||||
fetchContact()
|
||||
}, [contactId, open, initialValues])
|
||||
|
||||
const handleClose = () => {
|
||||
onClose();
|
||||
setContact(initialState);
|
||||
};
|
||||
onClose()
|
||||
setContact(initialState)
|
||||
}
|
||||
|
||||
const handleSaveContact = async values => {
|
||||
try {
|
||||
try {
|
||||
if (contactId) {
|
||||
await api.put(`/contacts/${contactId}`, values);
|
||||
handleClose();
|
||||
await api.put(`/contacts/${contactId}`, values)
|
||||
handleClose()
|
||||
} else {
|
||||
const { data } = await api.post("/contacts", values);
|
||||
const { data } = await api.post("/contacts", values)
|
||||
if (onSave) {
|
||||
onSave(data);
|
||||
onSave(data)
|
||||
}
|
||||
handleClose();
|
||||
handleClose()
|
||||
}
|
||||
toast.success(i18n.t("contactModal.success"));
|
||||
toast.success(i18n.t("contactModal.success"))
|
||||
} catch (err) {
|
||||
toastError(err);
|
||||
toastError(err)
|
||||
}
|
||||
};
|
||||
setSaving(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
|
@ -143,10 +145,11 @@ const ContactModal = ({ open, onClose, contactId, initialValues, onSave }) => {
|
|||
enableReinitialize={true}
|
||||
validationSchema={ContactSchema}
|
||||
onSubmit={(values, actions) => {
|
||||
setSaving(true)
|
||||
setTimeout(() => {
|
||||
handleSaveContact(values);
|
||||
actions.setSubmitting(false);
|
||||
}, 400);
|
||||
handleSaveContact(values)
|
||||
actions.setSubmitting(false)
|
||||
}, 400)
|
||||
}}
|
||||
>
|
||||
{({ values, errors, touched, isSubmitting }) => (
|
||||
|
@ -256,14 +259,14 @@ const ContactModal = ({ open, onClose, contactId, initialValues, onSave }) => {
|
|||
<Button
|
||||
type="submit"
|
||||
color="primary"
|
||||
disabled={isSubmitting}
|
||||
disabled={isSaving}
|
||||
variant="contained"
|
||||
className={classes.btnWrapper}
|
||||
>
|
||||
{contactId
|
||||
? `${i18n.t("contactModal.buttons.okEdit")}`
|
||||
: `${i18n.t("contactModal.buttons.okAdd")}`}
|
||||
{isSubmitting && (
|
||||
{isSaving && (
|
||||
<CircularProgress
|
||||
size={24}
|
||||
className={classes.buttonProgress}
|
||||
|
@ -276,7 +279,7 @@ const ContactModal = ({ open, onClose, contactId, initialValues, onSave }) => {
|
|||
</Formik>
|
||||
</Dialog>
|
||||
</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
|
||||
|
||||
try {
|
||||
const { data } = await api.get(`whatsapp/${whatsAppId}`)
|
||||
const { data } = await api.get(`whatsapp/${whatsAppId}`)
|
||||
|
||||
setWhatsApp(data)
|
||||
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 api from "../../services/api"
|
||||
import SelectField from "../../components/Report/SelectField"
|
||||
|
@ -17,6 +17,8 @@ import Checkbox from '@mui/material/Checkbox'
|
|||
import { Button } from "@material-ui/core"
|
||||
|
||||
import ReportModal from "../../components/ReportModal"
|
||||
import ReportModalType from "../../components/ReportModalType"
|
||||
|
||||
import MaterialTable from 'material-table'
|
||||
|
||||
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 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) => {
|
||||
|
@ -276,21 +281,16 @@ const Report = () => {
|
|||
const [hasMore, setHasMore] = useState(false)
|
||||
const [pageNumberTickets, setTicketsPageNumber] = useState(1)
|
||||
const [totalCountTickets, setTotalCountTickets] = useState(0)
|
||||
|
||||
|
||||
|
||||
const [pageNumber, setPageNumber] = useState(1)
|
||||
const [users, dispatch] = useReducer(reducer, [])
|
||||
const [startDate, setDatePicker1] = useState(new Date())
|
||||
const [endDate, setDatePicker2] = useState(new Date())
|
||||
const [userId, setUser] = useState(null)
|
||||
const [query, dispatchQ] = useReducer(reducerQ, [])
|
||||
|
||||
const [reportOption, setReport] = useState('1')
|
||||
const [reporList,] = useState(report)
|
||||
const [profile, setProfile] = useState('')
|
||||
const [dataRows, setData] = useState([])
|
||||
|
||||
const [onQueueStatus, setOnQueueProcessStatus] = useState(undefined)
|
||||
const [csvFile, setCsvFile] = useState()
|
||||
const [selectedValue, setSelectedValue] = useState('created')
|
||||
|
@ -298,6 +298,11 @@ const Report = () => {
|
|||
const [queues, setQueues] = useState([])
|
||||
const [queueId, setQueue] = useState(null)
|
||||
|
||||
const [reportTypeList,] = useState(reportOptType)
|
||||
const [reportType, setReportType] = useState('1')
|
||||
const [firstLoad, setFirstLoad] = useState(true);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
dispatch({ type: "RESET" })
|
||||
dispatchQ({ type: "RESET" })
|
||||
|
@ -306,6 +311,14 @@ const Report = () => {
|
|||
}, [searchParam, profile])
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (firstLoad) {
|
||||
setFirstLoad(false)
|
||||
} else {
|
||||
|
||||
}
|
||||
}, [firstLoad]);
|
||||
|
||||
useEffect(() => {
|
||||
//setLoading(true);
|
||||
|
||||
|
@ -337,16 +350,14 @@ const Report = () => {
|
|||
useEffect(() => {
|
||||
|
||||
//setLoading(true);
|
||||
if (firstLoad) return
|
||||
|
||||
const delayDebounceFn = setTimeout(() => {
|
||||
|
||||
const delayDebounceFn = setTimeout(() => {
|
||||
setLoading(true)
|
||||
const fetchQueries = async () => {
|
||||
try {
|
||||
if (reportOption === '1') {
|
||||
|
||||
// const { data } = await api.get("/reports/", { params: { userId: userId ? userId : 0, startDate: convertAndFormatDate(startDate), endDate: convertAndFormatDate(endDate), pageNumber: pageNumberTickets }, })
|
||||
|
||||
if (reportOption === '1') {
|
||||
|
||||
const { data } = await api.get("/reports/", { params: { userId, startDate, endDate, pageNumber: pageNumberTickets, createdOrUpdated: selectedValue, queueId }, userQueues: userA.queues })
|
||||
|
||||
let ticketsQueue = data.tickets
|
||||
|
@ -424,8 +435,21 @@ const Report = () => {
|
|||
setChecked(true)
|
||||
}
|
||||
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(() => {
|
||||
|
||||
if (reportOption === '1') {
|
||||
|
@ -500,7 +524,7 @@ const Report = () => {
|
|||
|
||||
|
||||
|
||||
const handleCSVMessages = () => {
|
||||
const handleCSVMessages = (type = 'default') => {
|
||||
|
||||
const fetchQueries = async () => {
|
||||
|
||||
|
@ -519,7 +543,8 @@ const Report = () => {
|
|||
userId: userId,
|
||||
startDate: startDate,
|
||||
endDate: endDate
|
||||
}
|
||||
},
|
||||
query_type: type
|
||||
})
|
||||
|
||||
const onQueueStatus = querySavedOnQueue.data.queueStatus
|
||||
|
@ -639,7 +664,10 @@ const Report = () => {
|
|||
case 'empty':
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
{query && query.length > 0 &&
|
||||
<ReportModalType currencies={reportTypeList} func={reportTypeValue} reportOption={reportType} />
|
||||
}
|
||||
{/* <Button
|
||||
disabled={query && query.length > 0 ? false : true}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
|
@ -648,7 +676,8 @@ const Report = () => {
|
|||
}}
|
||||
>
|
||||
{"CSV ALL"}
|
||||
</Button>
|
||||
|
||||
</Button> */}
|
||||
</>)
|
||||
|
||||
case 'pending' || 'processing':
|
||||
|
|
Loading…
Reference in New Issue