From 3aae93141a313566bf7b7746a619952e5799e908 Mon Sep 17 00:00:00 2001 From: adriano Date: Mon, 14 Nov 2022 11:21:58 -0300 Subject: [PATCH 01/12] =?UTF-8?q?Cria=C3=A7=C3=A3o=20de=20coluna=20number?= =?UTF-8?q?=20na=20tabela=20whatsapp=20e=20desenvolvimento=20do=20ignore?= =?UTF-8?q?=20id=20from=20message?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...112040251-add-number-column-to-whatsapp.ts | 13 + .../helpers/LastMessageIdByContactCache.ts | 262 ++++++++++++++++++ backend/src/helpers/TicketCache.ts | 4 +- backend/src/libs/wbot.ts | 7 +- backend/src/models/Whatsapp.ts | 3 + .../WbotServices/SendWhatsAppMessage.ts | 46 ++- .../WbotServices/wbotMessageListener.ts | 86 +++++- .../WhatsappService/ListWhatsAppsNumber.ts | 28 ++ 8 files changed, 422 insertions(+), 27 deletions(-) create mode 100644 backend/src/database/migrations/20221112040251-add-number-column-to-whatsapp.ts create mode 100644 backend/src/helpers/LastMessageIdByContactCache.ts create mode 100644 backend/src/services/WhatsappService/ListWhatsAppsNumber.ts diff --git a/backend/src/database/migrations/20221112040251-add-number-column-to-whatsapp.ts b/backend/src/database/migrations/20221112040251-add-number-column-to-whatsapp.ts new file mode 100644 index 0000000..58cd82e --- /dev/null +++ b/backend/src/database/migrations/20221112040251-add-number-column-to-whatsapp.ts @@ -0,0 +1,13 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Whatsapps", "number", { + type: DataTypes.TEXT + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Whatsapps", "number"); + } +}; diff --git a/backend/src/helpers/LastMessageIdByContactCache.ts b/backend/src/helpers/LastMessageIdByContactCache.ts new file mode 100644 index 0000000..15e26a4 --- /dev/null +++ b/backend/src/helpers/LastMessageIdByContactCache.ts @@ -0,0 +1,262 @@ + +import Redis from 'ioredis' +import { type } from 'os' +const unflatten = require('flat').unflatten +var flatten = require('flat') +import ListContactsServiceCache from "../services/ContactServices/ListContactsServiceCache" +import { redisConn } from './TicketCache' + + +const deleteContactsByIdCache = async (id: string | number) => { + + const redis: any = await redisConn(); + + if (!redis) return + + if (redis.status !== 'connect') return + + const contact_cache: any = await redis.hgetall(`contact:${id}`) + + try { + if (contact_cache && Object.keys(contact_cache).length > 0) { + + await redis.del(`contact:${id}`) + + console.log(`Contacts cache number ${contact_cache['number']} deleted!`) + } + else { + console.log('CONTACT CACHE NOT FOUND!') + } + } catch (error) { + console.log(`There was an error on deleteContactsByIdCache: ${error}`) + } + + redis.quit() +} + +const updateContactCache = async (hash: any, json_object: any) => { + + const redis: any = await redisConn(); + + if (!redis) return + + if (redis.status !== 'connect') return + + const pipeline = redis.pipeline() + + let entries = Object.entries(json_object) + + entries.forEach((e: any) => { + pipeline.hset(hash, e[0], e[1]) + }) + + await pipeline.exec(() => { console.log("Key/value inserted/updated") }); + + redis.quit() + +} + +const updateContactCacheById = async (id: string | number, update_fields: object | any) => { + + const redis: any = await redisConn(); + + if (!redis) return + + if (redis.status !== 'connect') return + + const contact_cache: any = await redis.hgetall(`contact:${id}`) + + try { + if (contact_cache && Object.keys(contact_cache).length > 0) { + + // await redis.del(`contact:${id}`) + + update_fields.escaped_name = escapeCharCache(update_fields.name) + + await updateContactCache(`contact:${id}`, update_fields) + + console.log(`CONTACT ${contact_cache['number']} CACHE WAS UPDATED!`) + } + else { + console.log('CONTACT CACHE NOT FOUND!') + } + } catch (error) { + console.log(`There was an error on updateContactCacheById: ${error}`) + } + + redis.quit() +} + +const createOrUpdateContactCache = async (hash: any, contact: any) => { + + const redis: any = await redisConn(); + + if (!redis) return + + if (redis.status !== 'connect') return + + if (contact.name) { + contact.escaped_name = escapeCharCache(contact.name) + } + + await redis.hmset(hash, contact); + + redis.quit() + +} + + +async function searchContactCache(search: string, offset: number, limit: number) { + + const redis: any = await redisConn(); + + if (!redis) return + + if (redis.status !== 'connect') return null + + search = escapeCharCache(search) + + const response: any = await redis.call('FT.SEARCH', 'idx_contact_message', `(@escaped_name:*${search}*)|(@number:*${search}*)`, 'LIMIT', offset, limit, 'SORTBY', 'escaped_name', 'ASC') + redis.quit() + + + if (response.length === 1) { + return [] + } + + const results: any = [] + + for (let n = 2; n < response.length; n += 2) { + const result: any = {} + const fieldNamesAndValues = response[n] + + for (let m = 0; m < fieldNamesAndValues.length; m += 2) { + const k = fieldNamesAndValues[m] + const v = fieldNamesAndValues[m + 1] + result[k] = v + } + + results.push(result) + } + + return results +} + + +const removeExtraSpace = (str: string) => { + + str = str.replace(/^\s+/g, '') + + return str.replace(/\s+/g, ' ') +} + +const escapeCharCache = (str: string) => { + + const pattern = /[\'|\"|\.|\,|\;|\<|\>|\{|\}|\[|\]|\"|\'|\=|\~|\*|\:|\#|\+|\^|\$|\@|\%|\!|\&|\)|\(|/|\-|\\)]/g; // no match, use replace function. + + let newStr = str.replace(pattern, (t1) => `\\${t1}`); + + newStr = removeExtraSpace(newStr) + + return newStr.trim() + +} + +const getLastId = async (hash: any) => { + + const redis: any = await redisConn(); + + if (!redis) return + + if (redis.status !== 'connect') return + + const contact_cache: any = await redis.hgetall(hash) + + return contact_cache + +} + +const insertMessageContactCache = async (hash: any, contact_message: any) => { + + const redis: any = await redisConn(); + + if (!redis) return + + if (redis.status !== 'connect') return + + await redis.hmset(hash, contact_message); + + console.log('CREATED/UPDATED CONTACT MESSAGE') + + redis.quit() + +} + +const loadContactsCache = async () => { + + await createContactMessageIndexCache('idx_contact_message') + + const redis: any = await redisConn(); + + if (!redis) return + + if (redis.status !== 'connect') return + + let contacts = await ListContactsServiceCache() + + const pipeline = redis.pipeline() + + for (let i = 0; i < contacts.length; i++) { + + contacts[i].createdAt = new Date(contacts[i].createdAt).toISOString() + contacts[i].updatedAt = new Date(contacts[i].updatedAt).toISOString() + + contacts[i].escaped_name = escapeCharCache(contacts[i].name) + + pipeline.hmset(`contact:${contacts[i].id}`, contacts[i]); + } + + await pipeline.exec(() => { console.log(`${contacts.length} CONTACTS INSERTED IN CACHE!`) }); + + redis.quit() +} + +const createContactMessageIndexCache = async (hashIndex: string) => { + + const redis: any = await redisConn(); + + if (!redis) return + + if (redis.status !== 'connect') return + + try { + + const lst_index_redis: any = await redis.call('FT._LIST') + + if (lst_index_redis.includes(hashIndex)) { + console.log('entrou...') + await redis.call('FT.DROPINDEX', hashIndex) + } + + const response = await redis.call('FT.CREATE', hashIndex, 'ON', 'HASH', 'PREFIX', '1', 'contact_message:', 'SCHEMA', 'number', 'TEXT', 'SORTABLE') + + console.log('contact_message index created: ', response) + + } catch (error) { + console.log('There was an error on contact_message: ', error) + } + + redis.quit() +} + +export { + loadContactsCache, + searchContactCache, + deleteContactsByIdCache, + updateContactCacheById, + createOrUpdateContactCache, + escapeCharCache, + + insertMessageContactCache, + getLastId +} \ No newline at end of file diff --git a/backend/src/helpers/TicketCache.ts b/backend/src/helpers/TicketCache.ts index dc4fe80..68e53b2 100644 --- a/backend/src/helpers/TicketCache.ts +++ b/backend/src/helpers/TicketCache.ts @@ -207,9 +207,7 @@ const createOrUpdateTicketCache = async (hash: any, ticket: any) => { if(!redis) return - if (redis.status !== 'connect') return - - if (redis.status !== 'connect') return + if (redis.status !== 'connect') return ticket.escaped_name = escapeCharCache(ticket['contact.name']) diff --git a/backend/src/libs/wbot.ts b/backend/src/libs/wbot.ts index 079022b..c3f914e 100644 --- a/backend/src/libs/wbot.ts +++ b/backend/src/libs/wbot.ts @@ -35,7 +35,9 @@ const syncUnreadMessages = async (wbot: Session) => { }); for (const msg of unreadMessages) { + // console.log('--BACKEND MSG: ', msg) + await handleMessage(msg, wbot); } @@ -129,12 +131,13 @@ export const initWbot = async (whatsapp: Whatsapp, backupSessionRestore: boolean wbot.on("ready", async () => { logger.info(`Session: ${sessionName} READY`); - // console.log('>>>>>>>>>>>>>> ready wbot.ts MOBILE NUMBER: ', wbot.info["wid"]["user"]) + console.log('>>>>>>>>>>>>>> ready wbot.ts MOBILE NUMBER: ', wbot.info["wid"]["user"]) await whatsapp.update({ status: "CONNECTED", qrcode: "", - retries: 0 + retries: 0, + number: wbot.info["wid"]["user"] }); io.emit("whatsappSession", { diff --git a/backend/src/models/Whatsapp.ts b/backend/src/models/Whatsapp.ts index 8442faa..1a3a6fc 100644 --- a/backend/src/models/Whatsapp.ts +++ b/backend/src/models/Whatsapp.ts @@ -53,6 +53,9 @@ class Whatsapp extends Model { @Column(DataType.TEXT) farewellMessage: string; + @Column + number: string; + @Default(false) @AllowNull @Column diff --git a/backend/src/services/WbotServices/SendWhatsAppMessage.ts b/backend/src/services/WbotServices/SendWhatsAppMessage.ts index 7ad1f50..c274601 100644 --- a/backend/src/services/WbotServices/SendWhatsAppMessage.ts +++ b/backend/src/services/WbotServices/SendWhatsAppMessage.ts @@ -5,13 +5,17 @@ import GetWbotMessage from "../../helpers/GetWbotMessage"; import SerializeWbotMsgId from "../../helpers/SerializeWbotMsgId"; import Message from "../../models/Message"; import Ticket from "../../models/Ticket"; +import Whatsapp from "../../models/Whatsapp"; import ShowWhatsAppService from "../WhatsappService/ShowWhatsAppService"; import wbotByUserQueue from '../../helpers/GetWbotByUserQueue' import { WhatsIndex } from "../../helpers/LoadBalanceWhatsSameQueue"; -import { updateTicketCacheByTicketId } from '../../helpers/TicketCache' +import { deleteTicketsByContactsCache, updateTicketCacheByTicketId } from '../../helpers/TicketCache' + +import ListWhatsAppsNumber from "../WhatsappService/ListWhatsAppsNumber"; +import { getWbot } from "../../libs/wbot"; interface Request { body: string; @@ -30,12 +34,39 @@ const SendWhatsAppMessage = async ({ quotedMsgSerializedId = SerializeWbotMsgId(ticket, quotedMsg); } + //TEST DEL + + // const whatsapp = await ShowWhatsAppService(33); - const whatsapp = await ShowWhatsAppService(ticket.whatsappId); + // const wbot2 = getWbot(whatsapp.id); - if (whatsapp.status != 'CONNECTED') { + // await wbot2.logout(); + + // - let whatsapps = await wbotByUserQueue(ticket.userId) + let whatsapps:any + + const listWhatsapp = await ListWhatsAppsNumber(ticket.whatsappId, 'CONNECTED') + + if (listWhatsapp.length > 1) { + + const _whatsapp = listWhatsapp[Math.floor(Math.random() * listWhatsapp.length)]; + + await ticket.update({ whatsappId: _whatsapp.id }); + + } + else { + + whatsapps = await Whatsapp.findOne({ + where: { id: ticket.whatsappId }, + attributes: ['status'] + }) + + } + + if (listWhatsapp.length == 0 || whatsapps !='CONNECTED') { + + whatsapps = await wbotByUserQueue(ticket.userId) if (whatsapps.length > 0) { @@ -54,19 +85,14 @@ const SendWhatsAppMessage = async ({ } - const wbot = await GetTicketWbot(ticket); - - try { const sentMessage = await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g" : "c"}.us`, body, { quotedMessageId: quotedMsgSerializedId, linkPreview: false }); + await ticket.update({ lastMessage: body }); - - // TEST DEL await updateTicketCacheByTicketId(ticket.id, { lastMessage: body, updatedAt: new Date(ticket.updatedAt).toISOString() }) - // return sentMessage; } catch (err) { diff --git a/backend/src/services/WbotServices/wbotMessageListener.ts b/backend/src/services/WbotServices/wbotMessageListener.ts index 18fe020..4c59268 100644 --- a/backend/src/services/WbotServices/wbotMessageListener.ts +++ b/backend/src/services/WbotServices/wbotMessageListener.ts @@ -54,8 +54,14 @@ import { splitDateTime } from "../../helpers/SplitDateTime"; // import { updateTicketCacheByTicketId } from '../../helpers/TicketCache' +import { insertMessageContactCache, getLastId } from '../../helpers/LastMessageIdByContactCache' +let testLastId = '' + +let lst: any[] = [] +let lstAux: any[] = [] + interface Session extends Client { id?: number; @@ -235,7 +241,7 @@ const verifyQueue = async ( ticketData: { queueId: choosenQueue.id }, ticketId: ticket.id }); - + let botOptions = '' @@ -297,7 +303,7 @@ const verifyQueue = async ( } - + } }; @@ -362,12 +368,68 @@ const handleMessage = async ( msg: WbotMessage, wbot: Session ): Promise => { + + // TEST DEL MULTI SESSION + + if (!msg.id.fromMe) { + } + + // let index = lst.findIndex((x: any) => x.id == msg.id.id) + + // console.log('INDEX: ', index) + + // if (index == -1) { + + // lst.push({id: msg.id.id}) + + // } + // else{ + // console.log('IGNORED ID: ', msg.id.id) + // return + // } + + // console.log('PASSOU.................................FROM: ', msg.from.split("@")[0], ' | ID: ', msg.id.id) + + + + + + // const contact_message = await getLastId(`contact_message:5517988310949`) + + // if (contact_message && contact_message.id == msg.id.id) { + // console.log('IGNORED MESSAGE SAME ID FROM CLIENT: ', contact_message.id) + // return + // } + + // await insertMessageContactCache(`contact_message:5517988310949`, + // { + // from: msg.from.split("@")[0], + // to: msg.to.split("@")[0], + // id: msg.id.id + // }) + + // console.log('PASSOU............................................... contact_message.id: ',contact_message.id) + + + // if (testLastId == msg.id.id) { + // console.log('IGNORED MESSAGE SAME ID!') + // return + // } + // testLastId = msg.id.id + + // console.log('PASSOU............................................... msg.id.id: ',msg.id.id) + + + + + + + + if (!isValidMsg(msg)) { return; } - - try { let msgContact: WbotContact; let groupContact: Contact | undefined; @@ -386,7 +448,7 @@ const handleMessage = async ( msgContact = await msg.getContact(); - // + // console.log(`\n <<<<<<<<<< RECEIVING MESSAGE: Parcial msg and msgContact info: @@ -420,8 +482,8 @@ const handleMessage = async ( const unreadMessages = msg.fromMe ? 0 : chat.unreadCount; - const contact = await verifyContact(msgContact); - + const contact = await verifyContact(msgContact); + if (unreadMessages === 0 && whatsapp.farewellMessage && whatsapp.farewellMessage === msg.body) return; @@ -431,7 +493,7 @@ const handleMessage = async ( wbot.id!, unreadMessages, groupContact - ); + ); // // await updateTicketCacheByTicketId(ticket.id, {'contact.profilePicUrl': ticket.contact.profilePicUrl}) @@ -439,7 +501,7 @@ const handleMessage = async ( // Para responder para o cliente pelo mesmo whatsapp que ele enviou a mensagen if (wbot.id != ticket.whatsappId) { - + await ticket.update({ whatsappId: wbot.id }); } @@ -558,7 +620,7 @@ const handleMessage = async ( - + // test del let next = true @@ -792,7 +854,7 @@ const handleMessage = async ( if (whatsapp.status == 'CONNECTED') { - + let timestamp = Math.floor(Date.now() / 1000) @@ -801,7 +863,7 @@ const handleMessage = async ( await restartWhatsSession(whatsapp) - + } } diff --git a/backend/src/services/WhatsappService/ListWhatsAppsNumber.ts b/backend/src/services/WhatsappService/ListWhatsAppsNumber.ts new file mode 100644 index 0000000..e236490 --- /dev/null +++ b/backend/src/services/WhatsappService/ListWhatsAppsNumber.ts @@ -0,0 +1,28 @@ + +import Whatsapp from "../../models/Whatsapp"; + +const ListWhatsAppsNumber = async (whatsappId: string | number, status: string): Promise => { + + const whatsapp = await Whatsapp.findOne({ + raw: true, + where: { id: whatsappId } + }) + + if (whatsapp) { + + const whatsapps = await Whatsapp.findAll({ + raw: true, + where: {number: whatsapp.number, status: status}, + attributes:['id', 'number'] + }); + + return whatsapps; + + } + + return [] + + +}; + +export default ListWhatsAppsNumber; From 74f38a82cf98641308858ac8bc067b14078171ad Mon Sep 17 00:00:00 2001 From: adriano Date: Wed, 16 Nov 2022 10:23:14 -0300 Subject: [PATCH 02/12] =?UTF-8?q?Implementa=C3=A7=C3=A3o=20de=20reestore?= =?UTF-8?q?=20automatico=20para=20quando=20a=20sess=C3=A3o=20estiver=20con?= =?UTF-8?q?ectada=20e=20n=C3=A3o=20envia=20mensagem?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/controllers/WhatsAppController.ts | 3 ++ .../controllers/WhatsAppSessionController.ts | 15 +++++- backend/src/helpers/RestartWhatsSession.ts | 8 +-- .../src/helpers/SetTicketMessagesAsRead.ts | 32 ++++++------ .../src/helpers/TrySendMessageMultiSession.ts | 49 ++++++++++++++++++ backend/src/libs/wbot.ts | 7 ++- .../WbotServices/SendWhatsAppMessage.ts | 50 +++++++++++++++++-- .../WbotServices/wbotMessageListener.ts | 36 ++++++------- 8 files changed, 152 insertions(+), 48 deletions(-) create mode 100644 backend/src/helpers/TrySendMessageMultiSession.ts diff --git a/backend/src/controllers/WhatsAppController.ts b/backend/src/controllers/WhatsAppController.ts index 253714d..504edfa 100644 --- a/backend/src/controllers/WhatsAppController.ts +++ b/backend/src/controllers/WhatsAppController.ts @@ -123,6 +123,9 @@ export const remove = async ( removeDir(path.join(process.cwd(), '.wwebjs_auth', `session-bd_${whatsappId}`)) + removeDir(path.join(process.cwd(), '.wwebjs_auth','sessions', `session-bd_${whatsappId}`)) + + removeWbot(+whatsappId); const io = getIO(); diff --git a/backend/src/controllers/WhatsAppSessionController.ts b/backend/src/controllers/WhatsAppSessionController.ts index 6cd2317..7f0392f 100644 --- a/backend/src/controllers/WhatsAppSessionController.ts +++ b/backend/src/controllers/WhatsAppSessionController.ts @@ -1,5 +1,5 @@ import { Request, Response } from "express"; -import { getWbot } from "../libs/wbot"; +import { getWbot, removeWbot } from "../libs/wbot"; import { removeDir } from "../helpers/DeleteDirectory"; import ShowWhatsAppService from "../services/WhatsappService/ShowWhatsAppService"; import { StartWhatsAppSession } from "../services/WbotServices/StartWhatsAppSession"; @@ -56,10 +56,21 @@ const remove = async (req: Request, res: Response): Promise => { const { whatsappId } = req.params; const whatsapp = await ShowWhatsAppService(whatsappId); - const wbot = getWbot(whatsapp.id); + const wbot = getWbot(whatsapp.id); await wbot.logout(); + + // TEST DEL + // removeWbot(+whatsapp.id) + + // await removeDir(path.join(process.cwd(), '.wwebjs_auth', 'sessions', `session-bd_${whatsappId}`)) + + // console.log('REMOVEU!!!!!!!!!!!!!!!!!!!!!') + + // + + return res.status(200).json({ message: "Session disconnected." }); }; diff --git a/backend/src/helpers/RestartWhatsSession.ts b/backend/src/helpers/RestartWhatsSession.ts index 1864152..a1feaf6 100644 --- a/backend/src/helpers/RestartWhatsSession.ts +++ b/backend/src/helpers/RestartWhatsSession.ts @@ -17,8 +17,8 @@ export const restartWhatsSession = async (whatsapp: Whatsapp, backupSession: boo const sourcePath = path.join(__dirname, `../../.wwebjs_auth/sessions/`, `session-bd_${whatsapp.id}`) const destPath = path.join(__dirname, `../../.wwebjs_auth/`, `session-bd_${whatsapp.id}`) - console.log('================sourcePath: ', sourcePath) - console.log('================destPath: ', destPath) + console.log('================> sourcePath: ', sourcePath) + console.log('================> destPath: ', destPath) removeWbot(whatsapp.id) @@ -34,6 +34,8 @@ export const restartWhatsSession = async (whatsapp: Whatsapp, backupSession: boo console.log('RESTARTING SESSION...') - await StartWhatsAppSession(whatsapp, backupSession); + // await StartWhatsAppSession(whatsapp, backupSession); + + setTimeout(() => StartWhatsAppSession(whatsapp, backupSession), 2000); } \ No newline at end of file diff --git a/backend/src/helpers/SetTicketMessagesAsRead.ts b/backend/src/helpers/SetTicketMessagesAsRead.ts index 326ca86..e880336 100644 --- a/backend/src/helpers/SetTicketMessagesAsRead.ts +++ b/backend/src/helpers/SetTicketMessagesAsRead.ts @@ -12,6 +12,7 @@ import { splitDateTime } from "./SplitDateTime"; import { format } from "date-fns"; import ptBR from 'date-fns/locale/pt-BR'; +import ListWhatsAppsNumber from "../services/WhatsappService/ListWhatsAppsNumber"; const SetTicketMessagesAsRead = async (ticket: Ticket): Promise => { await Message.update( @@ -26,39 +27,38 @@ const SetTicketMessagesAsRead = async (ticket: Ticket): Promise => { await ticket.update({ unreadMessages: 0 }); - try { + try { - const wbot = await GetTicketWbot(ticket); + const wbot = await GetTicketWbot(ticket); // test del // throw new Error('Throw makes it go boom!') // - + await wbot.sendSeen(`${ticket.contact.number}@${ticket.isGroup ? "g" : "c"}.us`); } catch (err) { - logger.warn( - `Could not mark messages as read. Maybe whatsapp session disconnected? Err: ${err}` - ); - //Solução para contornar erro de sessão - if ((`${err}`).includes("Evaluation failed: r") && ticket.whatsappId) { + logger.warn(`Could not mark messages as read. Maybe whatsapp session disconnected? Err: ${err}`); + + //Solução para contornar erro de sessão + if ((`${err}`).includes("Evaluation failed: r") && ticket.whatsappId) { + + const sourcePath = path.join(__dirname, `../../.wwebjs_auth/sessions`) - const sourcePath = path.join(__dirname,`../../.wwebjs_auth/sessions`) - const dateToday = splitDateTime(new Date(format(new Date(), 'yyyy-MM-dd HH:mm:ss', { locale: ptBR }))) - const whatsapp = await ShowWhatsAppService(ticket.whatsappId); + const whatsapp = await ShowWhatsAppService(ticket.whatsappId); + + if (whatsapp && whatsapp.status == 'CONNECTED') { - if (whatsapp && whatsapp.status == 'CONNECTED') { - let timestamp = Math.floor(Date.now() / 1000) - - fs.writeFile(`${sourcePath}/${timestamp}_SetTicketMessagesAsRead.txt`, `Whatsapp id: ${whatsapp.id} \nDate: ${dateToday.fullDate} ${dateToday.fullTime} \nFile: SetTicketMessagesAsRead.ts \nError: ${err}`, (error)=>{}); + + fs.writeFile(`${sourcePath}/${timestamp}_SetTicketMessagesAsRead.txt`, `Whatsapp id: ${whatsapp.id} \nDate: ${dateToday.fullDate} ${dateToday.fullTime} \nFile: SetTicketMessagesAsRead.ts \nError: ${err}`, (error) => { }); await restartWhatsSession(whatsapp) - + } } diff --git a/backend/src/helpers/TrySendMessageMultiSession.ts b/backend/src/helpers/TrySendMessageMultiSession.ts new file mode 100644 index 0000000..0a201ea --- /dev/null +++ b/backend/src/helpers/TrySendMessageMultiSession.ts @@ -0,0 +1,49 @@ + +import Ticket from "../models/Ticket"; +import ListWhatsAppsNumber from "../services/WhatsappService/ListWhatsAppsNumber"; +import GetTicketWbot from "./GetTicketWbot"; + +const sendMessageMultiSession = async (ticket: Ticket, body?: any, quotedMsgSerializedId?: any, sendSeen?: boolean) => { + + let sentMessage: any = '' + + const listWhatsapp: any = await ListWhatsAppsNumber(ticket.whatsappId, 'CONNECTED') + + if (listWhatsapp.length > 1) { + + for (let w = 0; w < listWhatsapp.length; w++) { + + if(listWhatsapp[w].id == ticket.whatsappId) continue + + try { + + console.log('CHANGE THE WHATSAPP SESSION ID: ', listWhatsapp[w].id) + + await ticket.update({ whatsappId: listWhatsapp[w].id }) + + const wbot = await GetTicketWbot(ticket); + + if (sendSeen) { + + await wbot.sendSeen(`${ticket.contact.number}@${ticket.isGroup ? "g" : "c"}.us`); + + } + else if (body) { + + sentMessage = await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g" : "c"}.us`, body, { quotedMessageId: quotedMsgSerializedId, linkPreview: false }); + + } + + break + + } catch (error) { + console.log('Cannot send send the message using the whatsapp id: ', listWhatsapp[w].id, ' | error: ', error) + } + + } + } + + return sentMessage +}; + +export default sendMessageMultiSession; diff --git a/backend/src/libs/wbot.ts b/backend/src/libs/wbot.ts index c3f914e..58e0e54 100644 --- a/backend/src/libs/wbot.ts +++ b/backend/src/libs/wbot.ts @@ -160,7 +160,7 @@ export const initWbot = async (whatsapp: Whatsapp, backupSessionRestore: boolean - console.log(`>>>>>>>>>>>>>>>>>>>>>>>>>.. BACKUP SESSION whatsapp.id ${whatsapp.id} | backupSession: ${backupSession}`) + console.log(`>>>>>>>>>>>>>>>>>>>>>>>>> BACKUP SESSION whatsapp.id ${whatsapp.id} | backupSession: ${backupSession}`) const whatsIndex = backupSession.findIndex((id: number) => id === +whatsapp.id); @@ -192,7 +192,7 @@ export const initWbot = async (whatsapp: Whatsapp, backupSessionRestore: boolean console.log(` COPIOU backup whatsapp.id ---------------------------------->${whatsapp.id}`) - }, 55000); + }, 90000); console.log(' PASSOU NO TIMEOUT whatsapp.id: ',whatsapp.id) @@ -210,6 +210,9 @@ export const initWbot = async (whatsapp: Whatsapp, backupSessionRestore: boolean export const getWbot = (whatsappId: number): Session => { const sessionIndex = sessions.findIndex(s => s.id === whatsappId); + console.log('----------> sessionIndex: ', sessionIndex, ' | whatasappId: ', whatsappId) + console.log('----------> sessions: ',sessions.map(s => s.id)) + if (sessionIndex === -1) { throw new AppError("ERR_WAPP_NOT_INITIALIZED"); } diff --git a/backend/src/services/WbotServices/SendWhatsAppMessage.ts b/backend/src/services/WbotServices/SendWhatsAppMessage.ts index c274601..b787d44 100644 --- a/backend/src/services/WbotServices/SendWhatsAppMessage.ts +++ b/backend/src/services/WbotServices/SendWhatsAppMessage.ts @@ -16,6 +16,12 @@ import { deleteTicketsByContactsCache, updateTicketCacheByTicketId } from '../.. import ListWhatsAppsNumber from "../WhatsappService/ListWhatsAppsNumber"; import { getWbot } from "../../libs/wbot"; +import { json } from "sequelize/types"; + +import sendMessageMultiSession from "../../helpers/TrySendMessageMultiSession"; +import { restartWhatsSession } from "../../helpers/RestartWhatsSession"; + + interface Request { body: string; @@ -35,16 +41,17 @@ const SendWhatsAppMessage = async ({ } //TEST DEL - + // const whatsapp = await ShowWhatsAppService(33); // const wbot2 = getWbot(whatsapp.id); // await wbot2.logout(); - + // - let whatsapps:any + + let whatsapps: any const listWhatsapp = await ListWhatsAppsNumber(ticket.whatsappId, 'CONNECTED') @@ -64,7 +71,13 @@ const SendWhatsAppMessage = async ({ } - if (listWhatsapp.length == 0 || whatsapps !='CONNECTED') { + + + console.log('3 --------> ticket.whatsappId: ', ticket.whatsappId) + + + + if (listWhatsapp.length == 0 || (whatsapps && whatsapps.status != 'CONNECTED')) { whatsapps = await wbotByUserQueue(ticket.userId) @@ -87,6 +100,9 @@ const SendWhatsAppMessage = async ({ const wbot = await GetTicketWbot(ticket); + console.log('4 --------> ticket.whatsappId: ', ticket.whatsappId) + + try { const sentMessage = await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g" : "c"}.us`, body, { quotedMessageId: quotedMsgSerializedId, linkPreview: false }); @@ -96,6 +112,32 @@ const SendWhatsAppMessage = async ({ return sentMessage; } catch (err) { + + const whatsapp = await ShowWhatsAppService(ticket.whatsappId); + + if (whatsapp.status != 'RESTORING') { + + console.log('THE WHATSAAP ID: ', whatsapp.id, ' WILL BE RESTORED SOON!') + + await whatsapp.update({ + status: "RESTORING", + }); + setTimeout(() => restartWhatsSession(whatsapp, true), 90000); + } + + + + const sentMessage = await sendMessageMultiSession(ticket, body, quotedMsgSerializedId) + + if (sentMessage.length > 0) { + + await ticket.update({ lastMessage: body }); + await updateTicketCacheByTicketId(ticket.id, { lastMessage: body, updatedAt: new Date(ticket.updatedAt).toISOString() }) + return sentMessage; + + } + + throw new AppError("ERR_SENDING_WAPP_MSG"); } }; diff --git a/backend/src/services/WbotServices/wbotMessageListener.ts b/backend/src/services/WbotServices/wbotMessageListener.ts index 4c59268..9e09c02 100644 --- a/backend/src/services/WbotServices/wbotMessageListener.ts +++ b/backend/src/services/WbotServices/wbotMessageListener.ts @@ -369,30 +369,24 @@ const handleMessage = async ( wbot: Session ): Promise => { - // TEST DEL MULTI SESSION + // TEST DEL MULTI SESSION - if (!msg.id.fromMe) { + + let index = lst.findIndex((x: any) => x.id == msg.id.id) + + console.log('INDEX: ', index) + + if (index == -1) { + + lst.push({ id: msg.id.id }) + + } + else { + console.log('IGNORED ID: ', msg.id.id) + return } - // let index = lst.findIndex((x: any) => x.id == msg.id.id) - - // console.log('INDEX: ', index) - - // if (index == -1) { - - // lst.push({id: msg.id.id}) - - // } - // else{ - // console.log('IGNORED ID: ', msg.id.id) - // return - // } - - // console.log('PASSOU.................................FROM: ', msg.from.split("@")[0], ' | ID: ', msg.id.id) - - - - + console.log('PASSOU.................................FROM: ', msg.from.split("@")[0], ' | ID: ', msg.id.id) // const contact_message = await getLastId(`contact_message:5517988310949`) From d86a7efe12d089df53aeae9e9dc87cb25023c008 Mon Sep 17 00:00:00 2001 From: adriano Date: Wed, 16 Nov 2022 15:29:20 -0300 Subject: [PATCH 03/12] =?UTF-8?q?Alter=C3=A7=C3=A3o=20no=20limite=20de=20a?= =?UTF-8?q?rmazenamento=20da=20lista=20de=20ids=20das=20mensagens=20enviad?= =?UTF-8?q?as=20e=20recebidas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/controllers/MessageController.ts | 3 +- backend/src/libs/wbot.ts | 4 +- .../WbotServices/SendWhatsAppMessage.ts | 4 +- .../WbotServices/wbotMessageListener.ts | 46 +++++++++++++++++-- 4 files changed, 49 insertions(+), 8 deletions(-) diff --git a/backend/src/controllers/MessageController.ts b/backend/src/controllers/MessageController.ts index 84c7cf3..f9641d6 100644 --- a/backend/src/controllers/MessageController.ts +++ b/backend/src/controllers/MessageController.ts @@ -70,8 +70,9 @@ export const store = async (req: Request, res: Response): Promise => { Parcial ticket info: ticket.id: ${ticket.id} ticket.status: ${ticket.status} - ticket.whatsapp.id: ${ticket.whatsappId} + ticket.whatsapp.id: ${ticket.whatsappId} ticket.contact.number: ${ticket.contact.number} + message: ${body} ticket.contact.name: ${ticket.contact.name} ticket.contact.profilePicUrl: ${ticket.contact.profilePicUrl} ticket.user.id: ${ticket.user.id} diff --git a/backend/src/libs/wbot.ts b/backend/src/libs/wbot.ts index 58e0e54..cb2cd12 100644 --- a/backend/src/libs/wbot.ts +++ b/backend/src/libs/wbot.ts @@ -210,8 +210,8 @@ export const initWbot = async (whatsapp: Whatsapp, backupSessionRestore: boolean export const getWbot = (whatsappId: number): Session => { const sessionIndex = sessions.findIndex(s => s.id === whatsappId); - console.log('----------> sessionIndex: ', sessionIndex, ' | whatasappId: ', whatsappId) - console.log('----------> sessions: ',sessions.map(s => s.id)) + // console.log('----------> sessionIndex: ', sessionIndex, ' | whatasappId: ', whatsappId) + // console.log('----------> sessions: ',sessions.map(s => s.id)) if (sessionIndex === -1) { throw new AppError("ERR_WAPP_NOT_INITIALIZED"); diff --git a/backend/src/services/WbotServices/SendWhatsAppMessage.ts b/backend/src/services/WbotServices/SendWhatsAppMessage.ts index b787d44..e07c8e3 100644 --- a/backend/src/services/WbotServices/SendWhatsAppMessage.ts +++ b/backend/src/services/WbotServices/SendWhatsAppMessage.ts @@ -73,7 +73,7 @@ const SendWhatsAppMessage = async ({ - console.log('3 --------> ticket.whatsappId: ', ticket.whatsappId) + console.log('1 --------> ticket.whatsappId: ', ticket.whatsappId) @@ -100,7 +100,7 @@ const SendWhatsAppMessage = async ({ const wbot = await GetTicketWbot(ticket); - console.log('4 --------> ticket.whatsappId: ', ticket.whatsappId) + console.log('2 --------> send from whatsapp ticket.whatsappId: ', ticket.whatsappId) try { diff --git a/backend/src/services/WbotServices/wbotMessageListener.ts b/backend/src/services/WbotServices/wbotMessageListener.ts index 9e09c02..24470c1 100644 --- a/backend/src/services/WbotServices/wbotMessageListener.ts +++ b/backend/src/services/WbotServices/wbotMessageListener.ts @@ -57,10 +57,9 @@ import { updateTicketCacheByTicketId } from '../../helpers/TicketCache' import { insertMessageContactCache, getLastId } from '../../helpers/LastMessageIdByContactCache' -let testLastId = '' let lst: any[] = [] -let lstAux: any[] = [] +let clear_lst: any interface Session extends Client { @@ -364,6 +363,45 @@ const botSendMessage = (ticket: Ticket, contact: Contact, wbot: Session, msg: st } +const _clear_lst = () => { + + console.log('LIST (lst.length) WHATSAPP MESSAGE ID MULTI SESSION: : ', lst.length) + + if (lst.length < 800 ) return + + console.log('BEFORE lst SLICE: ', lst) + + console.log('lst whatsapp message id sliced! | lst.length: ', lst.length) + + const chunk: any = Math.floor((lst.length / 2)) + + lst = lst.slice(chunk, chunk + lst.length); + + console.log('AFTER lst SLICE: ', lst) + +} + + +const clearMultiSessionWhatsappMessageId = () => { + + + try { + clearInterval(clear_lst); + + _clear_lst() + + } catch (error) { + console.log('error on clear lst whatsapp id message: ', error) + } + finally { + clear_lst = setInterval(_clear_lst, 10000); + } + +} + +clear_lst = setInterval(clearMultiSessionWhatsappMessageId, 10000); + + const handleMessage = async ( msg: WbotMessage, wbot: Session @@ -371,7 +409,6 @@ const handleMessage = async ( // TEST DEL MULTI SESSION - let index = lst.findIndex((x: any) => x.id == msg.id.id) console.log('INDEX: ', index) @@ -383,9 +420,12 @@ const handleMessage = async ( } else { console.log('IGNORED ID: ', msg.id.id) + return } + // console.log('LIST OF ID MESSAGE lst: ', lst) + console.log('PASSOU.................................FROM: ', msg.from.split("@")[0], ' | ID: ', msg.id.id) // const contact_message = await getLastId(`contact_message:5517988310949`) From bc406cb1d067812a6c1c91bb6448975a748fef35 Mon Sep 17 00:00:00 2001 From: adriano Date: Thu, 17 Nov 2022 11:40:37 -0300 Subject: [PATCH 04/12] =?UTF-8?q?Implementa=C3=A7=C3=A3o=20de=20cache=20pa?= =?UTF-8?q?ra=20whatsapp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/helpers/ContactsCache.ts | 4 +- backend/src/helpers/WhatsCache.ts | 240 ++++++++++++++++++ backend/src/libs/wbot.ts | 11 +- backend/src/server.ts | 2 + .../WbotServices/SendWhatsAppMessage.ts | 33 ++- .../WbotServices/StartWhatsAppSession.ts | 5 + .../src/services/WbotServices/wbotMonitor.ts | 3 + .../WhatsappService/CreateWhatsAppService.ts | 1 + .../WhatsappService/ListWhatsAppsNumber.ts | 4 +- .../WhatsappService/UpdateWhatsAppService.ts | 10 + 10 files changed, 297 insertions(+), 16 deletions(-) create mode 100644 backend/src/helpers/WhatsCache.ts diff --git a/backend/src/helpers/ContactsCache.ts b/backend/src/helpers/ContactsCache.ts index 1cb7835..902a385 100644 --- a/backend/src/helpers/ContactsCache.ts +++ b/backend/src/helpers/ContactsCache.ts @@ -67,9 +67,7 @@ const updateContactCacheById = async (id: string | number, update_fields: object const contact_cache: any = await redis.hgetall(`contact:${id}`) try { - if (contact_cache && Object.keys(contact_cache).length > 0) { - - // await redis.del(`contact:${id}`) + if (contact_cache && Object.keys(contact_cache).length > 0) { update_fields.escaped_name = escapeCharCache(update_fields.name) diff --git a/backend/src/helpers/WhatsCache.ts b/backend/src/helpers/WhatsCache.ts new file mode 100644 index 0000000..84f4a1a --- /dev/null +++ b/backend/src/helpers/WhatsCache.ts @@ -0,0 +1,240 @@ + +import Redis from 'ioredis' +import { type } from 'os' +const unflatten = require('flat').unflatten +var flatten = require('flat') +import ListWhatsAppsNumber from "../services/WhatsappService/ListWhatsAppsNumber" +import { redisConn } from './TicketCache' +import Whatsapp from "../models/Whatsapp"; + +const deleteWhatsappCache = async (hash:any) => { + + const redis: any = await redisConn(); + + if(!redis) return + + if (redis.status !== 'connect') return + + const whatsapp_cache: any = await redis.hgetall(hash) + + try { + if (whatsapp_cache && Object.keys(whatsapp_cache).length > 0) { + + await redis.del(hash) + + console.log(`Whatsapp cache number ${whatsapp_cache['number']} deleted!`) + } + else { + console.log('WHATSAPP CACHE NOT FOUND!') + } + } catch (error) { + console.log(`There was an error on deleteWhatsappCache: ${error}`) + } + + redis.quit() +} + +const updateWhatsappCache = async (hash: any, json_object: any) => { + + const redis: any = await redisConn(); + + if(!redis) return + + if (redis.status !== 'connect') return + + const pipeline = redis.pipeline() + + let entries = Object.entries(json_object) + + entries.forEach((e: any) => { + pipeline.hset(hash, e[0], e[1]) + }) + + await pipeline.exec(() => { console.log("whatsapp Key/value inserted/updated") }); + + redis.quit() + +} + +const updateWhatsappCacheById = async (hash:any, update_fields: object | any) => { + + const redis: any = await redisConn(); + + if(!redis) return + + if (redis.status !== 'connect') return + + const whatsapp_cache: any = await redis.hgetall(hash) + + try { + if (whatsapp_cache && Object.keys(whatsapp_cache).length > 0) { + + // update_fields.escaped_name = escapeCharCache(update_fields.name) + + await updateWhatsappCache(hash, update_fields) + + console.log(`WHATSAPP ${whatsapp_cache['number']} CACHE WAS UPDATED!`) + } + else { + console.log('WHATSAPP CACHE NOT FOUND!') + } + } catch (error) { + console.log(`There was an error on updateWhatsappCacheById: ${error}`) + } + + redis.quit() +} + +// const createOrUpdateContactCache = async (hash: any, contact: any) => { + +// const redis: any = await redisConn(); + +// if(!redis) return + +// if (redis.status !== 'connect') return + +// if (contact.name) { +// contact.escaped_name = escapeCharCache(contact.name) +// } + +// await redis.hmset(hash, contact); + +// redis.quit() + +// } + + +async function searchWhatsappCache(search: string) { + + const redis: any = await redisConn(); + + if(!redis) return + + if (redis.status !== 'connect') return null + + const response: any = await redis.call('FT.SEARCH', 'idx_whatsapp', `(@status:*${search}*)|(@number:*${search}*)`, 'SORTBY', 'status', 'ASC') + redis.quit() + + + if (response.length === 1) { + return [] + } + + const results: any = [] + + for (let n = 2; n < response.length; n += 2) { + const result: any = {} + const fieldNamesAndValues = response[n] + + for (let m = 0; m < fieldNamesAndValues.length; m += 2) { + const k = fieldNamesAndValues[m] + const v = fieldNamesAndValues[m + 1] + result[k] = v + } + + results.push(result) + } + + return results +} + + + +const insertOrUpeateWhatsCache = async (hash:any, whatsapp: any) => { + + const redis: any = await redisConn(); + + if(!redis) return + + if (redis.status !== 'connect') return + + if(Array.isArray(whatsapp)){ + + const pipeline = redis.pipeline() + + for (let i = 0; i < whatsapp.length; i++) { + + pipeline.hmset(hash, whatsapp[i]); + } + + await pipeline.exec(() => { console.log(`${whatsapp.length} WHATSAPP INSERTED IN CACHE!`) }); + } + else{ + + await redis.hmset(hash,JSON.parse(JSON.stringify(whatsapp))); + + console.log(`${whatsapp.length} WHATSAPP INSERTED OR UPADTED IN CACHE!`) + + } + + + redis.quit() +} + + + + +const loadWhatsappCache = async () => { + + await createWhatsappIndexCache('idx_whatsapp') + + const redis: any = await redisConn(); + + if(!redis) return + + if (redis.status !== 'connect') return + + let whatsapps:any = await Whatsapp.findAll({raw: true}) + + const pipeline = redis.pipeline() + + for (let i = 0; i < whatsapps.length; i++) { + + whatsapps[i].createdAt = new Date(whatsapps[i].createdAt).toISOString() + whatsapps[i].updatedAt = new Date(whatsapps[i].updatedAt).toISOString() + + // whatsapps[i].escaped_name = escapeCharCache(whatsapps[i].name) + + pipeline.hmset(`whatsapp:${whatsapps[i].id}`, whatsapps[i]); + } + + await pipeline.exec(() => { console.log(`${whatsapps.length} WHATSAPPS INSERTED IN CACHE!`) }); + + redis.quit() +} + +const createWhatsappIndexCache = async (hashIndex: string) => { + + const redis: any = await redisConn(); + + if(!redis) return + + if (redis.status !== 'connect') return + + try { + + const lst_index_redis: any = await redis.call('FT._LIST') + + if (lst_index_redis.includes(hashIndex)) { + console.log('entrou...') + await redis.call('FT.DROPINDEX', hashIndex) + } + + const response = await redis.call('FT.CREATE', hashIndex, 'ON', 'HASH', 'PREFIX', '1', 'whatsapp:', 'SCHEMA', 'status', 'TEXT', 'SORTABLE', 'number', 'TEXT', 'SORTABLE') + + console.log('Whatsapp index created: ', response) + + } catch (error) { + console.log('There was an error on createWhatsappIndexCache: ', error) + } + + redis.quit() +} + +export { + loadWhatsappCache, + searchWhatsappCache, + updateWhatsappCacheById, + insertOrUpeateWhatsCache, + deleteWhatsappCache +} \ No newline at end of file diff --git a/backend/src/libs/wbot.ts b/backend/src/libs/wbot.ts index cb2cd12..e666211 100644 --- a/backend/src/libs/wbot.ts +++ b/backend/src/libs/wbot.ts @@ -20,6 +20,7 @@ const sessions: Session[] = []; let backupSession: any[] = [] +import { insertOrUpeateWhatsCache } from "../helpers/WhatsCache"; @@ -87,6 +88,7 @@ export const initWbot = async (whatsapp: Whatsapp, backupSessionRestore: boolean logger.info("Session:", sessionName); qrCode.generate(qr, { small: true }); await whatsapp.update({ qrcode: qr, status: "qrcode", retries: 0 }); + await insertOrUpeateWhatsCache(`whatsapp:${whatsapp.id}`, { qrcode: qr, status: "qrcode", retries: 0 }) const sessionIndex = sessions.findIndex(s => s.id === whatsapp.id); if (sessionIndex === -1) { @@ -112,6 +114,7 @@ export const initWbot = async (whatsapp: Whatsapp, backupSessionRestore: boolean if (whatsapp.retries > 1) { await whatsapp.update({ session: "", retries: 0 }); + await insertOrUpeateWhatsCache(`whatsapp:${whatsapp.id}`, { session: "", retries: 0 }) } const retry = whatsapp.retries; @@ -119,6 +122,10 @@ export const initWbot = async (whatsapp: Whatsapp, backupSessionRestore: boolean status: "DISCONNECTED", retries: retry + 1 }); + await insertOrUpeateWhatsCache(`whatsapp:${whatsapp.id}`, { + status: "DISCONNECTED", + retries: retry + 1 + }) io.emit("whatsappSession", { action: "update", @@ -132,13 +139,15 @@ export const initWbot = async (whatsapp: Whatsapp, backupSessionRestore: boolean logger.info(`Session: ${sessionName} READY`); console.log('>>>>>>>>>>>>>> ready wbot.ts MOBILE NUMBER: ', wbot.info["wid"]["user"]) + await whatsapp.update({ status: "CONNECTED", qrcode: "", retries: 0, number: wbot.info["wid"]["user"] - }); + }); + await insertOrUpeateWhatsCache(`whatsapp:${whatsapp.id}`,whatsapp) io.emit("whatsappSession", { action: "update", diff --git a/backend/src/server.ts b/backend/src/server.ts index f4949f6..b5c793c 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -9,6 +9,7 @@ import { startWhoIsOnlineMonitor } from "./helpers/WhoIsOnlineMonitor" import { loadTicketsCache, flushCache, cacheSize } from './helpers/TicketCache' import { loadContactsCache } from './helpers/ContactsCache' +import { loadWhatsappCache } from './helpers/WhatsCache' const server = app.listen(process.env.PORT, () => { logger.info(`Server started on port: ${process.env.PORT}`); @@ -29,6 +30,7 @@ gracefulShutdown(server); await flushCache() await loadContactsCache() await loadTicketsCache() + await loadWhatsappCache() } })() diff --git a/backend/src/services/WbotServices/SendWhatsAppMessage.ts b/backend/src/services/WbotServices/SendWhatsAppMessage.ts index e07c8e3..68d4877 100644 --- a/backend/src/services/WbotServices/SendWhatsAppMessage.ts +++ b/backend/src/services/WbotServices/SendWhatsAppMessage.ts @@ -20,6 +20,7 @@ import { json } from "sequelize/types"; import sendMessageMultiSession from "../../helpers/TrySendMessageMultiSession"; import { restartWhatsSession } from "../../helpers/RestartWhatsSession"; +import { insertOrUpeateWhatsCache, searchWhatsappCache } from "../../helpers/WhatsCache"; @@ -34,22 +35,25 @@ const SendWhatsAppMessage = async ({ ticket, quotedMsg }: Request): Promise => { + + var timetaken = "Time taken to send message"; + + + console.time(timetaken) + + let quotedMsgSerializedId: string | undefined; if (quotedMsg) { await GetWbotMessage(ticket, quotedMsg.id); quotedMsgSerializedId = SerializeWbotMsgId(ticket, quotedMsg); } + + //TEST DEL - //TEST DEL - - // const whatsapp = await ShowWhatsAppService(33); - - // const wbot2 = getWbot(whatsapp.id); - - // await wbot2.logout(); - - // - + let whats_number = await searchWhatsappCache(`${ticket.whatsappId}`) + console.log('---') + console.log('whats_number search: ', whats_number) + console.log('---') let whatsapps: any @@ -104,12 +108,16 @@ const SendWhatsAppMessage = async ({ try { + console.time + const sentMessage = await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g" : "c"}.us`, body, { quotedMessageId: quotedMsgSerializedId, linkPreview: false }); await ticket.update({ lastMessage: body }); await updateTicketCacheByTicketId(ticket.id, { lastMessage: body, updatedAt: new Date(ticket.updatedAt).toISOString() }) + console.timeEnd(timetaken) + return sentMessage; } catch (err) { @@ -122,6 +130,11 @@ const SendWhatsAppMessage = async ({ await whatsapp.update({ status: "RESTORING", }); + + await insertOrUpeateWhatsCache(`whatsapp:${whatsapp.id}`, { + status: "RESTORING", + }) + setTimeout(() => restartWhatsSession(whatsapp, true), 90000); } diff --git a/backend/src/services/WbotServices/StartWhatsAppSession.ts b/backend/src/services/WbotServices/StartWhatsAppSession.ts index 3b02cd2..bd34e23 100644 --- a/backend/src/services/WbotServices/StartWhatsAppSession.ts +++ b/backend/src/services/WbotServices/StartWhatsAppSession.ts @@ -4,9 +4,14 @@ import { wbotMessageListener } from "./wbotMessageListener"; import { getIO } from "../../libs/socket"; import wbotMonitor from "./wbotMonitor"; import { logger } from "../../utils/logger"; +import { insertOrUpeateWhatsCache } from "../../helpers/WhatsCache"; export const StartWhatsAppSession = async (whatsapp: Whatsapp, backupSession: boolean = false): Promise => { await whatsapp.update({ status: "OPENING" }); + + await insertOrUpeateWhatsCache(`whatsapp:${whatsapp.id}`, { + status: "OPENING", + }) const io = getIO(); io.emit("whatsappSession", { diff --git a/backend/src/services/WbotServices/wbotMonitor.ts b/backend/src/services/WbotServices/wbotMonitor.ts index 54b4c2e..c7e0565 100644 --- a/backend/src/services/WbotServices/wbotMonitor.ts +++ b/backend/src/services/WbotServices/wbotMonitor.ts @@ -1,5 +1,6 @@ import * as Sentry from "@sentry/node"; import { Client } from "whatsapp-web.js"; +import { insertOrUpeateWhatsCache } from "../../helpers/WhatsCache"; import { getIO } from "../../libs/socket"; import Whatsapp from "../../models/Whatsapp"; @@ -25,6 +26,7 @@ const wbotMonitor = async ( try { await whatsapp.update({ status: newState }); + await insertOrUpeateWhatsCache(`whatsapp:${whatsapp.id}`, { status: newState }) } catch (err) { Sentry.captureException(err); logger.error(err); @@ -59,6 +61,7 @@ const wbotMonitor = async ( logger.info(`Disconnected session: ${sessionName}, reason: ${reason}`); try { await whatsapp.update({ status: "OPENING", session: "" }); + await insertOrUpeateWhatsCache(`whatsapp:${whatsapp.id}`, { status: "OPENING", session: "" }) } catch (err) { Sentry.captureException(err); logger.error(err); diff --git a/backend/src/services/WhatsappService/CreateWhatsAppService.ts b/backend/src/services/WhatsappService/CreateWhatsAppService.ts index b9f8d37..e2d896f 100644 --- a/backend/src/services/WhatsappService/CreateWhatsAppService.ts +++ b/backend/src/services/WhatsappService/CreateWhatsAppService.ts @@ -62,6 +62,7 @@ const CreateWhatsAppService = async ({ }); if (oldDefaultWhatsapp) { await oldDefaultWhatsapp.update({ isDefault: false }); + } } diff --git a/backend/src/services/WhatsappService/ListWhatsAppsNumber.ts b/backend/src/services/WhatsappService/ListWhatsAppsNumber.ts index e236490..b9c921f 100644 --- a/backend/src/services/WhatsappService/ListWhatsAppsNumber.ts +++ b/backend/src/services/WhatsappService/ListWhatsAppsNumber.ts @@ -12,8 +12,8 @@ const ListWhatsAppsNumber = async (whatsappId: string | number, status: string): const whatsapps = await Whatsapp.findAll({ raw: true, - where: {number: whatsapp.number, status: status}, - attributes:['id', 'number'] + where: { number: whatsapp.number, status: status }, + attributes: ['id', 'number', 'status', 'isDefault'] }); return whatsapps; diff --git a/backend/src/services/WhatsappService/UpdateWhatsAppService.ts b/backend/src/services/WhatsappService/UpdateWhatsAppService.ts index 5c6fde7..2b4e850 100644 --- a/backend/src/services/WhatsappService/UpdateWhatsAppService.ts +++ b/backend/src/services/WhatsappService/UpdateWhatsAppService.ts @@ -5,6 +5,7 @@ import AppError from "../../errors/AppError"; import Whatsapp from "../../models/Whatsapp"; import ShowWhatsAppService from "./ShowWhatsAppService"; import AssociateWhatsappQueue from "./AssociateWhatsappQueue"; +import { insertOrUpeateWhatsCache } from "../../helpers/WhatsCache"; interface WhatsappData { name?: string; @@ -78,6 +79,15 @@ const UpdateWhatsAppService = async ({ isDefault }); + await insertOrUpeateWhatsCache(`whatsapp:${whatsapp.id}`, { + name, + status, + session, + greetingMessage, + farewellMessage, + isDefault + }) + await AssociateWhatsappQueue(whatsapp, queueIds); return { whatsapp, oldDefaultWhatsapp }; From 408bb16e870a85f089f5402efac2af1c63a34aab Mon Sep 17 00:00:00 2001 From: adriano Date: Fri, 9 Dec 2022 10:21:16 -0300 Subject: [PATCH 05/12] =?UTF-8?q?Altera=C3=A7=C3=A3o=20parcial=20no=20sear?= =?UTF-8?q?ch=20do=20whatsapp=20cache?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/helpers/WhatsCache.ts | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/backend/src/helpers/WhatsCache.ts b/backend/src/helpers/WhatsCache.ts index 84f4a1a..45ed77e 100644 --- a/backend/src/helpers/WhatsCache.ts +++ b/backend/src/helpers/WhatsCache.ts @@ -6,6 +6,7 @@ var flatten = require('flat') import ListWhatsAppsNumber from "../services/WhatsappService/ListWhatsAppsNumber" import { redisConn } from './TicketCache' import Whatsapp from "../models/Whatsapp"; +import { response } from 'express' const deleteWhatsappCache = async (hash:any) => { @@ -104,7 +105,7 @@ const updateWhatsappCacheById = async (hash:any, update_fields: object | any) => // } -async function searchWhatsappCache(search: string) { +async function searchWhatsappCache(id: string, status: string) { const redis: any = await redisConn(); @@ -112,7 +113,18 @@ async function searchWhatsappCache(search: string) { if (redis.status !== 'connect') return null - const response: any = await redis.call('FT.SEARCH', 'idx_whatsapp', `(@status:*${search}*)|(@number:*${search}*)`, 'SORTBY', 'status', 'ASC') + // @x:foo @y:bar + + // const response: any = await redis.call('FT.SEARCH', 'idx_whatsapp', `(@status:*${status}*) (@number:*${number}*)`, 'SORTBY', 'status', 'ASC') + + // const response: any = await redis.call('FT.SEARCH', 'idx_whatsapp', `(@id:*${id}*))`) + + const response: any = [] + + const number_cache: any = await redis.hgetall(`whatsapp:${14}`) + + console.log('NUMBER CACHED: ', number_cache) + redis.quit() @@ -220,7 +232,7 @@ const createWhatsappIndexCache = async (hashIndex: string) => { await redis.call('FT.DROPINDEX', hashIndex) } - const response = await redis.call('FT.CREATE', hashIndex, 'ON', 'HASH', 'PREFIX', '1', 'whatsapp:', 'SCHEMA', 'status', 'TEXT', 'SORTABLE', 'number', 'TEXT', 'SORTABLE') + const response = await redis.call('FT.CREATE', hashIndex, 'ON', 'HASH', 'PREFIX', '1', 'whatsapp:', 'SCHEMA','id', 'NUMERIC', 'SORTABLE', 'status', 'TEXT', 'SORTABLE', 'number', 'TEXT') console.log('Whatsapp index created: ', response) From 330299726d89f96d8e606d220b8a5113e83738c5 Mon Sep 17 00:00:00 2001 From: adriano Date: Sun, 11 Dec 2022 04:47:32 -0300 Subject: [PATCH 06/12] =?UTF-8?q?Finaliza=C3=A7=C3=A3o=20de=20implementa?= =?UTF-8?q?=C3=A7=C3=A3o=20do=20controle=20do=20bot=C3=A3o=20restore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/WhatsAppSessionController.ts | 63 +++++++++--- .../src/helpers/TrySendMessageMultiSession.ts | 2 +- backend/src/helpers/WhatsCache.ts | 26 ++--- backend/src/libs/wbot.ts | 26 ++++- backend/src/routes/whatsappSessionRoutes.ts | 1 + .../WbotServices/SendWhatsAppMessage.ts | 95 ++++++++++++++----- .../WbotServices/wbotMessageListener.ts | 4 +- .../WhatsappService/UpdateWhatsAppService.ts | 16 +++- frontend/src/components/QrcodeModal/index.js | 21 +++- frontend/src/hooks/useWhatsApps/index.js | 53 ++++++++--- frontend/src/pages/Connections/index.js | 95 ++++++++++++------- frontend/src/translate/languages/en.js | 2 + frontend/src/translate/languages/es.js | 3 + frontend/src/translate/languages/pt.js | 4 + 14 files changed, 311 insertions(+), 100 deletions(-) diff --git a/backend/src/controllers/WhatsAppSessionController.ts b/backend/src/controllers/WhatsAppSessionController.ts index 7f0392f..e1fbeaa 100644 --- a/backend/src/controllers/WhatsAppSessionController.ts +++ b/backend/src/controllers/WhatsAppSessionController.ts @@ -7,7 +7,11 @@ import UpdateWhatsAppService from "../services/WhatsappService/UpdateWhatsAppSer import { restartWhatsSession } from "../helpers/RestartWhatsSession"; -import path from 'path'; +import path from 'path'; +import { getIO } from "../libs/socket"; +import { stat } from "fs"; + +let lstRestore: any = [] // import { WWebJsw } from "../../WWebJS/session-bd_40" @@ -36,17 +40,52 @@ const update = async (req: Request, res: Response): Promise => { + const restart = async (req: Request, res: Response): Promise => { - + const { whatsappId } = req.params; - console.log('FROM REQUEST WHATSAPP ID: ', whatsappId) + const io = getIO(); + if (Object.keys(req.body).length > 0) { + + for (let i = 0; i < lstRestore.length; i++) { + + io.emit("whatsappSession", { + action: "update", + session: { 'id': +lstRestore[i].id, 'disabled': true } + }); + + } + + return res.status(200).json({}); + + } + const whatsapp = await ShowWhatsAppService(whatsappId); restartWhatsSession(whatsapp, true) - //restartWhatsSession(whatsapp) + lstRestore.push({ 'id': +whatsappId, 'disabled': true }) + + io.emit("whatsappSession", { + action: "update", + session: { 'id': +whatsappId, 'disabled': true } + }); + + setTimeout(() => { + + let whatsapp = lstRestore.shift(); + + whatsapp.disabled = false + + io.emit("whatsappSession", { + action: "update", + session: whatsapp + }); + + }, 25000); + return res.status(200).json({ message: "Starting session." }); }; @@ -56,20 +95,20 @@ const remove = async (req: Request, res: Response): Promise => { const { whatsappId } = req.params; const whatsapp = await ShowWhatsAppService(whatsappId); - const wbot = getWbot(whatsapp.id); + const wbot = getWbot(whatsapp.id); await wbot.logout(); - // TEST DEL - // removeWbot(+whatsapp.id) + // TEST DEL + // removeWbot(+whatsapp.id) - // await removeDir(path.join(process.cwd(), '.wwebjs_auth', 'sessions', `session-bd_${whatsappId}`)) + // await removeDir(path.join(process.cwd(), '.wwebjs_auth', 'sessions', `session-bd_${whatsappId}`)) + + // console.log('REMOVEU!!!!!!!!!!!!!!!!!!!!!') + + // - // console.log('REMOVEU!!!!!!!!!!!!!!!!!!!!!') - - // - return res.status(200).json({ message: "Session disconnected." }); }; diff --git a/backend/src/helpers/TrySendMessageMultiSession.ts b/backend/src/helpers/TrySendMessageMultiSession.ts index 0a201ea..ecc0069 100644 --- a/backend/src/helpers/TrySendMessageMultiSession.ts +++ b/backend/src/helpers/TrySendMessageMultiSession.ts @@ -9,7 +9,7 @@ const sendMessageMultiSession = async (ticket: Ticket, body?: any, quotedMsgSeri const listWhatsapp: any = await ListWhatsAppsNumber(ticket.whatsappId, 'CONNECTED') - if (listWhatsapp.length > 1) { + if (listWhatsapp.length > 0) { for (let w = 0; w < listWhatsapp.length; w++) { diff --git a/backend/src/helpers/WhatsCache.ts b/backend/src/helpers/WhatsCache.ts index 45ed77e..0811ea6 100644 --- a/backend/src/helpers/WhatsCache.ts +++ b/backend/src/helpers/WhatsCache.ts @@ -113,18 +113,20 @@ async function searchWhatsappCache(id: string, status: string) { if (redis.status !== 'connect') return null + + const number_cache: any = await redis.hgetall(`whatsapp:${id}`) + + if(Object.entries(number_cache).length == 0){ + return [] + } + + console.log('NUMBER_CACHED: ', number_cache) + // @x:foo @y:bar - // const response: any = await redis.call('FT.SEARCH', 'idx_whatsapp', `(@status:*${status}*) (@number:*${number}*)`, 'SORTBY', 'status', 'ASC') - - // const response: any = await redis.call('FT.SEARCH', 'idx_whatsapp', `(@id:*${id}*))`) - - const response: any = [] - - const number_cache: any = await redis.hgetall(`whatsapp:${14}`) - - console.log('NUMBER CACHED: ', number_cache) - + const response: any = await redis.call('FT.SEARCH', 'idx_whatsapp', `(@status:*${status}*) (@number:*${number_cache.number}*)`, 'SORTBY', 'status', 'ASC') + + redis.quit() @@ -175,7 +177,7 @@ const insertOrUpeateWhatsCache = async (hash:any, whatsapp: any) => { await redis.hmset(hash,JSON.parse(JSON.stringify(whatsapp))); - console.log(`${whatsapp.length} WHATSAPP INSERTED OR UPADTED IN CACHE!`) + console.log(`WHATSAPP ID ${whatsapp.id} INSERTED OR UPADTED IN CACHE!`) } @@ -232,7 +234,7 @@ const createWhatsappIndexCache = async (hashIndex: string) => { await redis.call('FT.DROPINDEX', hashIndex) } - const response = await redis.call('FT.CREATE', hashIndex, 'ON', 'HASH', 'PREFIX', '1', 'whatsapp:', 'SCHEMA','id', 'NUMERIC', 'SORTABLE', 'status', 'TEXT', 'SORTABLE', 'number', 'TEXT') + const response = await redis.call('FT.CREATE', hashIndex, 'ON', 'HASH', 'PREFIX', '1', 'whatsapp:', 'SCHEMA','id', 'NUMERIC', 'status', 'TEXT', 'SORTABLE', 'number', 'TEXT', 'SORTABLE') console.log('Whatsapp index created: ', response) diff --git a/backend/src/libs/wbot.ts b/backend/src/libs/wbot.ts index e666211..589804f 100644 --- a/backend/src/libs/wbot.ts +++ b/backend/src/libs/wbot.ts @@ -21,6 +21,8 @@ const sessions: Session[] = []; let backupSession: any[] = [] import { insertOrUpeateWhatsCache } from "../helpers/WhatsCache"; +import { json } from "sequelize/types"; +import { restartWhatsSession } from "../helpers/RestartWhatsSession"; @@ -138,8 +140,28 @@ export const initWbot = async (whatsapp: Whatsapp, backupSessionRestore: boolean wbot.on("ready", async () => { logger.info(`Session: ${sessionName} READY`); - console.log('>>>>>>>>>>>>>> ready wbot.ts MOBILE NUMBER: ', wbot.info["wid"]["user"]) - + // console.log('>>>>>>>>>>>>>> ready wbot.ts MOBILE NUMBER: ', wbot.info["wid"]["user"]) + // console.log('::::::: WHATSAPP INFO: ', JSON.parse(JSON.stringify(whatsapp))) + + if(whatsapp.name.includes(wbot.info["wid"]["user"])){ + console.log('-----------------> THIS IS THE RIGHT NUMBER') + } + else{ + console.log('-----------------> THIS IS THE WRONG NUMBER') + let read_number = wbot.info["wid"]["user"] + + await wbot.logout() + + io.emit("whatsappSession", { + action: "error", + msg: `Numero lido: ${read_number} \nEssa sessão de whatsapp foi desconectada porque o numero que esta descrito no nome dessa sessão não corresponde ao numero lido!` + }); + + // restartWhatsSession(whatsapp) + + return + } + await whatsapp.update({ status: "CONNECTED", diff --git a/backend/src/routes/whatsappSessionRoutes.ts b/backend/src/routes/whatsappSessionRoutes.ts index 8a325f2..90e551e 100644 --- a/backend/src/routes/whatsappSessionRoutes.ts +++ b/backend/src/routes/whatsappSessionRoutes.ts @@ -12,6 +12,7 @@ whatsappSessionRoutes.post( isAuth, WhatsAppSessionController.store ); + whatsappSessionRoutes.put( "/whatsappsession/:whatsappId", diff --git a/backend/src/services/WbotServices/SendWhatsAppMessage.ts b/backend/src/services/WbotServices/SendWhatsAppMessage.ts index 68d4877..3e29aaa 100644 --- a/backend/src/services/WbotServices/SendWhatsAppMessage.ts +++ b/backend/src/services/WbotServices/SendWhatsAppMessage.ts @@ -21,6 +21,7 @@ import { json } from "sequelize/types"; import sendMessageMultiSession from "../../helpers/TrySendMessageMultiSession"; import { restartWhatsSession } from "../../helpers/RestartWhatsSession"; import { insertOrUpeateWhatsCache, searchWhatsappCache } from "../../helpers/WhatsCache"; +import GetDefaultWhatsApp from "../../helpers/GetDefaultWhatsApp"; @@ -47,41 +48,40 @@ const SendWhatsAppMessage = async ({ await GetWbotMessage(ticket, quotedMsg.id); quotedMsgSerializedId = SerializeWbotMsgId(ticket, quotedMsg); } + + + let whatsapps: any //TEST DEL - let whats_number = await searchWhatsappCache(`${ticket.whatsappId}`) - console.log('---') - console.log('whats_number search: ', whats_number) - console.log('---') + // const defaultWhatsapp = await GetDefaultWhatsApp(); + // console.log('DEFAULT WHATSAPP: ', JSON.parse(JSON.stringify(defaultWhatsapp))) - let whatsapps: any + let listWhatsapp = null + + listWhatsapp = await searchWhatsappCache(`${ticket.whatsappId}`, 'CONNECTED') - const listWhatsapp = await ListWhatsAppsNumber(ticket.whatsappId, 'CONNECTED') + if(!listWhatsapp){ + listWhatsapp = await ListWhatsAppsNumber(ticket.whatsappId, 'CONNECTED') + } + + // console.log('---') + // console.log('listWhatsapp search: ', listWhatsapp) + // console.log('---') if (listWhatsapp.length > 1) { - const _whatsapp = listWhatsapp[Math.floor(Math.random() * listWhatsapp.length)]; + console.log('entrou --------------------->') - await ticket.update({ whatsappId: _whatsapp.id }); + const _whatsapp = listWhatsapp[Math.floor(Math.random() * listWhatsapp.length)]; - } - else { + await ticket.update({ whatsappId: +_whatsapp.id }); - whatsapps = await Whatsapp.findOne({ - where: { id: ticket.whatsappId }, - attributes: ['status'] - }) + } - } + console.log('1 --------> ticket.whatsappId: ', ticket.whatsappId) - - - console.log('1 --------> ticket.whatsappId: ', ticket.whatsappId) - - - - if (listWhatsapp.length == 0 || (whatsapps && whatsapps.status != 'CONNECTED')) { + if (listWhatsapp.length == 0) { whatsapps = await wbotByUserQueue(ticket.userId) @@ -102,6 +102,57 @@ const SendWhatsAppMessage = async ({ } + +// + + + + + + // const listWhatsapp = await ListWhatsAppsNumber(ticket.whatsappId, 'CONNECTED') + + // if (listWhatsapp.length > 1) { + + // const _whatsapp = listWhatsapp[Math.floor(Math.random() * listWhatsapp.length)]; + + // await ticket.update({ whatsappId: _whatsapp.id }); + + // } + // else { + + // whatsapps = await Whatsapp.findOne({ + // where: { id: ticket.whatsappId }, + // attributes: ['status'] + // }) + + // } + + + // console.log('1 --------> ticket.whatsappId: ', ticket.whatsappId) + + + + // if (listWhatsapp.length == 0 || (whatsapps && whatsapps.status != 'CONNECTED')) { + + // whatsapps = await wbotByUserQueue(ticket.userId) + + // if (whatsapps.length > 0) { + + // if (whatsapps.length > 1) { + + // await ticket.update({ whatsappId: whatsapps[+WhatsIndex(whatsapps)].id }); + + // } + // else { + + // await ticket.update({ whatsappId: whatsapps[0].id }); + + // } + + // } + + // } + const wbot = await GetTicketWbot(ticket); console.log('2 --------> send from whatsapp ticket.whatsappId: ', ticket.whatsappId) diff --git a/backend/src/services/WbotServices/wbotMessageListener.ts b/backend/src/services/WbotServices/wbotMessageListener.ts index 24470c1..0bfc460 100644 --- a/backend/src/services/WbotServices/wbotMessageListener.ts +++ b/backend/src/services/WbotServices/wbotMessageListener.ts @@ -365,9 +365,9 @@ const botSendMessage = (ticket: Ticket, contact: Contact, wbot: Session, msg: st const _clear_lst = () => { - console.log('LIST (lst.length) WHATSAPP MESSAGE ID MULTI SESSION: : ', lst.length) + console.log('WHATSAPP MESSAGE ID MULTI SESSION: ', lst.length) - if (lst.length < 800 ) return + if (lst.length < 200 ) return console.log('BEFORE lst SLICE: ', lst) diff --git a/backend/src/services/WhatsappService/UpdateWhatsAppService.ts b/backend/src/services/WhatsappService/UpdateWhatsAppService.ts index 2b4e850..6b4d3c6 100644 --- a/backend/src/services/WhatsappService/UpdateWhatsAppService.ts +++ b/backend/src/services/WhatsappService/UpdateWhatsAppService.ts @@ -6,6 +6,10 @@ import Whatsapp from "../../models/Whatsapp"; import ShowWhatsAppService from "./ShowWhatsAppService"; import AssociateWhatsappQueue from "./AssociateWhatsappQueue"; import { insertOrUpeateWhatsCache } from "../../helpers/WhatsCache"; +import { getWbot } from "../../libs/wbot"; +import { restartWhatsSession } from "../../helpers/RestartWhatsSession"; + + interface WhatsappData { name?: string; @@ -47,6 +51,8 @@ const UpdateWhatsAppService = async ({ queueIds = [] } = whatsappData; + + try { await schema.validate({ name, status, isDefault }); } catch (err) { @@ -68,8 +74,16 @@ const UpdateWhatsAppService = async ({ } } - const whatsapp = await ShowWhatsAppService(whatsappId); + const whatsapp = await ShowWhatsAppService(whatsappId); + // console.log('############## whatsapp: ', JSON.parse(JSON.stringify(whatsapp))) + + if(name && !name.includes(whatsapp.number) && whatsapp.status === 'CONNECTED'){ + + throw new AppError("ERR_WAPP_WRONG_SESSION_NAME"); + + } + await whatsapp.update({ name, status, diff --git a/frontend/src/components/QrcodeModal/index.js b/frontend/src/components/QrcodeModal/index.js index 78b75b6..dcca527 100644 --- a/frontend/src/components/QrcodeModal/index.js +++ b/frontend/src/components/QrcodeModal/index.js @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { useEffect, useState, useContext } from "react"; import QRCode from "qrcode.react"; import openSocket from "socket.io-client"; import toastError from "../../errors/toastError"; @@ -7,7 +7,12 @@ import { Dialog, DialogContent, Paper, Typography } from "@material-ui/core"; import { i18n } from "../../translate/i18n"; import api from "../../services/api"; +import { AuthContext } from "../../context/Auth/AuthContext"; + const QrcodeModal = ({ open, onClose, whatsAppId }) => { + + const { user } = useContext(AuthContext); + const [qrCode, setQrCode] = useState(""); useEffect(() => { @@ -36,12 +41,24 @@ const QrcodeModal = ({ open, onClose, whatsAppId }) => { if (data.action === "update" && data.session.qrcode === "") { onClose(); } + + if (data.action === "error") { + + console.log('user.profile: ', user.profile) + + if(user.profile === 'master'){ + + alert(data.msg) + + } + + } }); return () => { socket.disconnect(); }; - }, [whatsAppId, onClose]); + }, [whatsAppId, onClose, user.profile]); return ( diff --git a/frontend/src/hooks/useWhatsApps/index.js b/frontend/src/hooks/useWhatsApps/index.js index a0b51fd..1360ac1 100644 --- a/frontend/src/hooks/useWhatsApps/index.js +++ b/frontend/src/hooks/useWhatsApps/index.js @@ -2,6 +2,7 @@ import { useState, useEffect, useReducer } from "react"; import openSocket from "socket.io-client"; import toastError from "../../errors/toastError"; + import api from "../../services/api"; const reducer = (state, action) => { @@ -28,16 +29,39 @@ const reducer = (state, action) => { const whatsAppIndex = state.findIndex(s => s.id === whatsApp.id); if (whatsAppIndex !== -1) { - state[whatsAppIndex].status = whatsApp.status; - state[whatsAppIndex].updatedAt = whatsApp.updatedAt; - state[whatsAppIndex].qrcode = whatsApp.qrcode; - state[whatsAppIndex].retries = whatsApp.retries; + + if ('disabled' in whatsApp) { + state[whatsAppIndex].disabled = whatsApp.disabled + } + else { + state[whatsAppIndex].status = whatsApp.status; + state[whatsAppIndex].updatedAt = whatsApp.updatedAt; + state[whatsAppIndex].qrcode = whatsApp.qrcode; + state[whatsAppIndex].retries = whatsApp.retries; + } + + return [...state]; } else { return [...state]; } } + // if(action.type === "UPDATE_SESSION_RESTORE"){ + + // const whatsApp = action.payload; + + // console.log('------> whatsApp: ', whatsApp) + + // const whatsAppIndex = state.findIndex(s => s.id === whatsApp.id); + + // if (whatsAppIndex !== -1) { + // console.log('kkkkkkkkkkkkkkkkkkkkkkkkkk: ',whatsAppIndex) + + // return [...state]; + // } + // } + // if (action.type === "UPDATE_DISK_SPACE_MONIT") { // const whatsApp = action.payload; @@ -56,7 +80,7 @@ const reducer = (state, action) => { const whatsApp = action.payload; const whatsAppIndex = state.findIndex(s => s.id === whatsApp.id); - if (whatsAppIndex !== -1) { + if (whatsAppIndex !== -1) { state[whatsAppIndex].sessionSize = whatsApp.sessionSize; return [...state]; } else { @@ -84,6 +108,8 @@ const useWhatsApps = () => { const [whatsApps, dispatch] = useReducer(reducer, []); const [loading, setLoading] = useState(true); + + useEffect(() => { setLoading(true); const fetchSession = async () => { @@ -115,22 +141,21 @@ const useWhatsApps = () => { }); socket.on("whatsappSession", data => { - if (data.action === "update") { - + if (data.action === "update") { dispatch({ type: "UPDATE_SESSION", payload: data.session }); } - }); + else if (data.action === "update_restore") { + dispatch({ type: "UPDATE_SESSION_RESTORE", payload: data.session }); + } + }); socket.on("whatsappSessionMonit", data => { if (data.action === "update") { - - - dispatch({ type: "UPDATE_WHATSAPPS_SESSION_MONIT", payload: data.whatsappSessionSize }); } - }); - - + }); + + return () => { socket.disconnect(); diff --git a/frontend/src/pages/Connections/index.js b/frontend/src/pages/Connections/index.js index 2efc13d..9e968cb 100644 --- a/frontend/src/pages/Connections/index.js +++ b/frontend/src/pages/Connections/index.js @@ -114,8 +114,8 @@ const Connections = () => { const [confirmModalOpen, setConfirmModalOpen] = useState(false); const [diskSpaceInfo, setDiskSpaceInfo] = useState({}); - - + + const [disabled, setDisabled] = useState(true); const confirmationModalInitialState = { @@ -140,7 +140,9 @@ const Connections = () => { const handleRestartWhatsAppSession = async whatsAppId => { try { + await api.post(`/restartwhatsappsession/${whatsAppId}`); + } catch (err) { toastError(err); } @@ -329,6 +331,32 @@ const Connections = () => { }; + + + useEffect(() => { + + const delayDebounceFn = setTimeout(() => { + + const fetchQueries = async () => { + try { + + await api.post(`/restartwhatsappsession/0`, { params: { status: 'status' }, }); + + setDisabled(false) + + } catch (err) { + console.log(err); + } + }; + + fetchQueries(); + + }, 500); + return () => clearTimeout(delayDebounceFn); + + }, []); + + useEffect(() => { const socket = openSocket(process.env.REACT_APP_BACKEND_URL); @@ -407,37 +435,37 @@ const Connections = () => { perform="space-disk-info:show" yes={() => ( <> - - - - - Size - - - Used - - - Available - - - Use% - - - - - - - {diskSpaceInfo.size} - {diskSpaceInfo.used} - {diskSpaceInfo.available} - {diskSpaceInfo.use} - - -
-
- + + + + + Size + + + Used + + + Available + + + Use% + + + + + + + {diskSpaceInfo.size} + {diskSpaceInfo.used} + {diskSpaceInfo.available} + {diskSpaceInfo.use} + + +
+
+ )} - /> + /> @@ -533,9 +561,11 @@ const Connections = () => { role={user.profile} perform="connection-button:show" yes={() => ( + diff --git a/frontend/src/translate/languages/en.js b/frontend/src/translate/languages/en.js index 0391037..6484c5c 100644 --- a/frontend/src/translate/languages/en.js +++ b/frontend/src/translate/languages/en.js @@ -453,6 +453,8 @@ const messages = { "This color is already in use, pick another one.", ERR_WAPP_GREETING_REQUIRED: "Greeting message is required if there is more than one queue.", + ERR_WAPP_WRONG_SESSION_NAME: + "The number updated in the session name does not match the number read! To change the new number in the name disconnect the session!", }, }, }, diff --git a/frontend/src/translate/languages/es.js b/frontend/src/translate/languages/es.js index b4f7d5e..2e27e49 100644 --- a/frontend/src/translate/languages/es.js +++ b/frontend/src/translate/languages/es.js @@ -460,6 +460,9 @@ const messages = { "Este color ya está en uso, elija otro.", ERR_WAPP_GREETING_REQUIRED: "El mensaje de saludo es obligatorio cuando hay más de una cola.", + ERR_WAPP_WRONG_SESSION_NAME: + "¡El número actualizado en el nombre de la sesión no coincide con el número leído! Para cambiar el nuevo número en el nombre desconecte la sesión!", + }, }, }, diff --git a/frontend/src/translate/languages/pt.js b/frontend/src/translate/languages/pt.js index d3b7835..a92ab11 100644 --- a/frontend/src/translate/languages/pt.js +++ b/frontend/src/translate/languages/pt.js @@ -458,6 +458,10 @@ const messages = { "Esta cor já está em uso, escolha outra.", ERR_WAPP_GREETING_REQUIRED: "A mensagem de saudação é obrigatório quando há mais de uma fila.", + ERR_WAPP_WRONG_SESSION_NAME: + "O numero atualizado no nome da sessão não corresponde ao numero lido! Para alterar o novo numero no nome desconecte a sessão!", + + }, }, }, From 1ef86354f8667a8e5529080655b4bf05632749ca Mon Sep 17 00:00:00 2001 From: adriano Date: Mon, 12 Dec 2022 13:02:18 -0300 Subject: [PATCH 07/12] Trabalhando no restore automatico --- backend/src/libs/wbot.ts | 5 +---- backend/src/services/WbotServices/StartWhatsAppSession.ts | 2 ++ backend/src/services/WbotServices/wbotMonitor.ts | 1 + 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/src/libs/wbot.ts b/backend/src/libs/wbot.ts index 589804f..0401c0a 100644 --- a/backend/src/libs/wbot.ts +++ b/backend/src/libs/wbot.ts @@ -138,10 +138,7 @@ export const initWbot = async (whatsapp: Whatsapp, backupSessionRestore: boolean }); wbot.on("ready", async () => { - logger.info(`Session: ${sessionName} READY`); - - // console.log('>>>>>>>>>>>>>> ready wbot.ts MOBILE NUMBER: ', wbot.info["wid"]["user"]) - // console.log('::::::: WHATSAPP INFO: ', JSON.parse(JSON.stringify(whatsapp))) + logger.info(`Session: ${sessionName} READY`); if(whatsapp.name.includes(wbot.info["wid"]["user"])){ console.log('-----------------> THIS IS THE RIGHT NUMBER') diff --git a/backend/src/services/WbotServices/StartWhatsAppSession.ts b/backend/src/services/WbotServices/StartWhatsAppSession.ts index bd34e23..2a21931 100644 --- a/backend/src/services/WbotServices/StartWhatsAppSession.ts +++ b/backend/src/services/WbotServices/StartWhatsAppSession.ts @@ -8,6 +8,8 @@ import { insertOrUpeateWhatsCache } from "../../helpers/WhatsCache"; export const StartWhatsAppSession = async (whatsapp: Whatsapp, backupSession: boolean = false): Promise => { await whatsapp.update({ status: "OPENING" }); + + console.log('kkkkkkkkkkkkkxxxxxxxxxxxxxxxxxx') await insertOrUpeateWhatsCache(`whatsapp:${whatsapp.id}`, { status: "OPENING", diff --git a/backend/src/services/WbotServices/wbotMonitor.ts b/backend/src/services/WbotServices/wbotMonitor.ts index c7e0565..d2b1e46 100644 --- a/backend/src/services/WbotServices/wbotMonitor.ts +++ b/backend/src/services/WbotServices/wbotMonitor.ts @@ -60,6 +60,7 @@ const wbotMonitor = async ( wbot.on("disconnected", async reason => { logger.info(`Disconnected session: ${sessionName}, reason: ${reason}`); try { + await whatsapp.update({ status: "OPENING", session: "" }); await insertOrUpeateWhatsCache(`whatsapp:${whatsapp.id}`, { status: "OPENING", session: "" }) } catch (err) { From 464182d53b46defea433b34c4c959f90a5177cf2 Mon Sep 17 00:00:00 2001 From: adriano Date: Wed, 14 Dec 2022 09:29:42 -0300 Subject: [PATCH 08/12] =?UTF-8?q?Conclus=C3=A3o=20do=20recurso=20de=20mult?= =?UTF-8?q?i-sessoes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/WhatsAppSessionController.ts | 39 ++--- backend/src/helpers/AutoRestore.ts | 69 +++++++++ backend/src/helpers/CreateSessionDir.ts | 72 ++++++++++ backend/src/helpers/RestoreControll.ts | 135 ++++++++++++++++++ .../src/helpers/SetTicketMessagesAsRead.ts | 5 +- backend/src/helpers/WhatsCache.ts | 2 +- backend/src/server.ts | 6 +- .../WbotServices/SendWhatsAppMessage.ts | 26 ++-- .../WbotServices/StartWhatsAppSession.ts | 89 +++++++++++- .../WbotServices/wbotMessageListener.ts | 10 +- 10 files changed, 396 insertions(+), 57 deletions(-) create mode 100644 backend/src/helpers/AutoRestore.ts create mode 100644 backend/src/helpers/CreateSessionDir.ts create mode 100644 backend/src/helpers/RestoreControll.ts diff --git a/backend/src/controllers/WhatsAppSessionController.ts b/backend/src/controllers/WhatsAppSessionController.ts index e1fbeaa..dcb698d 100644 --- a/backend/src/controllers/WhatsAppSessionController.ts +++ b/backend/src/controllers/WhatsAppSessionController.ts @@ -11,9 +11,12 @@ import path from 'path'; import { getIO } from "../libs/socket"; import { stat } from "fs"; -let lstRestore: any = [] +import { setRestoreControll, getRestoreControll, shifRestoreControll } from "../helpers/RestoreControll"; -// import { WWebJsw } from "../../WWebJS/session-bd_40" +import autoRestore from "../helpers/AutoRestore"; + + +// let lstRestore: any = [] const store = async (req: Request, res: Response): Promise => { const { whatsappId } = req.params; @@ -47,9 +50,11 @@ const restart = async (req: Request, res: Response): Promise => { const io = getIO(); - if (Object.keys(req.body).length > 0) { + if (Object.keys(req.body).length > 0) { - for (let i = 0; i < lstRestore.length; i++) { + let lstRestore: any = getRestoreControll() + + for (let i = 0; i < lstRestore.length; i++) { io.emit("whatsappSession", { action: "update", @@ -60,32 +65,10 @@ const restart = async (req: Request, res: Response): Promise => { return res.status(200).json({}); - } - - const whatsapp = await ShowWhatsAppService(whatsappId); + } - restartWhatsSession(whatsapp, true) + await autoRestore(whatsappId, 'human') - lstRestore.push({ 'id': +whatsappId, 'disabled': true }) - - io.emit("whatsappSession", { - action: "update", - session: { 'id': +whatsappId, 'disabled': true } - }); - - setTimeout(() => { - - let whatsapp = lstRestore.shift(); - - whatsapp.disabled = false - - io.emit("whatsappSession", { - action: "update", - session: whatsapp - }); - - }, 25000); - return res.status(200).json({ message: "Starting session." }); }; diff --git a/backend/src/helpers/AutoRestore.ts b/backend/src/helpers/AutoRestore.ts new file mode 100644 index 0000000..e56e3c2 --- /dev/null +++ b/backend/src/helpers/AutoRestore.ts @@ -0,0 +1,69 @@ +import ShowWhatsAppService from "../services/WhatsappService/ShowWhatsAppService"; +import { restartWhatsSession } from "./RestartWhatsSession"; +import { getRestoreControll, setRestoreControll, shifRestoreControll } from "./RestoreControll"; + +const fsPromises = require("fs/promises"); +const fs = require('fs') + +import { getIO } from "../libs/socket"; +import path from "path"; +import { splitDateTime } from "./SplitDateTime"; +import { format } from "date-fns"; +import ptBR from 'date-fns/locale/pt-BR'; +import { number } from "yargs"; + +const autoRestore = async (whatsappId: string | number, started_action_by: string = '') => { + + const whatsapp = await ShowWhatsAppService(whatsappId); + + restartWhatsSession(whatsapp, true) + + + const sourcePath = path.join(__dirname, `../../.wwebjs_auth/sessions/log`) + + if (fs.existsSync(sourcePath)) { + + let log = new Date(new Date() + 'UTC'); + + const dateToday = splitDateTime(new Date(format(new Date(), 'yyyy-MM-dd HH:mm:ss', { locale: ptBR }))) + + let timestamp = Math.floor(Date.now() / 1000) + + let number: any = whatsapp.number + + if (!number) { + number = '' + } + + fs.writeFileSync(`${sourcePath}/${timestamp}_restore_${number}_triggered_by_${started_action_by}_id_${whatsappId}.txt`, `Whatsapp id: ${whatsapp.id} \nDate: ${dateToday.fullDate} ${dateToday.fullTime}`, (error: any) => { console.log(error) }); + + } + + + setRestoreControll({ 'id': +whatsappId, 'disabled': true }) + + let lstRestore: any = getRestoreControll() + + const io = getIO(); + + io.emit("whatsappSession", { + action: "update", + session: { 'id': +whatsappId, 'disabled': true } + }); + + setTimeout(() => { + + let whatsapp = shifRestoreControll(); + + whatsapp.disabled = false + + io.emit("whatsappSession", { + action: "update", + session: whatsapp + }); + + }, 25000); + +} + +export default autoRestore; \ No newline at end of file diff --git a/backend/src/helpers/CreateSessionDir.ts b/backend/src/helpers/CreateSessionDir.ts new file mode 100644 index 0000000..6f20c80 --- /dev/null +++ b/backend/src/helpers/CreateSessionDir.ts @@ -0,0 +1,72 @@ +import os from 'os'; +import dir from 'path'; +import fs from 'fs'; +import path from 'path'; + +// Delete a directory and its children +export const createSessionDir = () => { + + console.log('process.cwd(): ', process.cwd()) + + const wwebjsAuthPath = dir.join(process.cwd(), '.wwebjs_auth'); + const sessionPath = dir.join(process.cwd(), '.wwebjs_auth', 'sessions'); + const sessionLogPath = dir.join(process.cwd(), '.wwebjs_auth', 'sessions','log'); + + fs.access(wwebjsAuthPath, (error) => { + // To check if the given directory + // already exists or not + if (error) { + // If current directory does not exist + // then create it + fs.mkdir(wwebjsAuthPath, (error) => { + if (error) { + console.log(error); + } else { + console.log(`wwebjs_auth Directory created successfully !!!`); + } + }); + } else { + console.log("wwebjs_auth Directory already exists !!"); + } + }); + + + fs.access(sessionPath, (error) => { + // To check if the given directory + // already exists or not + if (error) { + // If current directory does not exist + // then create it + fs.mkdir(sessionPath, (error) => { + if (error) { + console.log(error); + } else { + console.log(`sessions Directory created successfully !!!`); + } + }); + } else { + console.log("sessions Directory already exists !!"); + } + }); + + fs.access(sessionLogPath, (error) => { + + // To check if the given directory + // already exists or not + if (error) { + // If current directory does not exist + // then create it + fs.mkdir(sessionLogPath, (error) => { + if (error) { + console.log(error); + } else { + console.log(`log Directory created successfully !!!`); + } + }); + } else { + console.log("log Directory already exists !!"); + } + }); + + +} \ No newline at end of file diff --git a/backend/src/helpers/RestoreControll.ts b/backend/src/helpers/RestoreControll.ts new file mode 100644 index 0000000..22ae676 --- /dev/null +++ b/backend/src/helpers/RestoreControll.ts @@ -0,0 +1,135 @@ + +import os from 'os'; +import dir from 'path'; +import fs from 'fs'; + +export const setRestoreControll = (obj: object) => { + + const restoreInfoFile = dir.join(os.tmpdir(), `restoreInfo.json`); + + try { + + if (fs.existsSync(restoreInfoFile)) { + + if (Array.isArray(obj)) { + + fs.writeFileSync(restoreInfoFile, JSON.stringify(obj), "utf8"); + + } + else { + + const restoreInfo = fs.readFileSync(restoreInfoFile, { encoding: 'utf8', flag: 'r' }); + + let lstRestore: any = JSON.parse(restoreInfo) + + lstRestore.push(obj) + + fs.writeFileSync(restoreInfoFile, JSON.stringify(lstRestore), "utf8"); + } + + + } else { + + console.log('restoreInfo.json file not found! It will be created.'); + + if (Array.isArray(obj)) { + + fs.writeFileSync(restoreInfoFile, JSON.stringify(obj), "utf8"); + + } + else { + + fs.writeFileSync(restoreInfoFile, JSON.stringify([obj]), "utf8"); + + } + + + } + + } catch (error) { + console.log('There was an error on try to read the restoreInfo.json file: ', error) + } + +} + +export const shifRestoreControll = () => { + + const restoreInfoFile = dir.join(os.tmpdir(), `restoreInfo.json`); + + try { + + if (fs.existsSync(restoreInfoFile)) { + + const restoreInfo = fs.readFileSync(restoreInfoFile, { encoding: 'utf8', flag: 'r' }); + + let lstRestore: any = JSON.parse(restoreInfo) + + let whatsapp: any = lstRestore.shift() + + fs.writeFileSync(restoreInfoFile, JSON.stringify(lstRestore), "utf8"); + + return whatsapp + + } + + } catch (error) { + console.log('There was an error on try to read the restoreInfo.json file: ', error) + } + + return {} + +} + +export const delRestoreControllFile = () => { + + const restoreInfoFile = dir.join(os.tmpdir(), `restoreInfo.json`); + + try { + + if (fs.existsSync(restoreInfoFile)) { + + fs.unlinkSync(restoreInfoFile) + + } else { + + console.log('restoreInfo.json file not found!'); + + } + + } catch (error) { + console.log('There was an error on try delete the restoreInfo.json file: ', error) + } + +} + + + + +export const getRestoreControll = () => { + + const restoreInfoFile = dir.join(os.tmpdir(), `restoreInfo.json`); + + try { + + if (fs.existsSync(restoreInfoFile)) { + + const restoreInfo = fs.readFileSync(restoreInfoFile, { encoding: 'utf8', flag: 'r' }); + + let lstRestore: any = JSON.parse(restoreInfo) + + return lstRestore + + + } else { + + console.log('restoreInfo.json file not found!'); + + } + + } catch (error) { + console.log('There was an error on try to read the restoreInfo.json file: ', error) + } + + return [] + +} \ No newline at end of file diff --git a/backend/src/helpers/SetTicketMessagesAsRead.ts b/backend/src/helpers/SetTicketMessagesAsRead.ts index e880336..a14d97c 100644 --- a/backend/src/helpers/SetTicketMessagesAsRead.ts +++ b/backend/src/helpers/SetTicketMessagesAsRead.ts @@ -44,7 +44,7 @@ const SetTicketMessagesAsRead = async (ticket: Ticket): Promise => { //Solução para contornar erro de sessão if ((`${err}`).includes("Evaluation failed: r") && ticket.whatsappId) { - const sourcePath = path.join(__dirname, `../../.wwebjs_auth/sessions`) + const sourcePath = path.join(__dirname, `../../.wwebjs_auth/sessions/log`) const dateToday = splitDateTime(new Date(format(new Date(), 'yyyy-MM-dd HH:mm:ss', { locale: ptBR }))) @@ -52,12 +52,11 @@ const SetTicketMessagesAsRead = async (ticket: Ticket): Promise => { if (whatsapp && whatsapp.status == 'CONNECTED') { - let timestamp = Math.floor(Date.now() / 1000) fs.writeFile(`${sourcePath}/${timestamp}_SetTicketMessagesAsRead.txt`, `Whatsapp id: ${whatsapp.id} \nDate: ${dateToday.fullDate} ${dateToday.fullTime} \nFile: SetTicketMessagesAsRead.ts \nError: ${err}`, (error) => { }); - await restartWhatsSession(whatsapp) + // await restartWhatsSession(whatsapp) } diff --git a/backend/src/helpers/WhatsCache.ts b/backend/src/helpers/WhatsCache.ts index 0811ea6..4a6559b 100644 --- a/backend/src/helpers/WhatsCache.ts +++ b/backend/src/helpers/WhatsCache.ts @@ -120,7 +120,7 @@ async function searchWhatsappCache(id: string, status: string) { return [] } - console.log('NUMBER_CACHED: ', number_cache) + // console.log('NUMBER_CACHED: ', number_cache) // @x:foo @y:bar diff --git a/backend/src/server.ts b/backend/src/server.ts index b5c793c..4602c3d 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -10,6 +10,8 @@ import { startWhoIsOnlineMonitor } from "./helpers/WhoIsOnlineMonitor" import { loadTicketsCache, flushCache, cacheSize } from './helpers/TicketCache' import { loadContactsCache } from './helpers/ContactsCache' import { loadWhatsappCache } from './helpers/WhatsCache' +import { delRestoreControllFile } from "./helpers/RestoreControll"; +import { createSessionDir } from "./helpers/CreateSessionDir"; const server = app.listen(process.env.PORT, () => { logger.info(`Server started on port: ${process.env.PORT}`); @@ -32,9 +34,11 @@ gracefulShutdown(server); await loadTicketsCache() await loadWhatsappCache() } + })() - +createSessionDir() +delRestoreControllFile() startSchedulingMonitor(5000) startWhoIsOnlineMonitor(3000) diff --git a/backend/src/services/WbotServices/SendWhatsAppMessage.ts b/backend/src/services/WbotServices/SendWhatsAppMessage.ts index 3e29aaa..7e8039c 100644 --- a/backend/src/services/WbotServices/SendWhatsAppMessage.ts +++ b/backend/src/services/WbotServices/SendWhatsAppMessage.ts @@ -22,6 +22,7 @@ import sendMessageMultiSession from "../../helpers/TrySendMessageMultiSession"; import { restartWhatsSession } from "../../helpers/RestartWhatsSession"; import { insertOrUpeateWhatsCache, searchWhatsappCache } from "../../helpers/WhatsCache"; import GetDefaultWhatsApp from "../../helpers/GetDefaultWhatsApp"; +import autoRestore from "../../helpers/AutoRestore"; @@ -51,17 +52,17 @@ const SendWhatsAppMessage = async ({ let whatsapps: any - + //TEST DEL // const defaultWhatsapp = await GetDefaultWhatsApp(); // console.log('DEFAULT WHATSAPP: ', JSON.parse(JSON.stringify(defaultWhatsapp))) let listWhatsapp = null - + listWhatsapp = await searchWhatsappCache(`${ticket.whatsappId}`, 'CONNECTED') - if(!listWhatsapp){ + if (!listWhatsapp) { listWhatsapp = await ListWhatsAppsNumber(ticket.whatsappId, 'CONNECTED') } @@ -73,15 +74,15 @@ const SendWhatsAppMessage = async ({ console.log('entrou --------------------->') - const _whatsapp = listWhatsapp[Math.floor(Math.random() * listWhatsapp.length)]; + const _whatsapp = listWhatsapp[Math.floor(Math.random() * listWhatsapp.length)]; await ticket.update({ whatsappId: +_whatsapp.id }); - } + } - console.log('1 --------> ticket.whatsappId: ', ticket.whatsappId) + console.log('1 --------> ticket.whatsappId: ', ticket.whatsappId) - if (listWhatsapp.length == 0) { + if (listWhatsapp.length == 0) { whatsapps = await wbotByUserQueue(ticket.userId) @@ -102,13 +103,13 @@ const SendWhatsAppMessage = async ({ } - -// + + // + - // const listWhatsapp = await ListWhatsAppsNumber(ticket.whatsappId, 'CONNECTED') // if (listWhatsapp.length > 1) { @@ -186,11 +187,10 @@ const SendWhatsAppMessage = async ({ status: "RESTORING", }) - setTimeout(() => restartWhatsSession(whatsapp, true), 90000); + // setTimeout(() => restartWhatsSession(whatsapp, true), 90000); + setTimeout(async () => await autoRestore(whatsapp.id, 'auto_send_message'), 95000); } - - const sentMessage = await sendMessageMultiSession(ticket, body, quotedMsgSerializedId) if (sentMessage.length > 0) { diff --git a/backend/src/services/WbotServices/StartWhatsAppSession.ts b/backend/src/services/WbotServices/StartWhatsAppSession.ts index 2a21931..2ecfbc6 100644 --- a/backend/src/services/WbotServices/StartWhatsAppSession.ts +++ b/backend/src/services/WbotServices/StartWhatsAppSession.ts @@ -6,15 +6,96 @@ import wbotMonitor from "./wbotMonitor"; import { logger } from "../../utils/logger"; import { insertOrUpeateWhatsCache } from "../../helpers/WhatsCache"; -export const StartWhatsAppSession = async (whatsapp: Whatsapp, backupSession: boolean = false): Promise => { - await whatsapp.update({ status: "OPENING" }); +import { getRestoreControll, setRestoreControll, shifRestoreControll } from "../../helpers/RestoreControll"; +import ShowWhatsAppService from "../WhatsappService/ShowWhatsAppService"; +import { restartWhatsSession } from "../../helpers/RestartWhatsSession"; + +import autoRestore from "../../helpers/AutoRestore"; + +let lstAutoRestore: any = [] + +export const StartWhatsAppSession = async (whatsapp: Whatsapp, backupSession: boolean = false): Promise => { + await whatsapp.update({ status: "OPENING" }); - console.log('kkkkkkkkkkkkkxxxxxxxxxxxxxxxxxx') - await insertOrUpeateWhatsCache(`whatsapp:${whatsapp.id}`, { status: "OPENING", }) + + + try { + + let lstRestore: any = getRestoreControll() + + if (Object.keys(lstRestore.filter((e: any) => +e.id == +whatsapp.id)).length) { + + console.log('kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk: ', whatsapp.id) + + } + else { + + lstAutoRestore.push({ 'whatsappId': +whatsapp.id }) + + setTimeout(async () => { + + lstRestore = getRestoreControll() + + let count = lstAutoRestore.length + + for (let i = 0; i < count; i++) { + + let autoR = lstAutoRestore.shift() + + console.log('----------------> autoR: ', autoR) + + if (autoR && autoR.whatsappId) { + + if (Object.keys(lstRestore.filter((e: any) => +e.id == +autoR.whatsappId)).length) { + + console.log(' ACONTECENDO RESTORING autoR: ', autoR) + + continue + } + + const _whatsapp = await Whatsapp.findOne({ where: { id: autoR.whatsappId } }); + + let whatsappStatus = ["CONFLICT", + "DEPRECATED_VERSION ", + "OPENING ", + "PROXYBLOCK ", + "SMB_TOS_BLOCK ", + "TIMEOUT ", + "TOS_BLOCK ", + "UNLAUNCHED ", + "UNPAIRED ", + "UNPAIRED_IDLE"] + + if (_whatsapp?.status) { + + if (whatsappStatus.includes(_whatsapp.status)) { + + await autoRestore(autoR.whatsappId, 'auto_monit') + + } + + } + + } + + } + + + }, 20000); + + } + + } catch (error) { + console.log('There was an error on try execute AUTO-RESTORE: ', error) + } + + + + const io = getIO(); io.emit("whatsappSession", { action: "update", diff --git a/backend/src/services/WbotServices/wbotMessageListener.ts b/backend/src/services/WbotServices/wbotMessageListener.ts index 0bfc460..8099454 100644 --- a/backend/src/services/WbotServices/wbotMessageListener.ts +++ b/backend/src/services/WbotServices/wbotMessageListener.ts @@ -879,24 +879,20 @@ const handleMessage = async ( //Solução para contornar erro de sessão if ((`${err}`).includes("Evaluation failed: r")) { - const sourcePath = path.join(__dirname, `../../../.wwebjs_auth/sessions`) + const sourcePath = path.join(__dirname, `../../../.wwebjs_auth/sessions/log`) let log = new Date(new Date() + 'UTC'); const dateToday = splitDateTime(new Date(format(new Date(), 'yyyy-MM-dd HH:mm:ss', { locale: ptBR }))) const whatsapp = await ShowWhatsAppService(wbot.id!); - if (whatsapp.status == 'CONNECTED') { - - + if (whatsapp.status == 'CONNECTED') { let timestamp = Math.floor(Date.now() / 1000) fs.writeFile(`${sourcePath}/${timestamp}_wbotMessageListener.txt`, `Whatsapp id: ${whatsapp.id} \nDate: ${dateToday.fullDate} ${dateToday.fullTime} \nFile: wbotMessageListener.ts \nError: ${err}`, (error) => { }); - - await restartWhatsSession(whatsapp) - + // await restartWhatsSession(whatsapp) } From ae762460b8a464cd538da939313297589b5d3368 Mon Sep 17 00:00:00 2001 From: adriano Date: Wed, 14 Dec 2022 10:35:48 -0300 Subject: [PATCH 09/12] =?UTF-8?q?Remo=C3=A7=C3=A3o=20de=20console.log?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/services/WbotServices/SendWhatsAppMessage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/services/WbotServices/SendWhatsAppMessage.ts b/backend/src/services/WbotServices/SendWhatsAppMessage.ts index 7e8039c..636c0e5 100644 --- a/backend/src/services/WbotServices/SendWhatsAppMessage.ts +++ b/backend/src/services/WbotServices/SendWhatsAppMessage.ts @@ -38,7 +38,7 @@ const SendWhatsAppMessage = async ({ quotedMsg }: Request): Promise => { - var timetaken = "Time taken to send message"; + var timetaken = "####### Time taken to send message"; console.time(timetaken) From e89a54e3946c81d8480c3347baecfc8dae5a87b4 Mon Sep 17 00:00:00 2001 From: adriano Date: Wed, 14 Dec 2022 10:36:05 -0300 Subject: [PATCH 10/12] =?UTF-8?q?Remo=C3=A7=C3=A3o=20de=20console.log?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/services/WbotServices/wbotMessageListener.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/services/WbotServices/wbotMessageListener.ts b/backend/src/services/WbotServices/wbotMessageListener.ts index 8099454..f504bae 100644 --- a/backend/src/services/WbotServices/wbotMessageListener.ts +++ b/backend/src/services/WbotServices/wbotMessageListener.ts @@ -367,7 +367,7 @@ const _clear_lst = () => { console.log('WHATSAPP MESSAGE ID MULTI SESSION: ', lst.length) - if (lst.length < 200 ) return + if (lst.length <= 200 ) return console.log('BEFORE lst SLICE: ', lst) @@ -388,7 +388,7 @@ const clearMultiSessionWhatsappMessageId = () => { try { clearInterval(clear_lst); - _clear_lst() + _clear_lst() } catch (error) { console.log('error on clear lst whatsapp id message: ', error) From e10e9e9e5c9a6fd2fa24857339416a0f9df17c9d Mon Sep 17 00:00:00 2001 From: adriano Date: Thu, 15 Dec 2022 12:27:54 -0300 Subject: [PATCH 11/12] =?UTF-8?q?altera=C3=A7=C3=A3o=20no=20gitignore=20pa?= =?UTF-8?q?ra=20ignorar=20arquivos=20de=20log?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.gitignore b/.gitignore index b2d5d94..e19e6cd 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,16 @@ session-bd* */session-bd*/* **session-bd* +sessions* +/sessions* +*/sessions*/* +**sessions* + +log* +/log* +*/log*/* +**log* + WWebJS /WWebJS */WWebJS/* From 8ba8da82500df4263c6c40f871b7d02dc8a10ef0 Mon Sep 17 00:00:00 2001 From: adriano Date: Thu, 15 Dec 2022 14:44:02 -0300 Subject: [PATCH 12/12] =?UTF-8?q?Mudan=C3=A7a=20do=20console.log?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/services/WbotServices/StartWhatsAppSession.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/services/WbotServices/StartWhatsAppSession.ts b/backend/src/services/WbotServices/StartWhatsAppSession.ts index 2ecfbc6..05cd425 100644 --- a/backend/src/services/WbotServices/StartWhatsAppSession.ts +++ b/backend/src/services/WbotServices/StartWhatsAppSession.ts @@ -29,7 +29,7 @@ export const StartWhatsAppSession = async (whatsapp: Whatsapp, backupSession: bo if (Object.keys(lstRestore.filter((e: any) => +e.id == +whatsapp.id)).length) { - console.log('kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk: ', whatsapp.id) + console.log('Restore executed by human whatasappId: ', whatsapp.id) } else {