feat: Implement Redis solution for querying WhatsApp number in webhook controller
parent
943d121ab1
commit
2fc732eec1
|
@ -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();
|
||||||
|
@ -342,3 +324,5 @@ export const remove = async (
|
||||||
|
|
||||||
return res.status(200).json({ message: "User deleted" });
|
return res.status(200).json({ message: "User deleted" });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 { get, set } from "../helpers/RedisClient";
|
||||||
|
|
||||||
interface WhatsappData {
|
interface WhatsappData {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -229,6 +230,22 @@ 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_from_exist = await get("whatsapp:*", `${contact_from}`);
|
||||||
|
|
||||||
|
if (!contact_from_exist) {
|
||||||
|
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];
|
||||||
|
@ -382,6 +399,8 @@ 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}`, `${number}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const io = getIO();
|
const io = getIO();
|
||||||
|
@ -441,6 +460,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({
|
||||||
|
@ -455,6 +475,8 @@ 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}`, `${number}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const io = getIO();
|
const io = getIO();
|
||||||
|
|
|
@ -9,25 +9,42 @@ type WhatsappData = {
|
||||||
};
|
};
|
||||||
|
|
||||||
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 get(key: string, value?: string) {
|
||||||
|
if (key.includes("*")) {
|
||||||
|
const keys = await redis.keys(key);
|
||||||
|
|
||||||
|
// If there are keys, delete them
|
||||||
|
if (keys.length > 0) {
|
||||||
|
for (const key of keys) {
|
||||||
|
const val = await redis.get(key);
|
||||||
|
if (value == val) return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
const value: any = await redis.get(key);
|
||||||
|
return JSON.parse(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 +71,7 @@ export async function findByContain(
|
||||||
results.push(obj);
|
results.push(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,7 +23,10 @@ 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";
|
||||||
|
|
||||||
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,24 +42,30 @@ 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:*");
|
||||||
|
|
||||||
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 });
|
||||||
}
|
}
|
||||||
|
|
||||||
loadSettings();
|
loadSettings();
|
||||||
|
|
||||||
let whatsapps: any = await Whatsapp.findAll({
|
let whatsapps: any = await Whatsapp.findAll({
|
||||||
attributes: ["id", "url", "phoneNumberId"]
|
attributes: ["id", "url", "phoneNumberId", "number"]
|
||||||
});
|
});
|
||||||
|
|
||||||
if (whatsapps && whatsapps.length > 0) {
|
if (whatsapps && whatsapps.length > 0) {
|
||||||
|
@ -64,7 +73,14 @@ gracefulShutdown(server);
|
||||||
try {
|
try {
|
||||||
const { phoneNumberId } = whatsapps[i];
|
const { phoneNumberId } = whatsapps[i];
|
||||||
|
|
||||||
if (phoneNumberId) continue;
|
if (phoneNumberId) {
|
||||||
|
await set(
|
||||||
|
`whatsapp:${whatsapps[i].dataValues.id}`,
|
||||||
|
`${whatsapps[i].dataValues.number}`
|
||||||
|
);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
`API URL: ${whatsapps[i].dataValues.url}/api/connection/status`
|
`API URL: ${whatsapps[i].dataValues.url}/api/connection/status`
|
||||||
|
|
|
@ -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
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue