From 79b1c6bb1c5028a24ed4903580f0627c66edef8e Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 31 Jan 2025 17:38:42 -0300 Subject: [PATCH 1/9] feat: Add configurable file/cache storage for authentication state - Update Baileys package to version 6.7.10 - Implement conditional storage mechanism for authentication state - Add support for file-based or Redis cache storage based on environment configuration - Re-enable previously commented out file handling utility functions --- package-lock.json | 4 +- src/utils/use-multi-file-auth-state-prisma.ts | 60 +++++++++++-------- 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2396888d..6169f7ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4752,8 +4752,8 @@ "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==" }, "node_modules/baileys": { - "version": "6.7.9", - "resolved": "git+ssh://git@github.com/EvolutionAPI/Baileys.git#2140e16a9214067bf4cd408e88c231c24636a9e9", + "version": "6.7.10", + "resolved": "git+ssh://git@github.com/EvolutionAPI/Baileys.git#3d42781a00eb6d1b0f31f825a65b5e75708b9a89", "dependencies": { "@adiwajshing/keyed-db": "^0.2.4", "@hapi/boom": "^9.1.3", diff --git a/src/utils/use-multi-file-auth-state-prisma.ts b/src/utils/use-multi-file-auth-state-prisma.ts index 02f96f15..e16dc8b0 100644 --- a/src/utils/use-multi-file-auth-state-prisma.ts +++ b/src/utils/use-multi-file-auth-state-prisma.ts @@ -5,14 +5,14 @@ import { AuthenticationState, BufferJSON, initAuthCreds, WAProto as proto } from import fs from 'fs/promises'; import path from 'path'; -// const fixFileName = (file: string): string | undefined => { -// if (!file) { -// return undefined; -// } -// const replacedSlash = file.replace(/\//g, '__'); -// const replacedColon = replacedSlash.replace(/:/g, '-'); -// return replacedColon; -// }; +const fixFileName = (file: string): string | undefined => { + if (!file) { + return undefined; + } + const replacedSlash = file.replace(/\//g, '__'); + const replacedColon = replacedSlash.replace(/:/g, '-'); + return replacedColon; +}; export async function keyExists(sessionId: string): Promise { try { @@ -63,14 +63,14 @@ async function deleteAuthKey(sessionId: string): Promise { } } -// async function fileExists(file: string): Promise { -// try { -// const stat = await fs.stat(file); -// if (stat.isFile()) return true; -// } catch (error) { -// return; -// } -// } +async function fileExists(file: string): Promise { + try { + const stat = await fs.stat(file); + if (stat.isFile()) return true; + } catch (error) { + return; + } +} export default async function useMultiFileAuthStatePrisma( sessionId: string, @@ -80,16 +80,19 @@ export default async function useMultiFileAuthStatePrisma( saveCreds: () => Promise; }> { const localFolder = path.join(INSTANCE_DIR, sessionId); - // const localFile = (key: string) => path.join(localFolder, fixFileName(key) + '.json'); + const localFile = (key: string) => path.join(localFolder, fixFileName(key) + '.json'); await fs.mkdir(localFolder, { recursive: true }); async function writeData(data: any, key: string): Promise { const dataString = JSON.stringify(data, BufferJSON.replacer); if (key != 'creds') { - return await cache.hSet(sessionId, key, data); - // await fs.writeFile(localFile(key), dataString); - // return; + if (process.env.CACHE_REDIS_ENABLED === 'true') { + return await cache.hSet(sessionId, key, data); + } else { + await fs.writeFile(localFile(key), dataString); + return; + } } await saveKey(sessionId, dataString); return; @@ -100,9 +103,13 @@ export default async function useMultiFileAuthStatePrisma( let rawData; if (key != 'creds') { - return await cache.hGet(sessionId, key); - // if (!(await fileExists(localFile(key)))) return null; - // rawData = await fs.readFile(localFile(key), { encoding: 'utf-8' }); + if (process.env.CACHE_REDIS_ENABLED === 'true') { + return await cache.hGet(sessionId, key); + } else { + if (!(await fileExists(localFile(key)))) return null; + rawData = await fs.readFile(localFile(key), { encoding: 'utf-8' }); + return JSON.parse(rawData, BufferJSON.reviver); + } } else { rawData = await getAuthKey(sessionId); } @@ -117,8 +124,11 @@ export default async function useMultiFileAuthStatePrisma( async function removeData(key: string): Promise { try { if (key != 'creds') { - return await cache.hDelete(sessionId, key); - // await fs.unlink(localFile(key)); + if (process.env.CACHE_REDIS_ENABLED === 'true') { + return await cache.hDelete(sessionId, key); + } else { + await fs.unlink(localFile(key)); + } } else { await deleteAuthKey(sessionId); } From f8f1cbf4a2e1f5e4b410213279e0e6bb7ba0bda0 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 31 Jan 2025 17:44:44 -0300 Subject: [PATCH 2/9] fix: Disable group metadata caching in Baileys service - Remove group metadata caching mechanisms - Modify group-related cache update methods - Simplify group metadata retrieval process --- CHANGELOG.md | 7 +++++++ .../whatsapp/whatsapp.baileys.service.ts | 21 ++++++++++--------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 397ce2e6..53119159 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# 2.2.3 (develop) + +### Fixed + +* Fix cache in local file system +* Update Baileys Version + # 2.2.2 (2025-01-31 06:55) ### Features diff --git a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts index 2de39434..fd8e8e39 100644 --- a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts +++ b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts @@ -668,7 +668,7 @@ export class BaileysStartupService extends ChannelStartupService { shouldSyncHistoryMessage: (msg: proto.Message.IHistorySyncNotification) => { return this.historySyncNotification(msg); }, - cachedGroupMetadata: this.getGroupMetadataCache, + // cachedGroupMetadata: this.getGroupMetadataCache, userDevicesCache: this.userDevicesCache, transactionOpts: { maxCommitRetries: 10, delayBetweenTriesMs: 3000 }, patchMessageBeforeSending(message) { @@ -1562,11 +1562,11 @@ export class BaileysStartupService extends ChannelStartupService { 'groups.update': (groupMetadataUpdate: Partial[]) => { this.sendDataWebhook(Events.GROUPS_UPDATE, groupMetadataUpdate); - groupMetadataUpdate.forEach((group) => { - if (isJidGroup(group.id)) { - this.updateGroupMetadataCache(group.id); - } - }); + // groupMetadataUpdate.forEach((group) => { + // if (isJidGroup(group.id)) { + // this.updateGroupMetadataCache(group.id); + // } + // }); }, 'group-participants.update': (participantsUpdate: { @@ -1576,7 +1576,7 @@ export class BaileysStartupService extends ChannelStartupService { }) => { this.sendDataWebhook(Events.GROUP_PARTICIPANTS_UPDATE, participantsUpdate); - this.updateGroupMetadataCache(participantsUpdate.id); + // this.updateGroupMetadataCache(participantsUpdate.id); }, }; @@ -2160,9 +2160,10 @@ export class BaileysStartupService extends ChannelStartupService { if (isJidGroup(sender)) { let group; try { - const cache = this.configService.get('CACHE'); - if (!cache.REDIS.ENABLED && !cache.LOCAL.ENABLED) group = await this.findGroup({ groupJid: sender }, 'inner'); - else group = await this.getGroupMetadataCache(sender); + // const cache = this.configService.get('CACHE'); + // if (!cache.REDIS.ENABLED && !cache.LOCAL.ENABLED) group = await this.findGroup({ groupJid: sender }, 'inner'); + // else group = await this.getGroupMetadataCache(sender); + group = await this.findGroup({ groupJid: sender }, 'inner'); } catch (error) { throw new NotFoundException('Group not found'); } From 7ea46a05cac30104e80780c02772feb01156bad0 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 31 Jan 2025 17:45:09 -0300 Subject: [PATCH 3/9] version: 2.2.3 --- Dockerfile | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 370cc7f7..ca61b39a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ FROM node:20-alpine AS builder RUN apk update && \ apk add git ffmpeg wget curl bash openssl -LABEL version="2.2.2" description="Api to control whatsapp features through http requests." +LABEL version="2.2.3" description="Api to control whatsapp features through http requests." LABEL maintainer="Davidson Gomes" git="https://github.com/DavidsonGomes" LABEL contact="contato@atendai.com" diff --git a/package.json b/package.json index d2fcf50a..7e948028 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "2.2.2", + "version": "2.2.3", "description": "Rest api for communication with WhatsApp", "main": "./dist/main.js", "type": "commonjs", From c1494ca03515cbfeea52ca89752930865984b9d5 Mon Sep 17 00:00:00 2001 From: Aditya Nandwana Date: Sat, 1 Feb 2025 16:04:35 +0530 Subject: [PATCH 4/9] Refactor logical message deletion in BaileysStartupService --- .../channel/whatsapp/whatsapp.baileys.service.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts index 2de39434..a5602ab6 100644 --- a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts +++ b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts @@ -3551,25 +3551,31 @@ export class BaileysStartupService extends ChannelStartupService { const messageId = response.message?.protocolMessage?.key?.id; if (messageId) { const isLogicalDeleted = configService.get('DATABASE').DELETE_DATA.LOGICAL_MESSAGE_DELETE; - let message = await this.prismaRepository.message.findUnique({ - where: { id: messageId }, + let message = await this.prismaRepository.message.findFirst({ + where: { + key: { + path: ['id'], + equals: messageId, + }, + }, }); if (isLogicalDeleted) { if (!message) return response; const existingKey = typeof message?.key === 'object' && message.key !== null ? message.key : {}; message = await this.prismaRepository.message.update({ - where: { id: messageId }, + where: { id: message.id }, data: { key: { ...existingKey, deleted: true, }, + status: 'DELETED', }, }); } else { await this.prismaRepository.message.deleteMany({ where: { - id: messageId, + id: message.id, }, }); } @@ -3578,7 +3584,7 @@ export class BaileysStartupService extends ChannelStartupService { instanceId: message.instanceId, key: message.key, messageType: message.messageType, - status: message.status, + status: 'DELETED', source: message.source, messageTimestamp: message.messageTimestamp, pushName: message.pushName, From fc84e0f32723c17103c30de7a59c2e64b0a42907 Mon Sep 17 00:00:00 2001 From: Toni Moreira Date: Sat, 1 Feb 2025 11:47:50 -0300 Subject: [PATCH 5/9] fix: dify truncated messages --- .../chatbot/dify/services/dify.service.ts | 66 +++++++------------ 1 file changed, 23 insertions(+), 43 deletions(-) diff --git a/src/api/integrations/chatbot/dify/services/dify.service.ts b/src/api/integrations/chatbot/dify/services/dify.service.ts index c60782d7..348ee70c 100644 --- a/src/api/integrations/chatbot/dify/services/dify.service.ts +++ b/src/api/integrations/chatbot/dify/services/dify.service.ts @@ -224,63 +224,43 @@ export class DifyService { headers: { Authorization: `Bearer ${dify.apiKey}`, }, - responseType: 'stream', }); let conversationId; let answer = ''; - const stream = response.data; - const reader = new Readable().wrap(stream); + const data = response.data.replaceAll('data: ', ''); - reader.on('data', (chunk) => { - const data = chunk.toString().replace(/data:\s*/g, ''); + const events = data.split('\n').filter((line) => line.trim() !== ''); - if (data.trim() === '' || !data.startsWith('{')) { - return; - } + for (const eventString of events) { + if (eventString.trim().startsWith('{')) { + const event = JSON.parse(eventString); - try { - const events = data.split('\n').filter((line) => line.trim() !== ''); - - for (const eventString of events) { - if (eventString.trim().startsWith('{')) { - const event = JSON.parse(eventString); - - if (event?.event === 'agent_message') { - console.log('event:', event); - conversationId = conversationId ?? event?.conversation_id; - answer += event?.answer; - } - } + if (event?.event === 'agent_message') { + console.log('event:', event); + conversationId = conversationId ?? event?.conversation_id; + answer += event?.answer; } - } catch (error) { - console.error('Error parsing stream data:', error); } - }); + } - reader.on('end', async () => { - if (instance.integration === Integration.WHATSAPP_BAILEYS) - await instance.client.sendPresenceUpdate('paused', remoteJid); + if (instance.integration === Integration.WHATSAPP_BAILEYS) + await instance.client.sendPresenceUpdate('paused', remoteJid); - const message = answer; + const message = answer; - await this.sendMessageWhatsApp(instance, remoteJid, message, settings); + await this.sendMessageWhatsApp(instance, remoteJid, message, settings); - await this.prismaRepository.integrationSession.update({ - where: { - id: session.id, - }, - data: { - status: 'opened', - awaitUser: true, - sessionId: conversationId, - }, - }); - }); - - reader.on('error', (error) => { - console.error('Error reading stream:', error); + await this.prismaRepository.integrationSession.update({ + where: { + id: session.id, + }, + data: { + status: 'opened', + awaitUser: true, + sessionId: conversationId, + }, }); return; From b09638600e871c018c94d66951e6f7ac0d90ee3f Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sat, 1 Feb 2025 15:39:14 -0300 Subject: [PATCH 6/9] chore: Upgrade Baileys to version 6.7.12 - Update Baileys package to latest version - Bump package version to 2.2.3 --- package-lock.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6169f7ee..29c61422 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "evolution-api", - "version": "2.2.2", + "version": "2.2.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "evolution-api", - "version": "2.2.2", + "version": "2.2.3", "license": "Apache-2.0", "dependencies": { "@adiwajshing/keyed-db": "^0.2.4", @@ -4752,8 +4752,8 @@ "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==" }, "node_modules/baileys": { - "version": "6.7.10", - "resolved": "git+ssh://git@github.com/EvolutionAPI/Baileys.git#3d42781a00eb6d1b0f31f825a65b5e75708b9a89", + "version": "6.7.12", + "resolved": "git+ssh://git@github.com/EvolutionAPI/Baileys.git#ce92d5d32f1174f050d2bba8fd637dc6e45faafa", "dependencies": { "@adiwajshing/keyed-db": "^0.2.4", "@hapi/boom": "^9.1.3", From 4a5d7a91e22147cd56194ff7129e3fb3a3bf26ec Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 2 Feb 2025 11:39:45 -0300 Subject: [PATCH 7/9] chore: Update Baileys package to latest commit hash --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 29c61422..83bd4d16 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4753,7 +4753,7 @@ }, "node_modules/baileys": { "version": "6.7.12", - "resolved": "git+ssh://git@github.com/EvolutionAPI/Baileys.git#ce92d5d32f1174f050d2bba8fd637dc6e45faafa", + "resolved": "git+ssh://git@github.com/EvolutionAPI/Baileys.git#2c69f65d4b6c4e779d6e3d2c0c32689a5425df95", "dependencies": { "@adiwajshing/keyed-db": "^0.2.4", "@hapi/boom": "^9.1.3", From 3c2ea5c67c3f07a24812e64f2da0c942fb91b117 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 2 Feb 2025 16:42:17 -0300 Subject: [PATCH 8/9] feat: Re-enable group metadata caching in Baileys service - Restore group metadata caching mechanisms - Uncomment cache-related methods for group updates and participants - Implement conditional group metadata retrieval based on cache configuration --- .../whatsapp/whatsapp.baileys.service.ts | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts index cd6fac51..10feb7ce 100644 --- a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts +++ b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts @@ -668,7 +668,7 @@ export class BaileysStartupService extends ChannelStartupService { shouldSyncHistoryMessage: (msg: proto.Message.IHistorySyncNotification) => { return this.historySyncNotification(msg); }, - // cachedGroupMetadata: this.getGroupMetadataCache, + cachedGroupMetadata: this.getGroupMetadataCache, userDevicesCache: this.userDevicesCache, transactionOpts: { maxCommitRetries: 10, delayBetweenTriesMs: 3000 }, patchMessageBeforeSending(message) { @@ -1562,11 +1562,11 @@ export class BaileysStartupService extends ChannelStartupService { 'groups.update': (groupMetadataUpdate: Partial[]) => { this.sendDataWebhook(Events.GROUPS_UPDATE, groupMetadataUpdate); - // groupMetadataUpdate.forEach((group) => { - // if (isJidGroup(group.id)) { - // this.updateGroupMetadataCache(group.id); - // } - // }); + groupMetadataUpdate.forEach((group) => { + if (isJidGroup(group.id)) { + this.updateGroupMetadataCache(group.id); + } + }); }, 'group-participants.update': (participantsUpdate: { @@ -1576,7 +1576,7 @@ export class BaileysStartupService extends ChannelStartupService { }) => { this.sendDataWebhook(Events.GROUP_PARTICIPANTS_UPDATE, participantsUpdate); - // this.updateGroupMetadataCache(participantsUpdate.id); + this.updateGroupMetadataCache(participantsUpdate.id); }, }; @@ -2160,10 +2160,10 @@ export class BaileysStartupService extends ChannelStartupService { if (isJidGroup(sender)) { let group; try { - // const cache = this.configService.get('CACHE'); - // if (!cache.REDIS.ENABLED && !cache.LOCAL.ENABLED) group = await this.findGroup({ groupJid: sender }, 'inner'); - // else group = await this.getGroupMetadataCache(sender); - group = await this.findGroup({ groupJid: sender }, 'inner'); + const cache = this.configService.get('CACHE'); + if (!cache.REDIS.ENABLED && !cache.LOCAL.ENABLED) group = await this.findGroup({ groupJid: sender }, 'inner'); + else group = await this.getGroupMetadataCache(sender); + // group = await this.findGroup({ groupJid: sender }, 'inner'); } catch (error) { throw new NotFoundException('Group not found'); } From da74611769cb4a036324e56b625e4a5ce0ebccb0 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 3 Feb 2025 11:52:37 -0300 Subject: [PATCH 9/9] version: 2.2.3 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53119159..2d316041 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 2.2.3 (develop) +# 2.2.3 (2025-02-03 11:52) ### Fixed