From ce6438b9a84765e29782c94f0a96e0ec0dbc8067 Mon Sep 17 00:00:00 2001 From: Judson Cairo Date: Wed, 28 Aug 2024 11:19:47 -0300 Subject: [PATCH 1/6] Save is on whatsapp on the database --- .env.example | 1 + .../migration.sql | 14 +++ .../migration.sql | 8 ++ prisma/postgresql-schema.prisma | 10 ++ .../whatsapp/whatsapp.baileys.service.ts | 55 ++++++++++- src/config/env.config.ts | 2 + src/utils/onWhatsappCache.ts | 96 +++++++++++++++++++ 7 files changed, 181 insertions(+), 5 deletions(-) create mode 100644 prisma/postgresql-migrations/20240828140837_add_is_on_whatsapp_table/migration.sql create mode 100644 prisma/postgresql-migrations/20240828141556_remove_name_column_from_on_whatsapp_table/migration.sql create mode 100644 src/utils/onWhatsappCache.ts diff --git a/.env.example b/.env.example index c893e888..620af393 100644 --- a/.env.example +++ b/.env.example @@ -36,6 +36,7 @@ DATABASE_SAVE_DATA_CONTACTS=true DATABASE_SAVE_DATA_CHATS=true DATABASE_SAVE_DATA_LABELS=true DATABASE_SAVE_DATA_HISTORIC=true +DATABASE_SAVE_IS_ON_WHATSAPP=true # RabbitMQ - Environment variables RABBITMQ_ENABLED=false diff --git a/prisma/postgresql-migrations/20240828140837_add_is_on_whatsapp_table/migration.sql b/prisma/postgresql-migrations/20240828140837_add_is_on_whatsapp_table/migration.sql new file mode 100644 index 00000000..bb577211 --- /dev/null +++ b/prisma/postgresql-migrations/20240828140837_add_is_on_whatsapp_table/migration.sql @@ -0,0 +1,14 @@ +-- CreateTable +CREATE TABLE "is_on_whatsapp" ( + "id" TEXT NOT NULL, + "remote_jid" VARCHAR(100) NOT NULL, + "name" TEXT, + "jid_options" TEXT NOT NULL, + "created_at" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP NOT NULL, + + CONSTRAINT "is_on_whatsapp_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "is_on_whatsapp_remote_jid_key" ON "is_on_whatsapp"("remote_jid"); diff --git a/prisma/postgresql-migrations/20240828141556_remove_name_column_from_on_whatsapp_table/migration.sql b/prisma/postgresql-migrations/20240828141556_remove_name_column_from_on_whatsapp_table/migration.sql new file mode 100644 index 00000000..de907df7 --- /dev/null +++ b/prisma/postgresql-migrations/20240828141556_remove_name_column_from_on_whatsapp_table/migration.sql @@ -0,0 +1,8 @@ +/* + Warnings: + + - You are about to drop the column `name` on the `is_on_whatsapp` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE "is_on_whatsapp" DROP COLUMN "name"; diff --git a/prisma/postgresql-schema.prisma b/prisma/postgresql-schema.prisma index 9df70018..86cbb79f 100644 --- a/prisma/postgresql-schema.prisma +++ b/prisma/postgresql-schema.prisma @@ -574,3 +574,13 @@ model FlowiseSetting { Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) instanceId String @unique } + +model IsOnWhatsapp { + id String @id @default(cuid()) + remoteJid String @unique @map("remote_jid") @db.VarChar(100) + jidOptions String @map("jid_options") + createdAt DateTime @default(now()) @map("created_at") @db.Timestamp + updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamp + + @@map("is_on_whatsapp") +} diff --git a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts index fd1cd491..f6f852e3 100644 --- a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts +++ b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts @@ -71,6 +71,7 @@ import ffmpegPath from '@ffmpeg-installer/ffmpeg'; import { Boom } from '@hapi/boom'; import { Instance } from '@prisma/client'; import { makeProxyAgent } from '@utils/makeProxyAgent'; +import { getOnWhatsappCache, saveOnWhatsappCache } from '@utils/onWhatsappCache'; import useMultiFileAuthStatePrisma from '@utils/use-multi-file-auth-state-prisma'; import { AuthStateProvider } from '@utils/use-multi-file-auth-state-provider-files'; import { useMultiFileAuthStateRedisDb } from '@utils/use-multi-file-auth-state-redis-db'; @@ -682,14 +683,19 @@ export class BaileysStartupService extends ChannelStartupService { instanceId: this.instanceId, })); - if (contactsRaw.length > 0) this.sendDataWebhook(Events.CONTACTS_UPSERT, contactsRaw); - if (contactsRaw.length > 0) { + this.sendDataWebhook(Events.CONTACTS_UPSERT, contactsRaw); + if (this.configService.get('DATABASE').SAVE_DATA.CONTACTS) await this.prismaRepository.contact.createMany({ data: contactsRaw, skipDuplicates: true, }); + + const usersContacts = contactsRaw.filter((c) => c.remoteJid.includes('@s.whatsapp')); + if (usersContacts) { + await saveOnWhatsappCache(usersContacts.map((c) => ({ remoteJid: c.remoteJid }))); + } } if ( @@ -717,9 +723,13 @@ export class BaileysStartupService extends ChannelStartupService { })), ); - if (updatedContacts.length > 0) this.sendDataWebhook(Events.CONTACTS_UPDATE, updatedContacts); - if (updatedContacts.length > 0) { + const usersContacts = updatedContacts.filter((c) => c.remoteJid.includes('@s.whatsapp')); + if (usersContacts) { + await saveOnWhatsappCache(usersContacts.map((c) => ({ remoteJid: c.remoteJid }))); + } + + this.sendDataWebhook(Events.CONTACTS_UPDATE, updatedContacts); await Promise.all( updatedContacts.map(async (contact) => { const update = this.prismaRepository.contact.updateMany({ @@ -778,6 +788,11 @@ export class BaileysStartupService extends ChannelStartupService { }), ); await this.prismaRepository.$transaction(updateTransactions); + + const usersContacts = contactsRaw.filter((c) => c.remoteJid.includes('@s.whatsapp')); + if (usersContacts) { + await saveOnWhatsappCache(usersContacts.map((c) => ({ remoteJid: c.remoteJid }))); + } }, }; @@ -1225,6 +1240,10 @@ export class BaileysStartupService extends ChannelStartupService { update: contactRaw, create: contactRaw, }); + + if (contactRaw.remoteJid.includes('@s.whatsapp')) { + await saveOnWhatsappCache([{ remoteJid: contactRaw.remoteJid }]); + } } } catch (error) { this.logger.error('line 1318'); @@ -2686,11 +2705,27 @@ export class BaileysStartupService extends ChannelStartupService { }); const numbersToVerify = jids.users.map(({ jid }) => jid.replace('+', '')); - const verify = await this.client.onWhatsApp(...numbersToVerify); + + const cachedNumbers = await getOnWhatsappCache(numbersToVerify); + const filteredNumbers = numbersToVerify.filter( + (jid) => !cachedNumbers.some((cached) => cached.jidOptions.includes(jid)), + ); + + const verify = await this.client.onWhatsApp(...filteredNumbers); const users: OnWhatsAppDto[] = await Promise.all( jids.users.map(async (user) => { let numberVerified: (typeof verify)[0] | null = null; + const cached = cachedNumbers.find((cached) => cached.jidOptions.includes(user.jid.replace('+', ''))); + if (cached) { + return { + exists: true, + jid: cached.remoteJid, + name: contacts.find((c) => c.remoteJid === cached.remoteJid)?.pushName, + number: cached.number, + }; + } + // Brazilian numbers if (user.number.startsWith('55')) { const numberWithDigit = @@ -2733,6 +2768,7 @@ export class BaileysStartupService extends ChannelStartupService { } const numberJid = numberVerified?.jid || user.jid; + return { exists: !!numberVerified?.exists, jid: numberJid, @@ -2742,6 +2778,8 @@ export class BaileysStartupService extends ChannelStartupService { }), ); + await saveOnWhatsappCache(users.filter((user) => user.exists).map((user) => ({ remoteJid: user.jid }))); + onWhatsapp.push(...users); return onWhatsapp; @@ -3525,8 +3563,15 @@ export class BaileysStartupService extends ChannelStartupService { imgUrl: participant.imgUrl ?? contact?.profilePicUrl, }; }); + + const usersContacts = parsedParticipants.filter((c) => c.id.includes('@s.whatsapp')); + if (usersContacts) { + await saveOnWhatsappCache(usersContacts.map((c) => ({ remoteJid: c.id }))); + } + return { participants: parsedParticipants }; } catch (error) { + console.error(error); this.logger.error('line 3583'); throw new NotFoundException('No participants', error.toString()); } diff --git a/src/config/env.config.ts b/src/config/env.config.ts index c29c099f..998d298a 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -43,6 +43,7 @@ export type SaveData = { CONTACTS: boolean; CHATS: boolean; LABELS: boolean; + IS_ON_WHATSAPP: boolean; }; export type DBConnection = { @@ -295,6 +296,7 @@ export class ConfigService { CHATS: process.env?.DATABASE_SAVE_DATA_CHATS === 'true', HISTORIC: process.env?.DATABASE_SAVE_DATA_HISTORIC === 'true', LABELS: process.env?.DATABASE_SAVE_DATA_LABELS === 'true', + IS_ON_WHATSAPP: process.env?.DATABASE_SAVE_IS_ON_WHATSAPP === 'true', }, }, RABBITMQ: { diff --git a/src/utils/onWhatsappCache.ts b/src/utils/onWhatsappCache.ts new file mode 100644 index 00000000..285be212 --- /dev/null +++ b/src/utils/onWhatsappCache.ts @@ -0,0 +1,96 @@ +import { prismaRepository } from '@api/server.module'; +import { configService, Database } from '@config/env.config'; +import dayjs from 'dayjs'; + +const ON_WHATSAPP_CACHE_EXPIRATION = 7; // days + +function getAvailableNumbers(remoteJid: string) { + const numbersAvailable: string[] = []; + + if (remoteJid.startsWith('+')) { + remoteJid = remoteJid.slice(1); + } + + const [number, domain] = remoteJid.split('@'); + + // Brazilian numbers + if (remoteJid.startsWith('55')) { + const numberWithDigit = + number.slice(4, 5) === '9' && number.length === 13 ? number : `${number.slice(0, 4)}9${number.slice(4)}`; + const numberWithoutDigit = number.length === 12 ? number : number.slice(0, 4) + number.slice(5); + + numbersAvailable.push(numberWithDigit); + numbersAvailable.push(numberWithoutDigit); + } + + // Mexican/Argentina numbers + // Ref: https://faq.whatsapp.com/1294841057948784 + else if (number.startsWith('52') || number.startsWith('54')) { + let prefix = ''; + if (number.startsWith('52')) { + prefix = '1'; + } + if (number.startsWith('54')) { + prefix = '9'; + } + + const numberWithDigit = + number.slice(2, 3) === prefix && number.length === 13 + ? number + : `${number.slice(0, 2)}${prefix}${number.slice(2)}`; + const numberWithoutDigit = number.length === 12 ? number : number.slice(0, 2) + number.slice(3); + + numbersAvailable.push(numberWithDigit); + numbersAvailable.push(numberWithoutDigit); + } + + // Other countries + else { + numbersAvailable.push(remoteJid); + } + + return numbersAvailable.map((number) => `${number}@${domain}`); +} + +interface ISaveOnWhatsappCacheParams { + remoteJid: string; +} +export async function saveOnWhatsappCache(data: ISaveOnWhatsappCacheParams[]) { + if (configService.get('DATABASE').SAVE_DATA.IS_ON_WHATSAPP) { + const upsertsQuery = data.map((item) => { + const remoteJid = item.remoteJid.startsWith('+') ? item.remoteJid.slice(1) : item.remoteJid; + const numbersAvailable = getAvailableNumbers(remoteJid); + + return prismaRepository.isOnWhatsapp.upsert({ + create: { remoteJid: remoteJid, jidOptions: numbersAvailable.join(',') }, + update: { jidOptions: numbersAvailable.join(',') }, + where: { remoteJid: remoteJid }, + }); + }); + + await prismaRepository.$transaction(upsertsQuery); + } +} + +export async function getOnWhatsappCache(remoteJids: string[]) { + if (configService.get('DATABASE').SAVE_DATA.IS_ON_WHATSAPP) { + const remoteJidsWithoutPlus = remoteJids.map((remoteJid) => getAvailableNumbers(remoteJid)).flat(); + + const onWhatsappCache = await prismaRepository.isOnWhatsapp.findMany({ + where: { + OR: remoteJidsWithoutPlus.map((remoteJid) => ({ jidOptions: { contains: remoteJid } })), + updatedAt: { + gte: dayjs().subtract(ON_WHATSAPP_CACHE_EXPIRATION, 'days').toDate(), + }, + }, + }); + + return onWhatsappCache.map((item) => ({ + remoteJid: item.remoteJid, + number: item.remoteJid.split('@')[0], + jidOptions: item.jidOptions.split(','), + })); + } + + return []; +} From 7a76600cd63f07650df1ea37428067fe2d0b03b0 Mon Sep 17 00:00:00 2001 From: Judson Cairo Date: Wed, 28 Aug 2024 12:11:32 -0300 Subject: [PATCH 2/6] Added redis cache for on whatsapp & TTL on .env --- .env.example | 6 +++ src/api/services/cache.service.ts | 4 +- src/config/env.config.ts | 7 +++ src/utils/onWhatsappCache.ts | 76 ++++++++++++++++++++++++++----- 4 files changed, 80 insertions(+), 13 deletions(-) diff --git a/.env.example b/.env.example index 620af393..335acfef 100644 --- a/.env.example +++ b/.env.example @@ -37,6 +37,7 @@ DATABASE_SAVE_DATA_CHATS=true DATABASE_SAVE_DATA_LABELS=true DATABASE_SAVE_DATA_HISTORIC=true DATABASE_SAVE_IS_ON_WHATSAPP=true +DATABASE_SAVE_IS_ON_WHATSAPP_DAYS=7 # RabbitMQ - Environment variables RABBITMQ_ENABLED=false @@ -172,12 +173,17 @@ DIFY_ENABLED=false # Redis Cache enabled CACHE_REDIS_ENABLED=true CACHE_REDIS_URI=redis://localhost:6379/6 +CACHE_REDIS_TTL=604800 # Prefix serves to differentiate data from one installation to another that are using the same redis CACHE_REDIS_PREFIX_KEY=evolution # Enabling this variable will save the connection information in Redis and not in the database. CACHE_REDIS_SAVE_INSTANCES=false # Local Cache enabled CACHE_LOCAL_ENABLED=false +# Local Cache enabled +CACHE_SAVE_IS_ON_WHATSAPP=true +CACHE_REDIS_SAVE_IS_ON_WHATSAPP=false +CACHE_REDIS_SAVE_IS_ON_WHATSAPP_DAYS=7 # Amazon S3 - Environment variables S3_ENABLED=false diff --git a/src/api/services/cache.service.ts b/src/api/services/cache.service.ts index 1004bb9c..2e8cd275 100644 --- a/src/api/services/cache.service.ts +++ b/src/api/services/cache.service.ts @@ -35,11 +35,11 @@ export class CacheService { } } - async set(key: string, value: any) { + async set(key: string, value: any, ttl?: number) { if (!this.cache) { return; } - this.cache.set(key, value); + this.cache.set(key, value, ttl); } public async hSet(key: string, field: string, value: any) { diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 998d298a..0330e225 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -44,6 +44,7 @@ export type SaveData = { CHATS: boolean; LABELS: boolean; IS_ON_WHATSAPP: boolean; + IS_ON_WHATSAPP_DAYS: number; }; export type DBConnection = { @@ -168,6 +169,8 @@ export type CacheConfRedis = { PREFIX_KEY: string; TTL: number; SAVE_INSTANCES: boolean; + SAVE_IS_ON_WHATSAPP: boolean; + SAVE_IS_ON_WHATSAPP_TTL: number; }; export type CacheConfLocal = { ENABLED: boolean; @@ -297,6 +300,7 @@ export class ConfigService { HISTORIC: process.env?.DATABASE_SAVE_DATA_HISTORIC === 'true', LABELS: process.env?.DATABASE_SAVE_DATA_LABELS === 'true', IS_ON_WHATSAPP: process.env?.DATABASE_SAVE_IS_ON_WHATSAPP === 'true', + IS_ON_WHATSAPP_DAYS: Number.parseInt(process.env?.DATABASE_SAVE_IS_ON_WHATSAPP_DAYS ?? '7'), }, }, RABBITMQ: { @@ -453,6 +457,9 @@ export class ConfigService { PREFIX_KEY: process.env?.CACHE_REDIS_PREFIX_KEY || 'evolution-cache', TTL: Number.parseInt(process.env?.CACHE_REDIS_TTL) || 604800, SAVE_INSTANCES: process.env?.CACHE_REDIS_SAVE_INSTANCES === 'true', + SAVE_IS_ON_WHATSAPP: process.env?.CACHE_REDIS_SAVE_IS_ON_WHATSAPP === 'true', + SAVE_IS_ON_WHATSAPP_TTL: + (Number.parseInt(process.env?.CACHE_REDIS_SAVE_IS_ON_WHATSAPP_TTL) || 7) * 24 * 60 * 60, }, LOCAL: { ENABLED: process.env?.CACHE_LOCAL_ENABLED === 'true', diff --git a/src/utils/onWhatsappCache.ts b/src/utils/onWhatsappCache.ts index 285be212..bc7a5c06 100644 --- a/src/utils/onWhatsappCache.ts +++ b/src/utils/onWhatsappCache.ts @@ -1,9 +1,7 @@ -import { prismaRepository } from '@api/server.module'; -import { configService, Database } from '@config/env.config'; +import { cache, prismaRepository } from '@api/server.module'; +import { CacheConf, configService, Database } from '@config/env.config'; import dayjs from 'dayjs'; -const ON_WHATSAPP_CACHE_EXPIRATION = 7; // days - function getAvailableNumbers(remoteJid: string) { const numbersAvailable: string[] = []; @@ -56,6 +54,23 @@ interface ISaveOnWhatsappCacheParams { remoteJid: string; } export async function saveOnWhatsappCache(data: ISaveOnWhatsappCacheParams[]) { + const cacheConfig = configService.get('CACHE'); + + if (cacheConfig.REDIS.ENABLED && cacheConfig.REDIS.SAVE_IS_ON_WHATSAPP) { + await Promise.all( + data.map(async (item) => { + const remoteJid = item.remoteJid.startsWith('+') ? item.remoteJid.slice(1) : item.remoteJid; + const numbersAvailable = getAvailableNumbers(remoteJid); + + await cache.set( + `isOnWhatsapp:${remoteJid}`, + JSON.stringify({ jidOptions: numbersAvailable }), + cacheConfig.REDIS.SAVE_IS_ON_WHATSAPP_TTL, + ); + }), + ); + } + if (configService.get('DATABASE').SAVE_DATA.IS_ON_WHATSAPP) { const upsertsQuery = data.map((item) => { const remoteJid = item.remoteJid.startsWith('+') ? item.remoteJid.slice(1) : item.remoteJid; @@ -73,6 +88,43 @@ export async function saveOnWhatsappCache(data: ISaveOnWhatsappCacheParams[]) { } export async function getOnWhatsappCache(remoteJids: string[]) { + const cacheConfig = configService.get('CACHE'); + + const results: { + remoteJid: string; + number: string; + jidOptions: string[]; + }[] = []; + + if (cacheConfig.REDIS.ENABLED && cacheConfig.REDIS.SAVE_IS_ON_WHATSAPP) { + const data = await Promise.all( + remoteJids.map(async (remoteJid) => { + const remoteJidWithoutPlus = remoteJid.startsWith('+') ? remoteJid.slice(1) : remoteJid; + const cacheData = await cache.get(`isOnWhatsapp:${remoteJidWithoutPlus}`); + + if (cacheData) { + return { + remoteJid: remoteJidWithoutPlus, + number: remoteJidWithoutPlus.split('@')[0], + jidOptions: JSON.parse(cacheData)?.jidOptions, + }; + } + + return null; + }), + ); + + data.forEach((item) => { + if (item) { + results.push({ + remoteJid: item.remoteJid, + number: item.number, + jidOptions: item.jidOptions, + }); + } + }); + } + if (configService.get('DATABASE').SAVE_DATA.IS_ON_WHATSAPP) { const remoteJidsWithoutPlus = remoteJids.map((remoteJid) => getAvailableNumbers(remoteJid)).flat(); @@ -80,17 +132,19 @@ export async function getOnWhatsappCache(remoteJids: string[]) { where: { OR: remoteJidsWithoutPlus.map((remoteJid) => ({ jidOptions: { contains: remoteJid } })), updatedAt: { - gte: dayjs().subtract(ON_WHATSAPP_CACHE_EXPIRATION, 'days').toDate(), + gte: dayjs().subtract(configService.get('DATABASE').SAVE_DATA.IS_ON_WHATSAPP_DAYS, 'days').toDate(), }, }, }); - return onWhatsappCache.map((item) => ({ - remoteJid: item.remoteJid, - number: item.remoteJid.split('@')[0], - jidOptions: item.jidOptions.split(','), - })); + onWhatsappCache.forEach((item) => + results.push({ + remoteJid: item.remoteJid, + number: item.remoteJid.split('@')[0], + jidOptions: item.jidOptions.split(','), + }), + ); } - return []; + return results; } From 7468ae9169228bf67a74d0ae0aa56d76af09ddaf Mon Sep 17 00:00:00 2001 From: Judson Cairo Date: Wed, 28 Aug 2024 13:30:11 -0300 Subject: [PATCH 3/6] Removed unused variable from .env --- .env.example | 1 - 1 file changed, 1 deletion(-) diff --git a/.env.example b/.env.example index 335acfef..db6ea8b3 100644 --- a/.env.example +++ b/.env.example @@ -181,7 +181,6 @@ CACHE_REDIS_SAVE_INSTANCES=false # Local Cache enabled CACHE_LOCAL_ENABLED=false # Local Cache enabled -CACHE_SAVE_IS_ON_WHATSAPP=true CACHE_REDIS_SAVE_IS_ON_WHATSAPP=false CACHE_REDIS_SAVE_IS_ON_WHATSAPP_DAYS=7 From 49806cf47e38a7c4dd49afe9e256d168d50917d9 Mon Sep 17 00:00:00 2001 From: Judson Cairo Date: Wed, 28 Aug 2024 13:33:33 -0300 Subject: [PATCH 4/6] Avoid duplicate search If already found on redis ignore database --- src/utils/onWhatsappCache.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/utils/onWhatsappCache.ts b/src/utils/onWhatsappCache.ts index bc7a5c06..c2a21ce6 100644 --- a/src/utils/onWhatsappCache.ts +++ b/src/utils/onWhatsappCache.ts @@ -126,7 +126,10 @@ export async function getOnWhatsappCache(remoteJids: string[]) { } if (configService.get('DATABASE').SAVE_DATA.IS_ON_WHATSAPP) { - const remoteJidsWithoutPlus = remoteJids.map((remoteJid) => getAvailableNumbers(remoteJid)).flat(); + const remoteJidsWithoutPlus = remoteJids + .filter((remoteJid) => !results.some((result) => result.remoteJid === remoteJid)) + .map((remoteJid) => getAvailableNumbers(remoteJid)) + .flat(); const onWhatsappCache = await prismaRepository.isOnWhatsapp.findMany({ where: { From 41342f39de004fc4d2440e224b8af6d8435c0a2c Mon Sep 17 00:00:00 2001 From: Judson Cairo Date: Wed, 28 Aug 2024 17:29:01 -0300 Subject: [PATCH 5/6] Removed redis cache from is on whatsapp --- .env.example | 3 -- src/config/env.config.ts | 5 --- src/utils/onWhatsappCache.ts | 71 +++++------------------------------- 3 files changed, 9 insertions(+), 70 deletions(-) diff --git a/.env.example b/.env.example index db6ea8b3..88d3d59d 100644 --- a/.env.example +++ b/.env.example @@ -180,9 +180,6 @@ CACHE_REDIS_PREFIX_KEY=evolution CACHE_REDIS_SAVE_INSTANCES=false # Local Cache enabled CACHE_LOCAL_ENABLED=false -# Local Cache enabled -CACHE_REDIS_SAVE_IS_ON_WHATSAPP=false -CACHE_REDIS_SAVE_IS_ON_WHATSAPP_DAYS=7 # Amazon S3 - Environment variables S3_ENABLED=false diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 0330e225..76aac9c8 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -169,8 +169,6 @@ export type CacheConfRedis = { PREFIX_KEY: string; TTL: number; SAVE_INSTANCES: boolean; - SAVE_IS_ON_WHATSAPP: boolean; - SAVE_IS_ON_WHATSAPP_TTL: number; }; export type CacheConfLocal = { ENABLED: boolean; @@ -457,9 +455,6 @@ export class ConfigService { PREFIX_KEY: process.env?.CACHE_REDIS_PREFIX_KEY || 'evolution-cache', TTL: Number.parseInt(process.env?.CACHE_REDIS_TTL) || 604800, SAVE_INSTANCES: process.env?.CACHE_REDIS_SAVE_INSTANCES === 'true', - SAVE_IS_ON_WHATSAPP: process.env?.CACHE_REDIS_SAVE_IS_ON_WHATSAPP === 'true', - SAVE_IS_ON_WHATSAPP_TTL: - (Number.parseInt(process.env?.CACHE_REDIS_SAVE_IS_ON_WHATSAPP_TTL) || 7) * 24 * 60 * 60, }, LOCAL: { ENABLED: process.env?.CACHE_LOCAL_ENABLED === 'true', diff --git a/src/utils/onWhatsappCache.ts b/src/utils/onWhatsappCache.ts index c2a21ce6..a77ac396 100644 --- a/src/utils/onWhatsappCache.ts +++ b/src/utils/onWhatsappCache.ts @@ -1,5 +1,5 @@ -import { cache, prismaRepository } from '@api/server.module'; -import { CacheConf, configService, Database } from '@config/env.config'; +import { prismaRepository } from '@api/server.module'; +import { configService, Database } from '@config/env.config'; import dayjs from 'dayjs'; function getAvailableNumbers(remoteJid: string) { @@ -54,23 +54,6 @@ interface ISaveOnWhatsappCacheParams { remoteJid: string; } export async function saveOnWhatsappCache(data: ISaveOnWhatsappCacheParams[]) { - const cacheConfig = configService.get('CACHE'); - - if (cacheConfig.REDIS.ENABLED && cacheConfig.REDIS.SAVE_IS_ON_WHATSAPP) { - await Promise.all( - data.map(async (item) => { - const remoteJid = item.remoteJid.startsWith('+') ? item.remoteJid.slice(1) : item.remoteJid; - const numbersAvailable = getAvailableNumbers(remoteJid); - - await cache.set( - `isOnWhatsapp:${remoteJid}`, - JSON.stringify({ jidOptions: numbersAvailable }), - cacheConfig.REDIS.SAVE_IS_ON_WHATSAPP_TTL, - ); - }), - ); - } - if (configService.get('DATABASE').SAVE_DATA.IS_ON_WHATSAPP) { const upsertsQuery = data.map((item) => { const remoteJid = item.remoteJid.startsWith('+') ? item.remoteJid.slice(1) : item.remoteJid; @@ -88,48 +71,14 @@ export async function saveOnWhatsappCache(data: ISaveOnWhatsappCacheParams[]) { } export async function getOnWhatsappCache(remoteJids: string[]) { - const cacheConfig = configService.get('CACHE'); - - const results: { + let results: { remoteJid: string; number: string; jidOptions: string[]; }[] = []; - if (cacheConfig.REDIS.ENABLED && cacheConfig.REDIS.SAVE_IS_ON_WHATSAPP) { - const data = await Promise.all( - remoteJids.map(async (remoteJid) => { - const remoteJidWithoutPlus = remoteJid.startsWith('+') ? remoteJid.slice(1) : remoteJid; - const cacheData = await cache.get(`isOnWhatsapp:${remoteJidWithoutPlus}`); - - if (cacheData) { - return { - remoteJid: remoteJidWithoutPlus, - number: remoteJidWithoutPlus.split('@')[0], - jidOptions: JSON.parse(cacheData)?.jidOptions, - }; - } - - return null; - }), - ); - - data.forEach((item) => { - if (item) { - results.push({ - remoteJid: item.remoteJid, - number: item.number, - jidOptions: item.jidOptions, - }); - } - }); - } - if (configService.get('DATABASE').SAVE_DATA.IS_ON_WHATSAPP) { - const remoteJidsWithoutPlus = remoteJids - .filter((remoteJid) => !results.some((result) => result.remoteJid === remoteJid)) - .map((remoteJid) => getAvailableNumbers(remoteJid)) - .flat(); + const remoteJidsWithoutPlus = remoteJids.map((remoteJid) => getAvailableNumbers(remoteJid)).flat(); const onWhatsappCache = await prismaRepository.isOnWhatsapp.findMany({ where: { @@ -140,13 +89,11 @@ export async function getOnWhatsappCache(remoteJids: string[]) { }, }); - onWhatsappCache.forEach((item) => - results.push({ - remoteJid: item.remoteJid, - number: item.remoteJid.split('@')[0], - jidOptions: item.jidOptions.split(','), - }), - ); + results = onWhatsappCache.map((item) => ({ + remoteJid: item.remoteJid, + number: item.remoteJid.split('@')[0], + jidOptions: item.jidOptions.split(','), + })); } return results; From 4cdf76f381b385d97c9eca001b217fc3642408d1 Mon Sep 17 00:00:00 2001 From: Judson Cairo Date: Fri, 30 Aug 2024 16:37:20 -0300 Subject: [PATCH 6/6] Refactor database table name for IsOnWhatsapp --- .../migration.sql | 22 +++++++++++++++++++ prisma/postgresql-schema.prisma | 10 ++++----- 2 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 prisma/postgresql-migrations/20240830193533_changed_table_case/migration.sql diff --git a/prisma/postgresql-migrations/20240830193533_changed_table_case/migration.sql b/prisma/postgresql-migrations/20240830193533_changed_table_case/migration.sql new file mode 100644 index 00000000..209dd18c --- /dev/null +++ b/prisma/postgresql-migrations/20240830193533_changed_table_case/migration.sql @@ -0,0 +1,22 @@ +/* + Warnings: + + - You are about to drop the `is_on_whatsapp` table. If the table is not empty, all the data it contains will be lost. + +*/ +-- DropTable +DROP TABLE "is_on_whatsapp"; + +-- CreateTable +CREATE TABLE "IsOnWhatsapp" ( + "id" TEXT NOT NULL, + "remoteJid" VARCHAR(100) NOT NULL, + "jidOptions" TEXT NOT NULL, + "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP NOT NULL, + + CONSTRAINT "IsOnWhatsapp_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "IsOnWhatsapp_remoteJid_key" ON "IsOnWhatsapp"("remoteJid"); diff --git a/prisma/postgresql-schema.prisma b/prisma/postgresql-schema.prisma index 86cbb79f..931d67bd 100644 --- a/prisma/postgresql-schema.prisma +++ b/prisma/postgresql-schema.prisma @@ -577,10 +577,8 @@ model FlowiseSetting { model IsOnWhatsapp { id String @id @default(cuid()) - remoteJid String @unique @map("remote_jid") @db.VarChar(100) - jidOptions String @map("jid_options") - createdAt DateTime @default(now()) @map("created_at") @db.Timestamp - updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamp - - @@map("is_on_whatsapp") + remoteJid String @unique @db.VarChar(100) + jidOptions String + createdAt DateTime @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp }