feat: Implement solution for searching by message content and fix bug when closing ticket
parent
beb4fd64c4
commit
e71150ff75
|
@ -0,0 +1,23 @@
|
|||
const monthsAgo = (months: number) => {
|
||||
const { subMonths, startOfMonth, format } = require("date-fns");
|
||||
|
||||
// Get the current date
|
||||
const currentDate = new Date();
|
||||
|
||||
// Subtract 4 months from the current date
|
||||
const monthsAgo = subMonths(currentDate, months);
|
||||
|
||||
// Get the start of the month for the current date and four months ago
|
||||
// const startOfCurrentMonth = startOfMonth(currentDate);
|
||||
const startMonthsAgo = startOfMonth(monthsAgo);
|
||||
|
||||
// Format the dates in YYYY-MM-DD format
|
||||
// const formattedCurrentMonth = format(startOfCurrentMonth, "yyyy-MM-dd");
|
||||
const formattedMonthsAgo = format(startMonthsAgo, "yyyy-MM-dd");
|
||||
|
||||
// console.log("Current Month:", formattedCurrentMonth);
|
||||
// console.log("Months Ago:", formattedMonthsAgo);
|
||||
return formattedMonthsAgo;
|
||||
};
|
||||
|
||||
export default monthsAgo;
|
|
@ -29,7 +29,7 @@ export async function getSimple(key: string) {
|
|||
|
||||
export async function get({ key, value, parse }: getData) {
|
||||
if (key.includes("*")) {
|
||||
const keys = await redis.keys(key);
|
||||
const keys = await redis.keys(key);
|
||||
if (keys.length > 0) {
|
||||
if (value) {
|
||||
for (const key of keys) {
|
||||
|
@ -70,7 +70,7 @@ export async function clearAllKeys(...keys: string[]) {
|
|||
|
||||
// If there are keys, delete them
|
||||
if (del_keys.length > 0) {
|
||||
console.log("del_keys: ", del_keys);
|
||||
// console.log("del_keys: ", del_keys);
|
||||
await redis.del(...del_keys);
|
||||
}
|
||||
}
|
||||
|
@ -220,3 +220,5 @@ export async function getHashesWithPattern(
|
|||
|
||||
return hashes;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -6,14 +6,18 @@ import { StartAllWhatsAppsSessions } from "./services/WbotServices/StartAllWhats
|
|||
import User from "./models/User";
|
||||
import Whatsapp from "./models/Whatsapp";
|
||||
import endPointQuery from "./helpers/EndPointQuery";
|
||||
import { cacheSize, flushCache, loadTicketsCache } from "./helpers/TicketCache";
|
||||
import {
|
||||
cacheSize,
|
||||
flushCache,
|
||||
loadTicketsCache,
|
||||
} from "./helpers/TicketCache";
|
||||
|
||||
import "./helpers/CloseBotTickets";
|
||||
import { loadContactsCache } from "./helpers/ContactsCache";
|
||||
import { loadSchedulesCache } from "./helpers/SchedulingNotifyCache";
|
||||
import { delRestoreControllFile } from "./helpers/RestoreControll";
|
||||
import "./helpers/AutoCloseTickets";
|
||||
import "./helpers/AutoRemoteTickets"
|
||||
import "./helpers/AutoRemoteTickets";
|
||||
|
||||
import "./helpers/SchedulingNotifySendMessage";
|
||||
import axios from "axios";
|
||||
|
@ -30,6 +34,7 @@ import { json } from "sequelize";
|
|||
import { setBotInfo } from "./helpers/SetBotInfo";
|
||||
import Queue from "./models/Queue";
|
||||
import StatusChatEnd from "./models/StatusChatEnd";
|
||||
import Message from "./models/Message";
|
||||
|
||||
const server = app.listen(process.env.PORT, () => {
|
||||
logger.info(`Server started on port: ${process.env.PORT}`);
|
||||
|
@ -50,7 +55,21 @@ gracefulShutdown(server);
|
|||
(async () => {
|
||||
console.log("os.tmpdir(): ", os.tmpdir());
|
||||
|
||||
await clearAllKeys("user:*", "whatsapp:*", "queue:*", "statusChatEnd:*");
|
||||
await clearAllKeys(
|
||||
"user:*",
|
||||
"whatsapp:*",
|
||||
"queue:*",
|
||||
"statusChatEnd:*",
|
||||
);
|
||||
|
||||
// let messages: any = await Message.findAll({
|
||||
// attributes: ["id", "ticketId", "body"]
|
||||
// });
|
||||
|
||||
// for (const message of messages) {
|
||||
// const { id, body, ticketId } = message;
|
||||
// await set(`message:ticketId:${ticketId}:id:${id}`, body);
|
||||
// }
|
||||
|
||||
const statusChatEnds = await StatusChatEnd.findAll();
|
||||
|
||||
|
@ -90,17 +109,17 @@ gracefulShutdown(server);
|
|||
try {
|
||||
const { phoneNumberId, id, greetingMessage } = whatsapps[i];
|
||||
|
||||
if (phoneNumberId) {
|
||||
// await set(
|
||||
// `whatsapp:${whatsapps[i].dataValues.id}`,
|
||||
// JSON.stringify({
|
||||
// number: whatsapps[i].dataValues.number,
|
||||
// id,
|
||||
// greetingMessage,
|
||||
// phoneNumberId
|
||||
// })
|
||||
// );
|
||||
}
|
||||
// if (phoneNumberId) {
|
||||
// await set(
|
||||
// `whatsapp:${whatsapps[i].dataValues.id}`,
|
||||
// JSON.stringify({
|
||||
// number: whatsapps[i].dataValues.number,
|
||||
// id,
|
||||
// greetingMessage,
|
||||
// phoneNumberId
|
||||
// })
|
||||
// );
|
||||
// }
|
||||
|
||||
await set(
|
||||
`whatsapp:${whatsapps[i].dataValues.id}`,
|
||||
|
|
|
@ -15,12 +15,10 @@ const dateToday = splitDateTime(
|
|||
new Date(format(new Date(), "yyyy-MM-dd HH:mm:ss", { locale: ptBR }))
|
||||
);
|
||||
|
||||
import ListTicketServiceCache from "./ListTicketServiceCache";
|
||||
|
||||
import { searchTicketCache, loadTicketsCache } from "../../helpers/TicketCache";
|
||||
import { getWbot } from "../../libs/wbot";
|
||||
import User from "../../models/User";
|
||||
import { get } from "../../helpers/RedisClient";
|
||||
import monthsAgo from "../../helpers/MonthsAgo";
|
||||
|
||||
interface Request {
|
||||
searchParam?: string;
|
||||
|
@ -54,7 +52,12 @@ const ListTicketsService = async ({
|
|||
unlimited = "false",
|
||||
searchParamContent = ""
|
||||
}: Request): Promise<Response> => {
|
||||
console.log("----------> searchParamContent: ", searchParamContent);
|
||||
console.log(
|
||||
"----------> searchParamContent: ",
|
||||
searchParamContent,
|
||||
" | searchParam: ",
|
||||
searchParam
|
||||
);
|
||||
|
||||
let whereCondition: Filterable["where"] = {
|
||||
[Op.or]: [{ userId }, { status: "pending" }],
|
||||
|
@ -67,46 +70,46 @@ const ListTicketsService = async ({
|
|||
pageNumber = "1";
|
||||
}
|
||||
|
||||
if (searchParam && searchParam.trim().length > 0 && process.env.CACHE) {
|
||||
try {
|
||||
const offset = 40 * (+pageNumber - 1);
|
||||
// if (searchParam && searchParam.trim().length > 0 && process.env.CACHE) {
|
||||
// try {
|
||||
// const offset = 40 * (+pageNumber - 1);
|
||||
|
||||
searchParam = searchParam.replace(/\s+/g, " ").trim().toLowerCase();
|
||||
// searchParam = searchParam.replace(/\s+/g, " ").trim().toLowerCase();
|
||||
|
||||
console.log("QUERY TICKET SEARCH PARAM FROM CACHE: ", searchParam);
|
||||
// console.log("QUERY TICKET SEARCH PARAM FROM CACHE: ", searchParam);
|
||||
|
||||
let tickets: any = await searchTicketCache(searchParam, offset, 40);
|
||||
// let tickets: any = await searchTicketCache(searchParam, offset, 40);
|
||||
|
||||
if (tickets) {
|
||||
console.log(
|
||||
"QUERY TICKET SEARCH PARAM FROM CACHE LENGTH...: ",
|
||||
tickets.length
|
||||
);
|
||||
// if (tickets) {
|
||||
// console.log(
|
||||
// "QUERY TICKET SEARCH PARAM FROM CACHE LENGTH...: ",
|
||||
// tickets.length
|
||||
// );
|
||||
|
||||
tickets.map((t: any) => {
|
||||
t["contact.number"] = t["contact_number"];
|
||||
delete t["contact_number"];
|
||||
// tickets.map((t: any) => {
|
||||
// t["contact.number"] = t["contact_number"];
|
||||
// delete t["contact_number"];
|
||||
|
||||
return { ...["contact_number"] };
|
||||
});
|
||||
// return { ...["contact_number"] };
|
||||
// });
|
||||
|
||||
tickets = tickets.map((e: any) => unflatten(e));
|
||||
// tickets = tickets.map((e: any) => unflatten(e));
|
||||
|
||||
return {
|
||||
tickets,
|
||||
count: tickets.length,
|
||||
hasMore: tickets.length > 0 ? true : false
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(
|
||||
"There was an error on search ListTicketservice.ts search cache: ",
|
||||
error
|
||||
);
|
||||
}
|
||||
// return {
|
||||
// tickets,
|
||||
// count: tickets.length,
|
||||
// hasMore: tickets.length > 0 ? true : false
|
||||
// };
|
||||
// }
|
||||
// } catch (error) {
|
||||
// console.log(
|
||||
// "There was an error on search ListTicketservice.ts search cache: ",
|
||||
// error
|
||||
// );
|
||||
// }
|
||||
|
||||
console.log("QUERY TICKETS FROM DATABASE...");
|
||||
}
|
||||
// console.log("QUERY TICKETS FROM DATABASE...");
|
||||
// }
|
||||
|
||||
let includeCondition: Includeable[];
|
||||
|
||||
|
@ -143,38 +146,32 @@ const ListTicketsService = async ({
|
|||
|
||||
if (searchParam) {
|
||||
const sanitizedSearchParam = searchParam.toLocaleLowerCase().trim();
|
||||
const sanitizedSearchParamContent = searchParamContent
|
||||
.toLocaleLowerCase()
|
||||
.trim();
|
||||
|
||||
if (searchParamContent.length > 0) {
|
||||
includeCondition = [
|
||||
...includeCondition,
|
||||
{
|
||||
model: Message,
|
||||
as: "messages",
|
||||
attributes: ["id", "body"],
|
||||
where: {
|
||||
body: where(
|
||||
fn("LOWER", col("body")),
|
||||
"LIKE",
|
||||
`%${sanitizedSearchParamContent}%`
|
||||
)
|
||||
},
|
||||
required: false,
|
||||
duplicating: false
|
||||
}
|
||||
];
|
||||
includeCondition = [
|
||||
...includeCondition,
|
||||
{
|
||||
model: Message,
|
||||
as: "messages",
|
||||
attributes: ["id", "body"],
|
||||
where: {
|
||||
body: where(
|
||||
fn("LOWER", col("body")),
|
||||
"LIKE",
|
||||
`%${sanitizedSearchParam}%`
|
||||
)
|
||||
},
|
||||
required: false,
|
||||
duplicating: false
|
||||
}
|
||||
];
|
||||
|
||||
whereCondition = {
|
||||
...whereCondition,
|
||||
"$message.body$": where(
|
||||
fn("LOWER", col("body")),
|
||||
"LIKE",
|
||||
`%${sanitizedSearchParamContent}%`
|
||||
)
|
||||
};
|
||||
}
|
||||
whereCondition = {
|
||||
...whereCondition,
|
||||
createdAt: {
|
||||
[Op.gte]: monthsAgo(4) + " 00:00:00.000000",
|
||||
[Op.lte]: dateToday.fullDate + " 23:59:59.999999"
|
||||
}
|
||||
};
|
||||
|
||||
whereCondition = {
|
||||
...whereCondition,
|
||||
|
@ -186,11 +183,65 @@ const ListTicketsService = async ({
|
|||
`%${sanitizedSearchParam}%`
|
||||
)
|
||||
},
|
||||
|
||||
{ "$contact.number$": { [Op.like]: `%${sanitizedSearchParam}%` } }
|
||||
{ "$contact.number$": { [Op.like]: `%${sanitizedSearchParam}%` } },
|
||||
{
|
||||
"$message.body$": where(
|
||||
fn("LOWER", col("body")),
|
||||
"LIKE",
|
||||
`%${sanitizedSearchParam}%`
|
||||
)
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// const sanitizedSearchParamContent = searchParamContent
|
||||
// .toLocaleLowerCase()
|
||||
// .trim();
|
||||
|
||||
// if (searchParamContent.length > 0) {
|
||||
// includeCondition = [
|
||||
// ...includeCondition,
|
||||
// {
|
||||
// model: Message,
|
||||
// as: "messages",
|
||||
// attributes: ["id", "body"],
|
||||
// where: {
|
||||
// body: where(
|
||||
// fn("LOWER", col("body")),
|
||||
// "LIKE",
|
||||
// `%${sanitizedSearchParamContent}%`
|
||||
// )
|
||||
// },
|
||||
// required: false,
|
||||
// duplicating: false
|
||||
// }
|
||||
// ];
|
||||
|
||||
// whereCondition = {
|
||||
// ...whereCondition,
|
||||
// "$message.body$": where(
|
||||
// fn("LOWER", col("body")),
|
||||
// "LIKE",
|
||||
// `%${sanitizedSearchParamContent}%`
|
||||
// )
|
||||
// };
|
||||
// }
|
||||
|
||||
// whereCondition = {
|
||||
// ...whereCondition,
|
||||
// [Op.or]: [
|
||||
// {
|
||||
// "$contact.name$": where(
|
||||
// fn("LOWER", col("contact.name")),
|
||||
// "LIKE",
|
||||
// `%${sanitizedSearchParam}%`
|
||||
// )
|
||||
// },
|
||||
|
||||
// { "$contact.number$": { [Op.like]: `%${sanitizedSearchParam}%` } }
|
||||
// ]
|
||||
// };
|
||||
|
||||
const userProfile: any = await User.findByPk(userId);
|
||||
|
||||
if (
|
||||
|
@ -243,8 +294,8 @@ const ListTicketsService = async ({
|
|||
|
||||
const hasMore = count > offset + tickets.length;
|
||||
|
||||
const ticketIds = await get({ key: `remote:controll`, parse: true });
|
||||
|
||||
const ticketIds = await get({ key: `remote:controll`, parse: true });
|
||||
|
||||
return {
|
||||
tickets,
|
||||
count,
|
||||
|
|
|
@ -75,16 +75,19 @@ const UpdateTicketService = async ({
|
|||
del(`remote:ticketId:${ticket.id}`);
|
||||
|
||||
let ticketsIds = await get({ key: `remote:controll`, parse: true });
|
||||
const index = ticketsIds.findIndex((t: any) => t == ticket.id);
|
||||
|
||||
console.log("ticketsIds 1: ", ticketsIds);
|
||||
if (ticketsIds) {
|
||||
const index = ticketsIds.findIndex((t: any) => t == ticket.id);
|
||||
|
||||
if (index != -1) {
|
||||
ticketsIds.splice(index, 1);
|
||||
console.log("ticketsIds 1: ", ticketsIds);
|
||||
|
||||
console.log("ticketsIds 2: ", ticketsIds);
|
||||
if (index != -1) {
|
||||
ticketsIds.splice(index, 1);
|
||||
|
||||
set(`remote:controll`, JSON.stringify(ticketsIds));
|
||||
console.log("ticketsIds 2: ", ticketsIds);
|
||||
|
||||
set(`remote:controll`, JSON.stringify(ticketsIds));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -346,7 +346,7 @@ const TicketsManager = () => {
|
|||
{/* <IconButton onClick={() => setShowContentSearch(prev => !prev)}>
|
||||
<MenuIcon className={classes.menuSearch} />
|
||||
</IconButton> */}
|
||||
<Tooltip
|
||||
{/* <Tooltip
|
||||
open={openTooltipSearch}
|
||||
onOpen={() => handleOpenTooltipSearch()}
|
||||
onClose={() => handleCloseTooltipSearch()}
|
||||
|
@ -360,22 +360,22 @@ const TicketsManager = () => {
|
|||
<MenuIcon className={classes.menuSearch} />
|
||||
</IconButton>
|
||||
</span>
|
||||
</Tooltip>
|
||||
</Tooltip> */}
|
||||
</div>
|
||||
{
|
||||
// showContentSearch ?
|
||||
(showContentSearch && searchParam.searchParam.length >= 4) ?
|
||||
(<div className={classes.searchContentInput}>
|
||||
<FindInPageIcon className={classes.searchIcon} />
|
||||
<InputBase
|
||||
className={classes.searchInput}
|
||||
inputRef={searchContentInputRef}
|
||||
placeholder={i18n.t("Busca por conteúdo")}
|
||||
type="search"
|
||||
value={inputContentSearch}
|
||||
onChange={(e) => handleContentSearch(e)}
|
||||
/>
|
||||
</div>) : null
|
||||
// (showContentSearch /*&& searchParam.searchParam.length >= 4*/) ?
|
||||
// (<div className={classes.searchContentInput}>
|
||||
// <FindInPageIcon className={classes.searchIcon} />
|
||||
// <InputBase
|
||||
// className={classes.searchInput}
|
||||
// inputRef={searchContentInputRef}
|
||||
// placeholder={i18n.t("Busca por conteúdo")}
|
||||
// type="search"
|
||||
// value={inputContentSearch}
|
||||
// onChange={(e) => handleContentSearch(e)}
|
||||
// />
|
||||
// </div>) : null
|
||||
}
|
||||
</div>
|
||||
) : (
|
||||
|
|
Loading…
Reference in New Issue