From c9757cbb4b596e7a6154250fea55bb1b97d4372e Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 12 Dec 2023 17:45:12 -0300 Subject: [PATCH 01/47] fix: fixed lids messages --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 19891113..f2730fe1 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "@figuro/chatwoot-sdk": "^1.1.16", "@hapi/boom": "^10.0.1", "@sentry/node": "^7.59.2", - "@whiskeysockets/baileys": "^6.5.0", + "@whiskeysockets/baileys": "github:WhiskeySockets/Baileys#fix-lids", "amqplib": "^0.10.3", "aws-sdk": "^2.1499.0", "axios": "^1.3.5", From 87027ea2d001de8043e040ff165a8a1546fa0cbd Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 12 Dec 2023 18:16:02 -0300 Subject: [PATCH 02/47] update: manager --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b67354e..7cc6ee82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ # 1.6.0 (2023-12-12 17:24) ### Feature + * Added AWS SQS Integration * Added support for new typebot API * Added endpoint sendPresence @@ -24,7 +25,6 @@ * Fix workaround to manage param data as an array in mongodb * Removed await from webhook when sending a message * Update typebot.service.ts - element.underline change ~ for * -* Adjusts in proxy * Removed api restart on receiving an error * Fixes in mongodb and chatwoot * Adjusted return from queries in mongodb diff --git a/package.json b/package.json index f2730fe1..1987ae35 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "cross-env": "^7.0.3", "dayjs": "^1.11.7", "eventemitter2": "^6.4.9", - "evolution-manager": "^0.4.4", + "evolution-manager": "^0.4.5", "exiftool-vendored": "^22.0.0", "express": "^4.18.2", "express-async-errors": "^3.1.1", From a44646161b04d7c0c378311b43d6e51ac8b4eff1 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 14 Dec 2023 08:35:45 -0300 Subject: [PATCH 03/47] fix: variables in typebot --- CHANGELOG.md | 2 + Dockerfile | 2 +- package.json | 4 +- src/config/env.config.ts | 4 +- src/docs/swagger.yaml | 2 +- src/whatsapp/routers/index.router.ts | 3 +- src/whatsapp/services/typebot.service.ts | 210 ++++++++++++++-------- src/whatsapp/services/whatsapp.service.ts | 2 +- src/whatsapp/whatsapp.module.ts | 2 +- 9 files changed, 143 insertions(+), 88 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cc6ee82..c4263824 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ ### Fixed * Fixed Lid Messages +* Fixed sending variables to typebot +* Fixed sending variables from typebot # 1.6.0 (2023-12-12 17:24) diff --git a/Dockerfile b/Dockerfile index 10be07c4..82201346 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM node:20.7.0-alpine -LABEL version="1.6.0" description="Api to control whatsapp features through http requests." +LABEL version="1.6.1" description="Api to control whatsapp features through http requests." LABEL maintainer="Davidson Gomes" git="https://github.com/DavidsonGomes" LABEL contact="contato@agenciadgcode.com" diff --git a/package.json b/package.json index 1987ae35..54f8e4a9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.6.0", + "version": "1.6.1", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": { @@ -56,7 +56,7 @@ "cross-env": "^7.0.3", "dayjs": "^1.11.7", "eventemitter2": "^6.4.9", - "evolution-manager": "^0.4.5", + "evolution-manager": "^0.4.6", "exiftool-vendored": "^22.0.0", "express": "^4.18.2", "express-async-errors": "^3.1.1", diff --git a/src/config/env.config.ts b/src/config/env.config.ts index da491505..69e79f54 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -169,8 +169,8 @@ export class ConfigService { this.env = !(process.env?.DOCKER_ENV === 'true') ? this.envYaml() : this.envProcess(); this.env.PRODUCTION = process.env?.NODE_ENV === 'PROD'; if (process.env?.DOCKER_ENV === 'true') { - this.env.SERVER.TYPE = 'http'; - this.env.SERVER.PORT = 8080; + this.env.SERVER.TYPE = process.env.SERVER_TYPE as 'http' | 'http'; + this.env.SERVER.PORT = Number.parseInt(process.env.SERVER_PORT) || 8080; } } diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml index 589ba8dc..603aa0e0 100644 --- a/src/docs/swagger.yaml +++ b/src/docs/swagger.yaml @@ -25,7 +25,7 @@ info: [![Run in Postman](https://run.pstmn.io/button.svg)](https://god.gw.postman.com/run-collection/26869335-5546d063-156b-4529-915f-909dd628c090?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D26869335-5546d063-156b-4529-915f-909dd628c090%26entityType%3Dcollection%26workspaceId%3D339a4ee7-378b-45c9-b5b8-fd2c0a9c2442) - version: 1.5.5 + version: 1.6.1 contact: name: DavidsonGomes email: contato@agenciadgcode.com diff --git a/src/whatsapp/routers/index.router.ts b/src/whatsapp/routers/index.router.ts index 3dd4492b..781b528c 100644 --- a/src/whatsapp/routers/index.router.ts +++ b/src/whatsapp/routers/index.router.ts @@ -41,7 +41,8 @@ router status: HttpStatus.OK, message: 'Welcome to the Evolution API, it is working!', version: packageJson.version, - documentation: `${req.protocol}://${req.get('host')}/docs`, + swagger: `${req.protocol}://${req.get('host')}/docs`, + documentation: `https://doc.evolution-api.com`, manager: `${req.protocol}://${req.get('host')}/manager`, }); }) diff --git a/src/whatsapp/services/typebot.service.ts b/src/whatsapp/services/typebot.service.ts index 0da51193..6959dfc7 100644 --- a/src/whatsapp/services/typebot.service.ts +++ b/src/whatsapp/services/typebot.service.ts @@ -1,4 +1,5 @@ import axios from 'axios'; +import EventEmitter2 from 'eventemitter2'; import { ConfigService, Typebot } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; @@ -9,7 +10,15 @@ import { Events } from '../types/wa.types'; import { WAMonitoringService } from './monitor.service'; export class TypebotService { - constructor(private readonly waMonitor: WAMonitoringService, private readonly configService: ConfigService) {} + constructor( + private readonly waMonitor: WAMonitoringService, + private readonly configService: ConfigService, + private readonly eventEmitter: EventEmitter2, + ) { + this.eventEmitter.on('typebot:end', async (data) => { + await this.clearSessions(data.instance, data.remoteJid); + }); + } private readonly logger = new Logger(TypebotService.name); @@ -110,6 +119,37 @@ export class TypebotService { return { typebot: { ...instance, typebot: typebotData } }; } + public async clearSessions(instance: InstanceDto, remoteJid: string) { + const findTypebot = await this.find(instance); + const sessions = (findTypebot.sessions as Session[]) ?? []; + + const sessionWithRemoteJid = sessions.filter((session) => session.remoteJid === remoteJid); + + if (sessionWithRemoteJid.length > 0) { + sessionWithRemoteJid.forEach((session) => { + sessions.splice(sessions.indexOf(session), 1); + }); + + const typebotData = { + enabled: findTypebot.enabled, + url: findTypebot.url, + typebot: findTypebot.typebot, + expire: findTypebot.expire, + keyword_finish: findTypebot.keyword_finish, + delay_message: findTypebot.delay_message, + unknown_message: findTypebot.unknown_message, + listening_from_me: findTypebot.listening_from_me, + sessions, + }; + + this.create(instance, typebotData); + + return sessions; + } + + return sessions; + } + public async startTypebot(instance: InstanceDto, data: any) { if (data.remoteJid === 'status@broadcast') return; @@ -169,20 +209,25 @@ export class TypebotService { } else { const id = Math.floor(Math.random() * 10000000000).toString(); - const reqData = { - startParams: { - publicId: data.typebot, - prefilledVariables: prefilledVariables, - }, - }; - try { const version = this.configService.get('TYPEBOT').API_VERSION; let url: string; + let reqData: {}; if (version === 'latest') { url = `${data.url}/api/v1/typebots/${data.typebot}/startChat`; + + reqData = { + prefilledVariables: prefilledVariables, + }; } else { url = `${data.url}/api/v1/sendMessage`; + + reqData = { + startParams: { + publicId: data.typebot, + prefilledVariables: prefilledVariables, + }, + }; } const request = await axios.post(url, reqData); @@ -260,25 +305,35 @@ export class TypebotService { if (data.remoteJid === 'status@broadcast') return; const id = Math.floor(Math.random() * 10000000000).toString(); - const reqData = { - startParams: { - publicId: data.typebot, - prefilledVariables: { - ...data.prefilledVariables, - remoteJid: data.remoteJid, - pushName: data.pushName || data.prefilledVariables?.pushName || '', - instanceName: instance.instanceName, - }, - }, - }; - try { const version = this.configService.get('TYPEBOT').API_VERSION; let url: string; + let reqData: {}; if (version === 'latest') { url = `${data.url}/api/v1/typebots/${data.typebot}/startChat`; + + reqData = { + prefilledVariables: { + ...data.prefilledVariables, + remoteJid: data.remoteJid, + pushName: data.pushName || data.prefilledVariables?.pushName || '', + instanceName: instance.instanceName, + }, + }; } else { url = `${data.url}/api/v1/sendMessage`; + + reqData = { + startParams: { + publicId: data.typebot, + prefilledVariables: { + ...data.prefilledVariables, + remoteJid: data.remoteJid, + pushName: data.pushName || data.prefilledVariables?.pushName || '', + instanceName: instance.instanceName, + }, + }, + }; } const request = await axios.post(url, reqData); @@ -318,37 +373,6 @@ export class TypebotService { } } - public async clearSessions(instance: InstanceDto, remoteJid: string) { - const findTypebot = await this.find(instance); - const sessions = (findTypebot.sessions as Session[]) ?? []; - - const sessionWithRemoteJid = sessions.filter((session) => session.remoteJid === remoteJid); - - if (sessionWithRemoteJid.length > 0) { - sessionWithRemoteJid.forEach((session) => { - sessions.splice(sessions.indexOf(session), 1); - }); - - const typebotData = { - enabled: findTypebot.enabled, - url: findTypebot.url, - typebot: findTypebot.typebot, - expire: findTypebot.expire, - keyword_finish: findTypebot.keyword_finish, - delay_message: findTypebot.delay_message, - unknown_message: findTypebot.unknown_message, - listening_from_me: findTypebot.listening_from_me, - sessions, - }; - - this.create(instance, typebotData); - - return sessions; - } - - return sessions; - } - public async sendWAMessage( instance: InstanceDto, remoteJid: string, @@ -356,11 +380,15 @@ export class TypebotService { input: any[], clientSideActions: any[], ) { - processMessages(this.waMonitor.waInstances[instance.instanceName], messages, input, clientSideActions).catch( - (err) => { - console.error('Erro ao processar mensagens:', err); - }, - ); + processMessages( + this.waMonitor.waInstances[instance.instanceName], + messages, + input, + clientSideActions, + this.eventEmitter, + ).catch((err) => { + console.error('Erro ao processar mensagens:', err); + }); function findItemAndGetSecondsToWait(array, targetId) { if (!array) return null; @@ -373,7 +401,7 @@ export class TypebotService { return null; } - async function processMessages(instance, messages, input, clientSideActions) { + async function processMessages(instance, messages, input, clientSideActions, eventEmitter) { for (const message of messages) { const wait = findItemAndGetSecondsToWait(clientSideActions, message.id); @@ -383,31 +411,50 @@ export class TypebotService { let linkPreview = false; for (const richText of message.content.richText) { - for (const element of richText.children) { - let text = ''; - if (element.text) { - text = element.text; + if (richText.type === 'variable') { + for (const child of richText.children) { + for (const grandChild of child.children) { + formattedText += grandChild.text; + } } + } else { + for (const element of richText.children) { + let text = ''; - if (element.bold) { - text = `*${text}*`; + if (element.type === 'inline-variable') { + for (const child of element.children) { + for (const grandChild of child.children) { + text += grandChild.text; + } + } + } else if (element.text) { + text = element.text; + } + + // if (element.text) { + // text = element.text; + // } + + if (element.bold) { + text = `*${text}*`; + } + + if (element.italic) { + text = `_${text}_`; + } + + if (element.underline) { + text = `*${text}*`; + } + + if (element.url) { + const linkText = element.children[0].text; + text = `[${linkText}](${element.url})`; + linkPreview = true; + } + + formattedText += text; } - - if (element.italic) { - text = `_${text}_`; - } - - if (element.underline) { - text = `*${text}*`; - } - - if (element.url) { - const linkText = element.children[0].text; - text = `[${linkText}](${element.url})`; - linkPreview = true; - } - - formattedText += text; } formattedText += '\n'; } @@ -494,6 +541,11 @@ export class TypebotService { }, }); } + } else { + eventEmitter.emit('typebot:end', { + instance: instance, + remoteJid: remoteJid, + }); } } } diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 618aa65b..705fa594 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -168,7 +168,7 @@ export class WAStartupService { private chatwootService = new ChatwootService(waMonitor, this.configService, this.repository); - private typebotService = new TypebotService(waMonitor, this.configService); + private typebotService = new TypebotService(waMonitor, this.configService, this.eventEmitter); private chamaaiService = new ChamaaiService(waMonitor, this.configService); diff --git a/src/whatsapp/whatsapp.module.ts b/src/whatsapp/whatsapp.module.ts index 1fb84de6..e89d4f56 100644 --- a/src/whatsapp/whatsapp.module.ts +++ b/src/whatsapp/whatsapp.module.ts @@ -101,7 +101,7 @@ export const waMonitor = new WAMonitoringService(eventEmitter, configService, re const authService = new AuthService(configService, waMonitor, repository); -const typebotService = new TypebotService(waMonitor, configService); +const typebotService = new TypebotService(waMonitor, configService, eventEmitter); export const typebotController = new TypebotController(typebotService); From 20fb66e2f7b4c12edba65b2c9ef9902c72e4190a Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 14 Dec 2023 11:50:05 -0300 Subject: [PATCH 04/47] fix: correction sending s3/minio media to chatwoot and typebot --- CHANGELOG.md | 1 + src/whatsapp/services/chatwoot.service.ts | 6 +++++- src/whatsapp/services/whatsapp.service.ts | 4 +++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4263824..510abf7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * Fixed Lid Messages * Fixed sending variables to typebot * Fixed sending variables from typebot +* Correction sending s3/minio media to chatwoot and typebot # 1.6.0 (2023-12-12 17:24) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index a995f367..7aa62994 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -920,7 +920,11 @@ export class ChatwootService { const fileName = decodeURIComponent(parts[parts.length - 1]); this.logger.verbose('file name: ' + fileName); - const mimeType = mimeTypes.lookup(fileName).toString(); + const response = await axios.get(media, { + responseType: 'arraybuffer', + }); + + const mimeType = response.headers['content-type']; this.logger.verbose('mime type: ' + mimeType); let type = 'document'; diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 705fa594..d94a44ec 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -2689,7 +2689,9 @@ export class WAStartupService { mimetype = mediaMessage.mimetype; } else { if (isURL(mediaMessage.media)) { - mimetype = getMIMEType(mediaMessage.media); + const response = await axios.get(mediaMessage.media, { responseType: 'arraybuffer' }); + + mimetype = response.headers['content-type']; } else { mimetype = getMIMEType(mediaMessage.fileName); } From d3a83ba89e792924bc37b663cd9abdcf18fd74f8 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 14 Dec 2023 15:35:17 -0300 Subject: [PATCH 05/47] fix: correction sending s3/minio media to chatwoot and typebot --- src/whatsapp/controllers/instance.controller.ts | 6 +++++- src/whatsapp/types/wa.types.ts | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 8480c675..19669320 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -19,7 +19,7 @@ import { TypebotService } from '../services/typebot.service'; import { WebhookService } from '../services/webhook.service'; import { WebsocketService } from '../services/websocket.service'; import { WAStartupService } from '../services/whatsapp.service'; -import { wa } from '../types/wa.types'; +import { Events, wa } from '../types/wa.types'; export class InstanceController { constructor( @@ -87,6 +87,10 @@ export class InstanceController { const instance = new WAStartupService(this.configService, this.eventEmitter, this.repository, this.cache); instance.instanceName = instanceName; + instance.sendDataWebhook(Events.INSTANCE_CREATE, { + instanceName, + }); + this.logger.verbose('instance: ' + instance.instanceName + ' created'); this.waMonitor.waInstances[instance.instanceName] = instance; diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index 27582001..f6e6da6a 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -3,6 +3,7 @@ import { AuthenticationState, WAConnectionState } from '@whiskeysockets/baileys' export enum Events { APPLICATION_STARTUP = 'application.startup', + INSTANCE_CREATE = 'instance.create', QRCODE_UPDATED = 'qrcode.updated', CONNECTION_UPDATE = 'connection.update', STATUS_INSTANCE = 'status.instance', From 1fc820787a8193301bca122278e9541eff46b726 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 14 Dec 2023 15:57:34 -0300 Subject: [PATCH 06/47] fix: correction sending s3/minio media to chatwoot and typebot --- src/whatsapp/controllers/instance.controller.ts | 3 +++ src/whatsapp/types/wa.types.ts | 1 + 2 files changed, 4 insertions(+) diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 19669320..7ff09426 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -634,6 +634,9 @@ export class InstanceController { this.logger.verbose('deleting instance: ' + instanceName); + this.waMonitor.waInstances[instanceName].sendDataWebhook(Events.INSTANCE_DELETE, { + instanceName, + }); delete this.waMonitor.waInstances[instanceName]; this.eventEmitter.emit('remove.instance', instanceName, 'inner'); return { status: 'SUCCESS', error: false, response: { message: 'Instance deleted' } }; diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index f6e6da6a..5adf9ca2 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -4,6 +4,7 @@ import { AuthenticationState, WAConnectionState } from '@whiskeysockets/baileys' export enum Events { APPLICATION_STARTUP = 'application.startup', INSTANCE_CREATE = 'instance.create', + INSTANCE_DELETE = 'instance.delete', QRCODE_UPDATED = 'qrcode.updated', CONNECTION_UPDATE = 'connection.update', STATUS_INSTANCE = 'status.instance', From a369c16db88fc64f149666013eb6eb00a5a508e8 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 14 Dec 2023 15:59:06 -0300 Subject: [PATCH 07/47] fix: correction sending s3/minio media to chatwoot and typebot --- src/config/env.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 69e79f54..80886724 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -181,7 +181,7 @@ export class ConfigService { private envProcess(): Env { return { SERVER: { - TYPE: process.env.SERVER_TYPE as 'http' | 'https', + TYPE: (process.env.SERVER_TYPE as 'http' | 'https') || 'http', PORT: Number.parseInt(process.env.SERVER_PORT) || 8080, URL: process.env.SERVER_URL, }, From 4e41e072d6d6ae51455d257f5618ddd64f389d4f Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 14 Dec 2023 16:13:15 -0300 Subject: [PATCH 08/47] fix: correction sending s3/minio media to chatwoot and typebot --- Dockerfile | 2 ++ src/config/env.config.ts | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/Dockerfile b/Dockerfile index 82201346..4056daed 100644 --- a/Dockerfile +++ b/Dockerfile @@ -68,6 +68,8 @@ ENV WEBHOOK_GLOBAL_ENABLED=false ENV WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS=false ENV WEBHOOK_EVENTS_APPLICATION_STARTUP=false +ENV WEBHOOK_EVENTS_INSTANCE_CREATE=false +ENV WEBHOOK_EVENTS_INSTANCE_DELETE=false ENV WEBHOOK_EVENTS_QRCODE_UPDATED=true ENV WEBHOOK_EVENTS_MESSAGES_SET=true ENV WEBHOOK_EVENTS_MESSAGES_UPSERT=true diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 80886724..bc09b83a 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -80,6 +80,8 @@ export type Websocket = { export type EventsWebhook = { APPLICATION_STARTUP: boolean; + INSTANCE_CREATE: boolean; + INSTANCE_DELETE: boolean; QRCODE_UPDATED: boolean; MESSAGES_SET: boolean; MESSAGES_UPSERT: boolean; @@ -267,6 +269,8 @@ export class ConfigService { }, EVENTS: { APPLICATION_STARTUP: process.env?.WEBHOOK_EVENTS_APPLICATION_STARTUP === 'true', + INSTANCE_CREATE: process.env?.WEBHOOK_EVENTS_INSTANCE_CREATE === 'false', + INSTANCE_DELETE: process.env?.WEBHOOK_EVENTS_INSTANCE_DELETE === 'false', QRCODE_UPDATED: process.env?.WEBHOOK_EVENTS_QRCODE_UPDATED === 'true', MESSAGES_SET: process.env?.WEBHOOK_EVENTS_MESSAGES_SET === 'true', MESSAGES_UPSERT: process.env?.WEBHOOK_EVENTS_MESSAGES_UPSERT === 'true', From 182dce48406b445f255f8c3068732263c16ac414 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 14 Dec 2023 16:42:03 -0300 Subject: [PATCH 09/47] fix: correction sending s3/minio media to chatwoot and typebot --- Dockerfile | 2 ++ src/config/env.config.ts | 4 ++-- src/whatsapp/services/whatsapp.service.ts | 4 ++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4056daed..7f906ad0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,6 +14,8 @@ COPY ./package.json . ENV TZ=America/Sao_Paulo ENV DOCKER_ENV=true +ENV SERVER_TYPE=http +ENV SERVER_PORT=8080 ENV SERVER_URL=http://localhost:8080 ENV CORS_ORIGIN=* diff --git a/src/config/env.config.ts b/src/config/env.config.ts index bc09b83a..e35e2dd8 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -269,8 +269,8 @@ export class ConfigService { }, EVENTS: { APPLICATION_STARTUP: process.env?.WEBHOOK_EVENTS_APPLICATION_STARTUP === 'true', - INSTANCE_CREATE: process.env?.WEBHOOK_EVENTS_INSTANCE_CREATE === 'false', - INSTANCE_DELETE: process.env?.WEBHOOK_EVENTS_INSTANCE_DELETE === 'false', + INSTANCE_CREATE: process.env?.WEBHOOK_EVENTS_INSTANCE_CREATE === 'true', + INSTANCE_DELETE: process.env?.WEBHOOK_EVENTS_INSTANCE_DELETE === 'true', QRCODE_UPDATED: process.env?.WEBHOOK_EVENTS_QRCODE_UPDATED === 'true', MESSAGES_SET: process.env?.WEBHOOK_EVENTS_MESSAGES_SET === 'true', MESSAGES_UPSERT: process.env?.WEBHOOK_EVENTS_MESSAGES_UPSERT === 'true', diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index d94a44ec..c3f27bf0 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1005,6 +1005,10 @@ export class WAStartupService { } } + console.log('webhookGlobal.GLOBAL?.ENABLED', webhookGlobal.GLOBAL?.ENABLED); + console.log('webhookGlobal.EVENTS[we]', webhookGlobal.EVENTS[we]); + console.log('we', we); + if (webhookGlobal.GLOBAL?.ENABLED) { if (webhookGlobal.EVENTS[we]) { this.logger.verbose('Sending data to webhook global'); From f612a45550b78c1a5b99d9b25efdaf59e507aaed Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 14 Dec 2023 17:20:37 -0300 Subject: [PATCH 10/47] fix: correction sending s3/minio media to chatwoot and typebot --- src/whatsapp/services/whatsapp.service.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index c3f27bf0..d94a44ec 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1005,10 +1005,6 @@ export class WAStartupService { } } - console.log('webhookGlobal.GLOBAL?.ENABLED', webhookGlobal.GLOBAL?.ENABLED); - console.log('webhookGlobal.EVENTS[we]', webhookGlobal.EVENTS[we]); - console.log('we', we); - if (webhookGlobal.GLOBAL?.ENABLED) { if (webhookGlobal.EVENTS[we]) { this.logger.verbose('Sending data to webhook global'); From ff829871446fcfd0f54e3bfc49ec9ef5a8bcd0a3 Mon Sep 17 00:00:00 2001 From: Gabriel Pastori <58153955+gabrielpastori1@users.noreply.github.com> Date: Fri, 15 Dec 2023 12:39:07 -0300 Subject: [PATCH 11/47] simple add keep open --- Docker/.env.example | 1 + src/config/env.config.ts | 3 ++- src/dev-env.yml | 1 + src/whatsapp/services/typebot.service.ts | 3 +++ 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Docker/.env.example b/Docker/.env.example index fefd9456..2813117e 100644 --- a/Docker/.env.example +++ b/Docker/.env.example @@ -107,6 +107,7 @@ QRCODE_COLOR=#198754 # old | latest TYPEBOT_API_VERSION=latest +TYPEBOT_KEEP_OPEN=false # Defines an authentication type for the api # We recommend using the apikey because it will allow you to use a custom token, diff --git a/src/config/env.config.ts b/src/config/env.config.ts index e35e2dd8..45b8a5e1 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -130,7 +130,7 @@ export type SslConf = { PRIVKEY: string; FULLCHAIN: string }; export type Webhook = { GLOBAL?: GlobalWebhook; EVENTS: EventsWebhook }; export type ConfigSessionPhone = { CLIENT: string; NAME: string }; export type QrCode = { LIMIT: number; COLOR: string }; -export type Typebot = { API_VERSION: string }; +export type Typebot = { API_VERSION: string; KEEP_OPEN: boolean }; export type Production = boolean; export interface Env { @@ -308,6 +308,7 @@ export class ConfigService { }, TYPEBOT: { API_VERSION: process.env?.TYPEBOT_API_VERSION || 'old', + KEEP_OPEN: process.env.TYPEBOT_KEEP_OPEN === 'true', }, AUTHENTICATION: { TYPE: process.env.AUTHENTICATION_TYPE as 'apikey', diff --git a/src/dev-env.yml b/src/dev-env.yml index 117226a2..01a5927f 100644 --- a/src/dev-env.yml +++ b/src/dev-env.yml @@ -148,6 +148,7 @@ QRCODE: TYPEBOT: API_VERSION: 'old' # old | latest + KEEP_OPEN: false # Defines an authentication type for the api # We recommend using the apikey because it will allow you to use a custom token, diff --git a/src/whatsapp/services/typebot.service.ts b/src/whatsapp/services/typebot.service.ts index 6959dfc7..dbba16ed 100644 --- a/src/whatsapp/services/typebot.service.ts +++ b/src/whatsapp/services/typebot.service.ts @@ -16,6 +16,9 @@ export class TypebotService { private readonly eventEmitter: EventEmitter2, ) { this.eventEmitter.on('typebot:end', async (data) => { + const keep_open = this.configService.get('TYPEBOT').KEEP_OPEN; + if (keep_open) return; + await this.clearSessions(data.instance, data.remoteJid); }); } From b781c83545123b9da89263021f8bd94d5437f465 Mon Sep 17 00:00:00 2001 From: Guilherme Oliveira Date: Fri, 15 Dec 2023 14:46:31 -0300 Subject: [PATCH 12/47] Dockerfile modified to use multi-stage build --- Dockerfile | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7f906ad0..cf9bccf4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:20.7.0-alpine +FROM node:20.7.0-alpine AS builder LABEL version="1.6.1" description="Api to control whatsapp features through http requests." LABEL maintainer="Davidson Gomes" git="https://github.com/DavidsonGomes" @@ -11,6 +11,14 @@ WORKDIR /evolution COPY ./package.json . +RUN npm install + +COPY . . + +RUN npm run build + +FROM node:20.7.0-alpine AS final + ENV TZ=America/Sao_Paulo ENV DOCKER_ENV=true @@ -126,10 +134,8 @@ ENV AUTHENTICATION_INSTANCE_CHATWOOT_ACCOUNT_ID=1 ENV AUTHENTICATION_INSTANCE_CHATWOOT_TOKEN=123456 ENV AUTHENTICATION_INSTANCE_CHATWOOT_URL= -RUN npm install +WORKDIR /evolution -COPY . . - -RUN npm run build +COPY --from=builder /evolution . CMD [ "node", "./dist/src/main.js" ] From 1be1326b52cfda26b46efef8ea64349f1e6e8850 Mon Sep 17 00:00:00 2001 From: Gabriel Pastori <58153955+gabrielpastori1@users.noreply.github.com> Date: Sat, 16 Dec 2023 15:58:01 -0300 Subject: [PATCH 13/47] Refactor message formatting in ChatwootService (Bold, italic, etc) --- src/whatsapp/services/chatwoot.service.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 7aa62994..86fbf13a 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1019,7 +1019,13 @@ export class ChatwootService { this.logger.verbose('check if is group'); const chatId = body.conversation.meta.sender?.phone_number?.replace('+', '') || body.conversation.meta.sender?.identifier; - const messageReceived = body.content; + // Alterado por Edison Martins em 16/12/2023 + // const messageReceived = body.content; + const messageReceived = body.content + .replaceAll(/\*((?!\s)([^\n*]+?)(? Date: Sat, 16 Dec 2023 17:23:39 -0300 Subject: [PATCH 14/47] chatwoot_sign_delimiter --- src/validate/validate.schema.ts | 1 + src/whatsapp/controllers/chatwoot.controller.ts | 2 ++ src/whatsapp/dto/chatwoot.dto.ts | 1 + src/whatsapp/models/chatwoot.model.ts | 2 ++ src/whatsapp/services/chatwoot.service.ts | 8 +++++++- src/whatsapp/services/whatsapp.service.ts | 6 +++++- 6 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index a468b151..4b803873 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -889,6 +889,7 @@ export const chatwootSchema: JSONSchema7 = { token: { type: 'string' }, url: { type: 'string' }, sign_msg: { type: 'boolean', enum: [true, false] }, + sign_delimiter: { type: ['string', 'null'] }, reopen_conversation: { type: 'boolean', enum: [true, false] }, conversation_pending: { type: 'boolean', enum: [true, false] }, auto_create: { type: 'boolean', enum: [true, false] }, diff --git a/src/whatsapp/controllers/chatwoot.controller.ts b/src/whatsapp/controllers/chatwoot.controller.ts index b83b2ddc..8f59ccac 100644 --- a/src/whatsapp/controllers/chatwoot.controller.ts +++ b/src/whatsapp/controllers/chatwoot.controller.ts @@ -37,6 +37,7 @@ export class ChatwootController { if (data.sign_msg !== true && data.sign_msg !== false) { throw new BadRequestException('sign_msg is required'); } + if (data.sign_msg === false) data.sign_delimiter = null; } if (!data.enabled) { @@ -45,6 +46,7 @@ export class ChatwootController { data.token = ''; data.url = ''; data.sign_msg = false; + data.sign_delimiter = null; data.reopen_conversation = false; data.conversation_pending = false; data.auto_create = false; diff --git a/src/whatsapp/dto/chatwoot.dto.ts b/src/whatsapp/dto/chatwoot.dto.ts index 22085faf..7960a1a0 100644 --- a/src/whatsapp/dto/chatwoot.dto.ts +++ b/src/whatsapp/dto/chatwoot.dto.ts @@ -5,6 +5,7 @@ export class ChatwootDto { url?: string; name_inbox?: string; sign_msg?: boolean; + sign_delimiter?: string; number?: string; reopen_conversation?: boolean; conversation_pending?: boolean; diff --git a/src/whatsapp/models/chatwoot.model.ts b/src/whatsapp/models/chatwoot.model.ts index ed7c2ef0..54b45f7c 100644 --- a/src/whatsapp/models/chatwoot.model.ts +++ b/src/whatsapp/models/chatwoot.model.ts @@ -10,6 +10,7 @@ export class ChatwootRaw { url?: string; name_inbox?: string; sign_msg?: boolean; + sign_delimiter?: string; number?: string; reopen_conversation?: boolean; conversation_pending?: boolean; @@ -23,6 +24,7 @@ const chatwootSchema = new Schema({ url: { type: String, required: true }, name_inbox: { type: String, required: true }, sign_msg: { type: Boolean, required: true }, + sign_delimiter: { type: String, required: false }, number: { type: String, required: true }, reopen_conversation: { type: Boolean, required: true }, conversation_pending: { type: Boolean, required: true }, diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 86fbf13a..65459a62 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1121,7 +1121,13 @@ export class ChatwootService { if (senderName === null || senderName === undefined) { formatText = messageReceived; } else { - formatText = this.provider.sign_msg ? `*${senderName}:*\n${messageReceived}` : messageReceived; + const formattedDelimiter = this.provider.sign_delimiter + ? this.provider.sign_delimiter.replaceAll('\\n', '\n') + : '\n'; + const textToConcat = this.provider.sign_msg ? [`*${senderName}:*`] : []; + textToConcat.push(messageReceived); + + formatText = textToConcat.join(formattedDelimiter); } for (const message of body.conversation.messages) { diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index d94a44ec..8eaa1a2a 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -357,10 +357,12 @@ export class WAStartupService { this.logger.verbose(`Chatwoot url: ${data.url}`); this.logger.verbose(`Chatwoot inbox name: ${data.name_inbox}`); this.logger.verbose(`Chatwoot sign msg: ${data.sign_msg}`); + this.logger.verbose(`Chatwoot sign delimiter: ${data.sign_delimiter}`); this.logger.verbose(`Chatwoot reopen conversation: ${data.reopen_conversation}`); this.logger.verbose(`Chatwoot conversation pending: ${data.conversation_pending}`); - Object.assign(this.localChatwoot, data); + Object.assign(this.localChatwoot, { ...data, sign_delimiter: data.sign_msg ? data.sign_delimiter : null }); + this.logger.verbose('Chatwoot set'); } @@ -378,6 +380,7 @@ export class WAStartupService { this.logger.verbose(`Chatwoot url: ${data.url}`); this.logger.verbose(`Chatwoot inbox name: ${data.name_inbox}`); this.logger.verbose(`Chatwoot sign msg: ${data.sign_msg}`); + this.logger.verbose(`Chatwoot sign delimiter: ${data.sign_delimiter}`); this.logger.verbose(`Chatwoot reopen conversation: ${data.reopen_conversation}`); this.logger.verbose(`Chatwoot conversation pending: ${data.conversation_pending}`); @@ -388,6 +391,7 @@ export class WAStartupService { url: data.url, name_inbox: data.name_inbox, sign_msg: data.sign_msg, + sign_delimiter: data.sign_delimiter || null, reopen_conversation: data.reopen_conversation, conversation_pending: data.conversation_pending, }; From 5aa89d85f306ab47bb2faf448af7c8dc9c79a726 Mon Sep 17 00:00:00 2001 From: Gabriel Pastori <58153955+gabrielpastori1@users.noreply.github.com> Date: Sat, 16 Dec 2023 18:39:46 -0300 Subject: [PATCH 15/47] fix: remove comments --- src/whatsapp/services/chatwoot.service.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 65459a62..fe11d083 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1019,8 +1019,6 @@ export class ChatwootService { this.logger.verbose('check if is group'); const chatId = body.conversation.meta.sender?.phone_number?.replace('+', '') || body.conversation.meta.sender?.identifier; - // Alterado por Edison Martins em 16/12/2023 - // const messageReceived = body.content; const messageReceived = body.content .replaceAll(/\*((?!\s)([^\n*]+?)(? Date: Sun, 17 Dec 2023 06:59:05 -0300 Subject: [PATCH 16/47] fix: include instance Id field in the instance configuration --- CHANGELOG.md | 4 ++++ src/whatsapp/controllers/instance.controller.ts | 7 +++++++ src/whatsapp/dto/instance.dto.ts | 1 + src/whatsapp/models/auth.model.ts | 2 ++ src/whatsapp/repository/auth.repository.ts | 1 + src/whatsapp/services/auth.service.ts | 7 +++++-- src/whatsapp/services/monitor.service.ts | 2 ++ 7 files changed, 22 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 510abf7e..4e8bc2fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ * Fixed sending variables to typebot * Fixed sending variables from typebot * Correction sending s3/minio media to chatwoot and typebot +* Fixed the problem with typebot closing at the end of the flow, now this is optional with the TYPEBOT_KEEP_OPEN variable +* Fixed chatwoot Bold, Italic and Underline formatting using Regex +* Added the sign_delimiter property to the Chatwoot configuration, allowing you to set a different delimiter for the signature. Default when not defined \n +* Include instance Id field in the instance configuration # 1.6.0 (2023-12-12 17:24) diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 7ff09426..275a1554 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -1,6 +1,7 @@ import { delay } from '@whiskeysockets/baileys'; import { isURL } from 'class-validator'; import EventEmitter2 from 'eventemitter2'; +import { v4 } from 'uuid'; import { ConfigService, HttpServer } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; @@ -87,8 +88,11 @@ export class InstanceController { const instance = new WAStartupService(this.configService, this.eventEmitter, this.repository, this.cache); instance.instanceName = instanceName; + const instanceId = v4(); + instance.sendDataWebhook(Events.INSTANCE_CREATE, { instanceName, + instanceId: instanceId, }); this.logger.verbose('instance: ' + instance.instanceName + ' created'); @@ -100,6 +104,7 @@ export class InstanceController { const hash = await this.authService.generateHash( { instanceName: instance.instanceName, + instanceId: instanceId, }, token, ); @@ -367,6 +372,7 @@ export class InstanceController { const result = { instance: { instanceName: instance.instanceName, + instanceId: instanceId, status: 'created', }, hash, @@ -459,6 +465,7 @@ export class InstanceController { return { instance: { instanceName: instance.instanceName, + instanceId: instanceId, status: 'created', }, hash, diff --git a/src/whatsapp/dto/instance.dto.ts b/src/whatsapp/dto/instance.dto.ts index c63620c5..2bf5c362 100644 --- a/src/whatsapp/dto/instance.dto.ts +++ b/src/whatsapp/dto/instance.dto.ts @@ -1,5 +1,6 @@ export class InstanceDto { instanceName: string; + instanceId?: string; qrcode?: boolean; number?: string; token?: string; diff --git a/src/whatsapp/models/auth.model.ts b/src/whatsapp/models/auth.model.ts index 0f7d5ec3..9ae5537f 100644 --- a/src/whatsapp/models/auth.model.ts +++ b/src/whatsapp/models/auth.model.ts @@ -6,12 +6,14 @@ export class AuthRaw { _id?: string; jwt?: string; apikey?: string; + instanceId?: string; } const authSchema = new Schema({ _id: { type: String, _id: true }, jwt: { type: String, minlength: 1 }, apikey: { type: String, minlength: 1 }, + instanceId: { type: String, minlength: 1 }, }); export const AuthModel = dbserver?.model(AuthRaw.name, authSchema, 'authentication'); diff --git a/src/whatsapp/repository/auth.repository.ts b/src/whatsapp/repository/auth.repository.ts index 4da8980b..5720cccb 100644 --- a/src/whatsapp/repository/auth.repository.ts +++ b/src/whatsapp/repository/auth.repository.ts @@ -19,6 +19,7 @@ export class AuthRepository extends Repository { public async create(data: AuthRaw, instance: string): Promise { try { this.logger.verbose('creating auth'); + if (this.dbSettings.ENABLED) { this.logger.verbose('saving auth to db'); const insert = await this.authModel.replaceOne({ _id: instance }, { ...data }, { upsert: true }); diff --git a/src/whatsapp/services/auth.service.ts b/src/whatsapp/services/auth.service.ts index 915a07b7..45a43551 100644 --- a/src/whatsapp/services/auth.service.ts +++ b/src/whatsapp/services/auth.service.ts @@ -46,7 +46,10 @@ export class AuthService { this.logger.verbose('JWT token created: ' + token); - const auth = await this.repository.auth.create({ jwt: token }, instance.instanceName); + const auth = await this.repository.auth.create( + { jwt: token, instanceId: instance.instanceId }, + instance.instanceName, + ); this.logger.verbose('JWT token saved in database'); @@ -66,7 +69,7 @@ export class AuthService { this.logger.verbose(token ? 'APIKEY defined: ' + apikey : 'APIKEY created: ' + apikey); - const auth = await this.repository.auth.create({ apikey }, instance.instanceName); + const auth = await this.repository.auth.create({ apikey, instanceId: instance.instanceId }, instance.instanceName); this.logger.verbose('APIKEY saved in database'); diff --git a/src/whatsapp/services/monitor.service.ts b/src/whatsapp/services/monitor.service.ts index 766569de..54193664 100644 --- a/src/whatsapp/services/monitor.service.ts +++ b/src/whatsapp/services/monitor.service.ts @@ -112,6 +112,7 @@ export class WAMonitoringService { const instanceData = { instance: { instanceName: key, + instanceId: (await this.repository.auth.find(key))?.instanceId, owner: value.wuid, profileName: (await value.getProfileName()) || 'not loaded', profilePictureUrl: value.profilePictureUrl, @@ -135,6 +136,7 @@ export class WAMonitoringService { const instanceData = { instance: { instanceName: key, + instanceId: (await this.repository.auth.find(key))?.instanceId, status: value.connectionStatus.state, }, }; From 7cc324e1c099ee2cb6b2498c5abdf37b89dfb6b1 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 17 Dec 2023 07:04:33 -0300 Subject: [PATCH 17/47] fix: include instance Id field in the instance configuration --- .../controllers/instance.controller.ts | 4 +- src/whatsapp/repository/auth.repository.ts | 17 ++++ src/whatsapp/services/monitor.service.ts | 78 +++++++++++++++++++ 3 files changed, 98 insertions(+), 1 deletion(-) diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 275a1554..a4517955 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -591,11 +591,13 @@ export class InstanceController { }; } - public async fetchInstances({ instanceName }: InstanceDto) { + public async fetchInstances({ instanceName, instanceId }: InstanceDto) { if (instanceName) { this.logger.verbose('requested fetchInstances from ' + instanceName + ' instance'); this.logger.verbose('instanceName: ' + instanceName); return this.waMonitor.instanceInfo(instanceName); + } else if (instanceId) { + return this.waMonitor.instanceInfoById(instanceId); } this.logger.verbose('requested fetchInstances (all instances)'); diff --git a/src/whatsapp/repository/auth.repository.ts b/src/whatsapp/repository/auth.repository.ts index 5720cccb..47fc579e 100644 --- a/src/whatsapp/repository/auth.repository.ts +++ b/src/whatsapp/repository/auth.repository.ts @@ -5,6 +5,7 @@ import { Auth, ConfigService } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; import { AUTH_DIR } from '../../config/path.config'; import { IInsert, Repository } from '../abstract/abstract.repository'; +import { InstanceDto } from '../dto/instance.dto'; import { AuthRaw, IAuthModel } from '../models'; export class AuthRepository extends Repository { @@ -63,4 +64,20 @@ export class AuthRepository extends Repository { return {}; } } + + public async findInstanceNameById(instanceId: string): Promise { + try { + this.logger.verbose('finding auth by instanceId'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('finding auth in db'); + const response = await this.authModel.findOne({ instanceId }); + + return response._id; + } + + this.logger.verbose('finding auth in store is not supported'); + } catch (error) { + return ''; + } + } } diff --git a/src/whatsapp/services/monitor.service.ts b/src/whatsapp/services/monitor.service.ts index 54193664..78c83c85 100644 --- a/src/whatsapp/services/monitor.service.ts +++ b/src/whatsapp/services/monitor.service.ts @@ -159,6 +159,84 @@ export class WAMonitoringService { return instances.find((i) => i.instance.instanceName === instanceName) ?? instances; } + public async instanceInfoById(instanceId?: string) { + this.logger.verbose('get instance info'); + const instanceName = await this.repository.auth.findInstanceNameById(instanceId); + if (instanceName && !this.waInstances[instanceName]) { + throw new NotFoundException(`Instance "${instanceName}" not found`); + } + + const instances: any[] = []; + + for await (const [key, value] of Object.entries(this.waInstances)) { + if (value) { + this.logger.verbose('get instance info: ' + key); + let chatwoot: any; + + const urlServer = this.configService.get('SERVER').URL; + + const findChatwoot = await this.waInstances[key].findChatwoot(); + + if (findChatwoot && findChatwoot.enabled) { + chatwoot = { + ...findChatwoot, + webhook_url: `${urlServer}/chatwoot/webhook/${encodeURIComponent(key)}`, + }; + } + + if (value.connectionStatus.state === 'open') { + this.logger.verbose('instance: ' + key + ' - connectionStatus: open'); + + const instanceData = { + instance: { + instanceName: key, + instanceId: (await this.repository.auth.find(key))?.instanceId, + owner: value.wuid, + profileName: (await value.getProfileName()) || 'not loaded', + profilePictureUrl: value.profilePictureUrl, + profileStatus: (await value.getProfileStatus()) || '', + status: value.connectionStatus.state, + }, + }; + + if (this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) { + instanceData.instance['serverUrl'] = this.configService.get('SERVER').URL; + + instanceData.instance['apikey'] = (await this.repository.auth.find(key))?.apikey; + + instanceData.instance['chatwoot'] = chatwoot; + } + + instances.push(instanceData); + } else { + this.logger.verbose('instance: ' + key + ' - connectionStatus: ' + value.connectionStatus.state); + + const instanceData = { + instance: { + instanceName: key, + instanceId: (await this.repository.auth.find(key))?.instanceId, + status: value.connectionStatus.state, + }, + }; + + if (this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) { + instanceData.instance['serverUrl'] = this.configService.get('SERVER').URL; + + instanceData.instance['apikey'] = (await this.repository.auth.find(key))?.apikey; + + instanceData.instance['chatwoot'] = chatwoot; + } + + instances.push(instanceData); + } + } + } + + this.logger.verbose('return instance info: ' + instances.length); + + return instances.find((i) => i.instance.instanceName === instanceName) ?? instances; + } + private delInstanceFiles() { this.logger.verbose('cron to delete instance files started'); setInterval(async () => { From 4ba5cfceaf34396352e5eb5dc86b6f954c06d0bb Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 17 Dec 2023 07:50:17 -0300 Subject: [PATCH 18/47] fix: include instance Id field in the instance configuration --- src/whatsapp/controllers/instance.controller.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index a4517955..0f06895e 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -645,6 +645,7 @@ export class InstanceController { this.waMonitor.waInstances[instanceName].sendDataWebhook(Events.INSTANCE_DELETE, { instanceName, + instanceId: (await this.repository.auth.find(instanceName))?.instanceId, }); delete this.waMonitor.waInstances[instanceName]; this.eventEmitter.emit('remove.instance', instanceName, 'inner'); From 2d6a29664ac9fdccca8871d72e730c22ff8d84be Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 17 Dec 2023 07:59:24 -0300 Subject: [PATCH 19/47] fix: include instance Id field in the instance configuration --- docker-compose.yaml.example.dockerhub | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yaml.example.dockerhub b/docker-compose.yaml.example.dockerhub index 562d1b07..b33e8f4a 100644 --- a/docker-compose.yaml.example.dockerhub +++ b/docker-compose.yaml.example.dockerhub @@ -3,7 +3,7 @@ version: '3.3' services: api: container_name: evolution_api - image: davidsongomes/evolution-api:latest + image: atendai/evolution-api:latest restart: always ports: - 8080:8080 From da796347c4eafc977037bb0a48bc972bd30c8da3 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 17 Dec 2023 09:37:18 -0300 Subject: [PATCH 20/47] fix: include instance Id field in the instance configuration --- src/whatsapp/repository/auth.repository.ts | 5 ++--- src/whatsapp/services/monitor.service.ts | 4 ++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/whatsapp/repository/auth.repository.ts b/src/whatsapp/repository/auth.repository.ts index 47fc579e..7aa1a427 100644 --- a/src/whatsapp/repository/auth.repository.ts +++ b/src/whatsapp/repository/auth.repository.ts @@ -5,7 +5,6 @@ import { Auth, ConfigService } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; import { AUTH_DIR } from '../../config/path.config'; import { IInsert, Repository } from '../abstract/abstract.repository'; -import { InstanceDto } from '../dto/instance.dto'; import { AuthRaw, IAuthModel } from '../models'; export class AuthRepository extends Repository { @@ -65,7 +64,7 @@ export class AuthRepository extends Repository { } } - public async findInstanceNameById(instanceId: string): Promise { + public async findInstanceNameById(instanceId: string): Promise { try { this.logger.verbose('finding auth by instanceId'); if (this.dbSettings.ENABLED) { @@ -77,7 +76,7 @@ export class AuthRepository extends Repository { this.logger.verbose('finding auth in store is not supported'); } catch (error) { - return ''; + return null; } } } diff --git a/src/whatsapp/services/monitor.service.ts b/src/whatsapp/services/monitor.service.ts index 78c83c85..b449f693 100644 --- a/src/whatsapp/services/monitor.service.ts +++ b/src/whatsapp/services/monitor.service.ts @@ -162,6 +162,10 @@ export class WAMonitoringService { public async instanceInfoById(instanceId?: string) { this.logger.verbose('get instance info'); const instanceName = await this.repository.auth.findInstanceNameById(instanceId); + if (!instanceName) { + throw new NotFoundException(`Instance "${instanceId}" not found`); + } + if (instanceName && !this.waInstances[instanceName]) { throw new NotFoundException(`Instance "${instanceName}" not found`); } From 8d041983096c398e57e9ee0b926860ff19ba54a7 Mon Sep 17 00:00:00 2001 From: Gabriel Pastori <58153955+gabrielpastori1@users.noreply.github.com> Date: Sun, 17 Dec 2023 13:24:43 -0300 Subject: [PATCH 21/47] fix: monospace and bold --- src/whatsapp/services/chatwoot.service.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index fe11d083..cf32e00e 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1019,10 +1019,12 @@ export class ChatwootService { this.logger.verbose('check if is group'); const chatId = body.conversation.meta.sender?.phone_number?.replace('+', '') || body.conversation.meta.sender?.identifier; + // Chatwoot to Whatsapp const messageReceived = body.content - .replaceAll(/\*((?!\s)([^\n*]+?)(? Date: Sun, 17 Dec 2023 13:25:03 -0300 Subject: [PATCH 22/47] Add new env and fix message formatting in Chatwoot to changelog --- CHANGELOG.md | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 510abf7e..0a749609 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,17 @@ # 1.6.1 (develop) +### Feature + +* New env `TYPEBOT_KEEP_OPEN` to keep the session open after the end of the flow +* Add `sign_delimiter` to chatwoot set to change the delimiter of the signature + ### Fixed * Fixed Lid Messages * Fixed sending variables to typebot * Fixed sending variables from typebot * Correction sending s3/minio media to chatwoot and typebot +* Fixed message formatting in chatwoot (bold, italic, underline, monospace) # 1.6.0 (2023-12-12 17:24) @@ -39,8 +45,8 @@ ### Integrations -- Chatwoot: v3.3.1 -- Typebot: v2.20.0 +* Chatwoot: v3.3.1 +* Typebot: v2.20.0 # 1.5.4 (2023-10-09 20:43) @@ -119,9 +125,9 @@ ### Integrations -- Chatwoot: v2.18.0 - v3.0.0 -- Typebot: v2.16.0 -- Manager Evolution API +* Chatwoot: v2.18.0 - v3.0.0 +* Typebot: v2.16.0 +* Manager Evolution API # 1.4.8 (2023-07-27 10:27) @@ -174,7 +180,7 @@ ### Fixed -* Fixed validation is set settings +* Fixed validation is set settings * Adjusts in group validations * Ajusts in sticker message to chatwoot @@ -209,7 +215,7 @@ ### Integrations -- Chatwoot: v2.18.0 - v3.0.0 (Beta) +* Chatwoot: v2.18.0 - v3.0.0 (Beta) # 1.3.2 (2023-07-21 17:19) @@ -225,7 +231,7 @@ ### Integrations -- Chatwoot: v2.18.0 +* Chatwoot: v2.18.0 # 1.3.1 (2023-07-20 07:48) @@ -235,7 +241,7 @@ ### Integrations -- Chatwoot: v2.18.0 +* Chatwoot: v2.18.0 # 1.3.0 (2023-07-19 11:33) @@ -251,7 +257,7 @@ * Translation set to default (english) in chatwoot ### Fixed - + * Fixed error to send message in large groups * Docker files adjusted * Fixed in the postman collection the webhookByEvent parameter by webhook_by_events @@ -272,7 +278,7 @@ ### Integrations -- Chatwoot: v2.18.0 +* Chatwoot: v2.18.0 # 1.2.2 (2023-07-15 09:36) @@ -283,7 +289,7 @@ ### Integrations -- Chatwoot: v2.18.0 +* Chatwoot: v2.18.0 # 1.2.1 (2023-07-14 19:04) @@ -439,4 +445,4 @@ * Sending the local webhook url as destination in the webhook data for webhook redirection * Startup modes, server or container * Server Mode works normally as everyone is used to -* Container mode made to use one instance per container, when starting the application an instance is already created and the qrcode is generated and it starts sending webhook without having to call it manually, it only allows one instance at a time. \ No newline at end of file +* Container mode made to use one instance per container, when starting the application an instance is already created and the qrcode is generated and it starts sending webhook without having to call it manually, it only allows one instance at a time. From 38978dd447aaa39ba9747d078a65d26ccd460a41 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 18 Dec 2023 12:07:02 -0300 Subject: [PATCH 23/47] test: adjusts baileys lids --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 54f8e4a9..f03144fe 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "@figuro/chatwoot-sdk": "^1.1.16", "@hapi/boom": "^10.0.1", "@sentry/node": "^7.59.2", - "@whiskeysockets/baileys": "github:WhiskeySockets/Baileys#fix-lids", + "@whiskeysockets/baileys": "github:PurpShell/Baileys", "amqplib": "^0.10.3", "aws-sdk": "^2.1499.0", "axios": "^1.3.5", @@ -56,7 +56,7 @@ "cross-env": "^7.0.3", "dayjs": "^1.11.7", "eventemitter2": "^6.4.9", - "evolution-manager": "^0.4.6", + "evolution-manager": "^0.4.8", "exiftool-vendored": "^22.0.0", "express": "^4.18.2", "express-async-errors": "^3.1.1", From 35641d054349323c2a6335dbb4b09c1de8e8092f Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 18 Dec 2023 15:24:19 -0300 Subject: [PATCH 24/47] fix: fixed the pairing code --- CHANGELOG.md | 1 + src/whatsapp/services/whatsapp.service.ts | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d3078a78..3ec26b40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ * Fixed chatwoot Bold, Italic and Underline formatting using Regex * Added the sign_delimiter property to the Chatwoot configuration, allowing you to set a different delimiter for the signature. Default when not defined \n * Include instance Id field in the instance configuration +* Fixed the pairing code # 1.6.0 (2023-12-12 17:24) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 8eaa1a2a..2529e616 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1383,7 +1383,7 @@ export class WAStartupService { }, logger: P({ level: this.logBaileys }), printQRInTerminal: false, - browser, + browser: ['Chrome (Linux)', '', ''], version, markOnlineOnConnect: this.localSettings.always_online, retryRequestDelayMs: 10, @@ -1449,8 +1449,8 @@ export class WAStartupService { this.instance.authState = await this.defineAuthState(); const { version } = await fetchLatestBaileysVersion(); - const session = this.configService.get('CONFIG_SESSION_PHONE'); - const browser: WABrowserDescription = [session.CLIENT, session.NAME, release()]; + // const session = this.configService.get('CONFIG_SESSION_PHONE'); + // const browser: WABrowserDescription = [session.CLIENT, session.NAME, release()]; let options; @@ -1470,7 +1470,7 @@ export class WAStartupService { }, logger: P({ level: this.logBaileys }), printQRInTerminal: false, - browser, + browser: ['Chrome (Linux)', '', ''], version, markOnlineOnConnect: this.localSettings.always_online, retryRequestDelayMs: 10, From d39776a3147bc6178101e84a2f6da963791283a8 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 18 Dec 2023 15:27:22 -0300 Subject: [PATCH 25/47] fix: fixed the pairing code --- src/whatsapp/services/whatsapp.service.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 2529e616..4bbbe834 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1383,7 +1383,7 @@ export class WAStartupService { }, logger: P({ level: this.logBaileys }), printQRInTerminal: false, - browser: ['Chrome (Linux)', '', ''], + browser: ['Chrome (Linux)', session.NAME, release()], version, markOnlineOnConnect: this.localSettings.always_online, retryRequestDelayMs: 10, @@ -1449,7 +1449,7 @@ export class WAStartupService { this.instance.authState = await this.defineAuthState(); const { version } = await fetchLatestBaileysVersion(); - // const session = this.configService.get('CONFIG_SESSION_PHONE'); + const session = this.configService.get('CONFIG_SESSION_PHONE'); // const browser: WABrowserDescription = [session.CLIENT, session.NAME, release()]; let options; @@ -1470,7 +1470,7 @@ export class WAStartupService { }, logger: P({ level: this.logBaileys }), printQRInTerminal: false, - browser: ['Chrome (Linux)', '', ''], + browser: ['Chrome (Linux)', session.NAME, release()], version, markOnlineOnConnect: this.localSettings.always_online, retryRequestDelayMs: 10, From 8bfc62a3b261bec5551d1c7170b7618a921edc64 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 18 Dec 2023 16:27:37 -0300 Subject: [PATCH 26/47] fix: adjusts in typebot --- src/whatsapp/services/typebot.service.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/whatsapp/services/typebot.service.ts b/src/whatsapp/services/typebot.service.ts index dbba16ed..3dc4c894 100644 --- a/src/whatsapp/services/typebot.service.ts +++ b/src/whatsapp/services/typebot.service.ts @@ -637,12 +637,12 @@ export class TypebotService { let urlTypebot: string; let reqData: {}; if (version === 'latest') { - urlTypebot = `${data.url}/api/v1/sessions/${data.sessionId}/continueChat`; + urlTypebot = `${url}/api/v1/sessions/${data.sessionId}/continueChat`; reqData = { message: content, }; } else { - urlTypebot = `${data.url}/api/v1/sendMessage`; + urlTypebot = `${url}/api/v1/sendMessage`; reqData = { message: content, sessionId: data.sessionId, @@ -734,12 +734,12 @@ export class TypebotService { let urlTypebot: string; let reqData: {}; if (version === 'latest') { - urlTypebot = `${data.url}/api/v1/sessions/${data.sessionId}/continueChat`; + urlTypebot = `${url}/api/v1/sessions/${data.sessionId}/continueChat`; reqData = { message: content, }; } else { - urlTypebot = `${data.url}/api/v1/sendMessage`; + urlTypebot = `${url}/api/v1/sendMessage`; reqData = { message: content, sessionId: data.sessionId, From 547f981c47706741c57cc66eaf5d7e79d9fbeb13 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 18 Dec 2023 16:46:04 -0300 Subject: [PATCH 27/47] fix: adjusts in typebot --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ec26b40..429fd513 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * Added the sign_delimiter property to the Chatwoot configuration, allowing you to set a different delimiter for the signature. Default when not defined \n * Include instance Id field in the instance configuration * Fixed the pairing code +* Adjusts in typebot # 1.6.0 (2023-12-12 17:24) From 076f2b492ea5e682eb23891ebfeb7f36aac55102 Mon Sep 17 00:00:00 2001 From: Gabriel Pastori <58153955+gabrielpastori1@users.noreply.github.com> Date: Mon, 18 Dec 2023 21:23:56 -0300 Subject: [PATCH 28/47] fix: chatwoot media process --- src/whatsapp/services/chatwoot.service.ts | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index cf32e00e..87f70219 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1021,10 +1021,12 @@ export class ChatwootService { body.conversation.meta.sender?.phone_number?.replace('+', '') || body.conversation.meta.sender?.identifier; // Chatwoot to Whatsapp const messageReceived = body.content - .replaceAll(/(? Date: Tue, 19 Dec 2023 08:02:29 -0300 Subject: [PATCH 29/47] Add connected number and instance name to connected log --- src/whatsapp/services/whatsapp.service.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 4bbbe834..d8f7c997 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1233,10 +1233,14 @@ export class WAStartupService { this.logger.verbose('Connection opened'); this.instance.wuid = this.client.user.id.replace(/:\d+/, ''); this.instance.profilePictureUrl = (await this.profilePicture(this.instance.wuid)).profilePictureUrl; + const formattedWuid = this.instance.wuid.split('@')[0].padEnd(30, ' '); + const formattedName = this.instance.name.split('@')[0].padEnd(30, ' '); this.logger.info( ` ┌──────────────────────────────┐ │ CONNECTED TO WHATSAPP │ + │${formattedWuid}│ + │${formattedName}│ └──────────────────────────────┘`.replace(/^ +/gm, ' '), ); From e8764dd1c6b294a9335925afab3ac734c73c91bb Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 19 Dec 2023 14:55:16 -0300 Subject: [PATCH 30/47] fix: Fix the problem when disconnecting the instance and connecting again using mongodb --- CHANGELOG.md | 1 + src/whatsapp/services/monitor.service.ts | 17 +++++++++-------- src/whatsapp/services/whatsapp.service.ts | 6 +++--- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 429fd513..6b62084d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * Include instance Id field in the instance configuration * Fixed the pairing code * Adjusts in typebot +* Fix the problem when disconnecting the instance and connecting again using mongodb # 1.6.0 (2023-12-12 17:24) diff --git a/src/whatsapp/services/monitor.service.ts b/src/whatsapp/services/monitor.service.ts index b449f693..0191079c 100644 --- a/src/whatsapp/services/monitor.service.ts +++ b/src/whatsapp/services/monitor.service.ts @@ -277,12 +277,6 @@ export class WAMonitoringService { public async cleaningUp(instanceName: string) { this.logger.verbose('cleaning up instance: ' + instanceName); - if (this.redis.ENABLED) { - this.logger.verbose('cleaning up instance in redis: ' + instanceName); - this.cache.reference = instanceName; - await this.cache.delAll(); - return; - } if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) { this.logger.verbose('cleaning up instance in database: ' + instanceName); @@ -294,6 +288,13 @@ export class WAMonitoringService { return; } + if (this.redis.ENABLED) { + this.logger.verbose('cleaning up instance in redis: ' + instanceName); + this.cache.reference = instanceName; + await this.cache.delAll(); + return; + } + this.logger.verbose('cleaning up instance in files: ' + instanceName); rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true }); } @@ -441,8 +442,8 @@ export class WAMonitoringService { this.eventEmitter.on('logout.instance', async (instanceName: string) => { this.logger.verbose('logout instance: ' + instanceName); try { - // this.logger.verbose('request cleaning up instance: ' + instanceName); - // this.cleaningUp(instanceName); + this.logger.verbose('request cleaning up instance: ' + instanceName); + this.cleaningUp(instanceName); } finally { this.logger.warn(`Instance "${instanceName}" - LOGOUT`); } diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index d8f7c997..1f124504 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1387,7 +1387,7 @@ export class WAStartupService { }, logger: P({ level: this.logBaileys }), printQRInTerminal: false, - browser: ['Chrome (Linux)', session.NAME, release()], + browser: number ? ['Chrome (Linux)', session.NAME, release()] : browser, version, markOnlineOnConnect: this.localSettings.always_online, retryRequestDelayMs: 10, @@ -1454,7 +1454,7 @@ export class WAStartupService { const { version } = await fetchLatestBaileysVersion(); const session = this.configService.get('CONFIG_SESSION_PHONE'); - // const browser: WABrowserDescription = [session.CLIENT, session.NAME, release()]; + const browser: WABrowserDescription = [session.CLIENT, session.NAME, release()]; let options; @@ -1474,7 +1474,7 @@ export class WAStartupService { }, logger: P({ level: this.logBaileys }), printQRInTerminal: false, - browser: ['Chrome (Linux)', session.NAME, release()], + browser: this.phoneNumber ? ['Chrome (Linux)', session.NAME, release()] : browser, version, markOnlineOnConnect: this.localSettings.always_online, retryRequestDelayMs: 10, From a00ad20c0834320197434cd4e32a090bff07c45d Mon Sep 17 00:00:00 2001 From: Gabriel Pastori <58153955+gabrielpastori1@users.noreply.github.com> Date: Tue, 19 Dec 2023 16:41:52 -0300 Subject: [PATCH 31/47] chatwoot agent available_name --- src/whatsapp/services/chatwoot.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 87f70219..ec8079f6 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1028,7 +1028,7 @@ export class ChatwootService { .replaceAll(/(? Date: Tue, 19 Dec 2023 22:28:50 +0200 Subject: [PATCH 32/47] fix: message retry --- package.json | 2 +- src/whatsapp/services/whatsapp.service.ts | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index f03144fe..0ca2d340 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "@figuro/chatwoot-sdk": "^1.1.16", "@hapi/boom": "^10.0.1", "@sentry/node": "^7.59.2", - "@whiskeysockets/baileys": "github:PurpShell/Baileys", + "@whiskeysockets/baileys": "github:PurpShell/Baileys#combined", "amqplib": "^0.10.3", "aws-sdk": "^2.1499.0", "axios": "^1.3.5", diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 1f124504..47118ccb 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -133,6 +133,9 @@ import { waMonitor } from '../whatsapp.module'; import { ChamaaiService } from './chamaai.service'; import { ChatwootService } from './chatwoot.service'; import { TypebotService } from './typebot.service'; + +const retryCache = {}; + export class WAStartupService { constructor( private readonly configService: ConfigService, @@ -2038,12 +2041,27 @@ export class WAStartupService { if (events['messages.upsert']) { this.logger.verbose('Listening event: messages.upsert'); const payload = events['messages.upsert']; + if (payload.messages.find(a => a?.messageStubType === 2)) { + const msg = payload.messages[0]; + retryCache[msg.key.id] = msg; + return; + } this.messageHandle['messages.upsert'](payload, database, settings); } if (events['messages.update']) { this.logger.verbose('Listening event: messages.update'); const payload = events['messages.update']; + payload.forEach(message => { + if (retryCache[message.key.id]) { + this.client.ev.emit("messages.upsert", { + messages: [message], + type: "notify" + }); + delete retryCache[message.key.id]; + return; + } + }) this.messageHandle['messages.update'](payload, database, settings); } From 244fe0835e24f0d41ffa43d74874efa70428b011 Mon Sep 17 00:00:00 2001 From: jaison-x Date: Tue, 19 Dec 2023 17:10:33 -0300 Subject: [PATCH 33/47] Update chatwoot.service.ts fix: message can be undefined --- src/whatsapp/services/chatwoot.service.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index a995f367..65db8359 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1204,9 +1204,10 @@ export class ChatwootService { } private updateChatwootMessageId(message: MessageRaw, chatwootMessageId: string, instance: InstanceDto) { - if (!chatwootMessageId) { + if (!chatwootMessageId || !message?.key?.id) { return; } + message.chatwootMessageId = chatwootMessageId; this.repository.message.update([message], instance.instanceName, true); } From 9363301d2ae038f9636b0609426b9302807e32f0 Mon Sep 17 00:00:00 2001 From: Gabriel Pastori <58153955+gabrielpastori1@users.noreply.github.com> Date: Tue, 19 Dec 2023 21:18:40 -0300 Subject: [PATCH 34/47] Add DISABLE_DOCS and DISABLE_MANAGER --- src/config/env.config.ts | 10 +++++++++- src/dev-env.yml | 3 +++ src/main.ts | 3 ++- src/whatsapp/routers/index.router.ts | 8 +++++--- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 45b8a5e1..511f4ebc 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -3,7 +3,13 @@ import { readFileSync } from 'fs'; import { load } from 'js-yaml'; import { join } from 'path'; -export type HttpServer = { TYPE: 'http' | 'https'; PORT: number; URL: string }; +export type HttpServer = { + TYPE: 'http' | 'https'; + PORT: number; + URL: string; + DISABLE_DOCS: boolean; + DISABLE_MANAGER: boolean; +}; export type HttpMethods = 'POST' | 'GET' | 'PUT' | 'DELETE'; export type Cors = { @@ -186,6 +192,8 @@ export class ConfigService { TYPE: (process.env.SERVER_TYPE as 'http' | 'https') || 'http', PORT: Number.parseInt(process.env.SERVER_PORT) || 8080, URL: process.env.SERVER_URL, + DISABLE_DOCS: process.env?.SERVER_DISABLE_DOCS === 'true', + DISABLE_MANAGER: process.env?.SERVER_DISABLE_MANAGER === 'true', }, CORS: { ORIGIN: process.env.CORS_ORIGIN.split(',') || ['*'], diff --git a/src/dev-env.yml b/src/dev-env.yml index 01a5927f..80c7e376 100644 --- a/src/dev-env.yml +++ b/src/dev-env.yml @@ -9,6 +9,9 @@ SERVER: TYPE: http # https PORT: 8080 # 443 URL: localhost + DISABLE_MANAGER: false + DISABLE_DOCS: false + CORS: ORIGIN: diff --git a/src/main.ts b/src/main.ts index 52bdd798..554d95e8 100644 --- a/src/main.ts +++ b/src/main.ts @@ -53,7 +53,8 @@ function bootstrap() { app.use('/store', express.static(join(ROOT_DIR, 'store'))); app.use('/', router); - app.use(swaggerRouter); + + if (!configService.get('SERVER').DISABLE_DOCS) app.use(swaggerRouter); app.use( (err: Error, req: Request, res: Response, next: NextFunction) => { diff --git a/src/whatsapp/routers/index.router.ts b/src/whatsapp/routers/index.router.ts index 781b528c..56b9301f 100644 --- a/src/whatsapp/routers/index.router.ts +++ b/src/whatsapp/routers/index.router.ts @@ -31,23 +31,25 @@ enum HttpStatus { const router = Router(); const authType = configService.get('AUTHENTICATION').TYPE; +const serverConfig = configService.get('SERVER'); const guards = [instanceExistsGuard, instanceLoggedGuard, authGuard[authType]]; const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8')); +if (!serverConfig.DISABLE_MANAGER) router.use('/manager', new ViewsRouter().router); + router .get('/', (req, res) => { res.status(HttpStatus.OK).json({ status: HttpStatus.OK, message: 'Welcome to the Evolution API, it is working!', version: packageJson.version, - swagger: `${req.protocol}://${req.get('host')}/docs`, + swagger: !serverConfig.DISABLE_DOCS ? `${req.protocol}://${req.get('host')}/docs` : undefined, + manager: !serverConfig.DISABLE_MANAGER ? `${req.protocol}://${req.get('host')}/manager` : undefined, documentation: `https://doc.evolution-api.com`, - manager: `${req.protocol}://${req.get('host')}/manager`, }); }) .use('/instance', new InstanceRouter(configService, ...guards).router) - .use('/manager', new ViewsRouter().router) .use('/message', new MessageRouter(...guards).router) .use('/chat', new ChatRouter(...guards).router) .use('/group', new GroupRouter(...guards).router) From 97b3f9b3c7583c4ac27bcdedceda03d3bb850383 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 20 Dec 2023 09:55:51 -0300 Subject: [PATCH 35/47] fix: Fix the problem when disconnecting the instance and connecting again using mongodb --- src/whatsapp/services/whatsapp.service.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 1f124504..5ad7e1e8 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1234,15 +1234,17 @@ export class WAStartupService { this.instance.wuid = this.client.user.id.replace(/:\d+/, ''); this.instance.profilePictureUrl = (await this.profilePicture(this.instance.wuid)).profilePictureUrl; const formattedWuid = this.instance.wuid.split('@')[0].padEnd(30, ' '); - const formattedName = this.instance.name.split('@')[0].padEnd(30, ' '); + const formattedName = this.instance.name; this.logger.info( ` ┌──────────────────────────────┐ │ CONNECTED TO WHATSAPP │ - │${formattedWuid}│ - │${formattedName}│ └──────────────────────────────┘`.replace(/^ +/gm, ' '), ); + this.logger.info(` + wuid: ${formattedWuid} + name: ${formattedName} + `); if (this.localChatwoot.enabled) { this.chatwootService.eventWhatsapp( From 060a945aea62efcdc11ac233dc8d543c95501dc0 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 20 Dec 2023 09:56:53 -0300 Subject: [PATCH 36/47] fix: Fix the problem when disconnecting the instance and connecting again using mongodb --- src/whatsapp/services/whatsapp.service.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 0ee46008..35c763bb 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -2043,7 +2043,7 @@ export class WAStartupService { if (events['messages.upsert']) { this.logger.verbose('Listening event: messages.upsert'); const payload = events['messages.upsert']; - if (payload.messages.find(a => a?.messageStubType === 2)) { + if (payload.messages.find((a) => a?.messageStubType === 2)) { const msg = payload.messages[0]; retryCache[msg.key.id] = msg; return; @@ -2054,16 +2054,16 @@ export class WAStartupService { if (events['messages.update']) { this.logger.verbose('Listening event: messages.update'); const payload = events['messages.update']; - payload.forEach(message => { + payload.forEach((message) => { if (retryCache[message.key.id]) { - this.client.ev.emit("messages.upsert", { + this.client.ev.emit('messages.upsert', { messages: [message], - type: "notify" + type: 'notify', }); delete retryCache[message.key.id]; return; } - }) + }); this.messageHandle['messages.update'](payload, database, settings); } From 1f657311650201f760b83f4a50f9153c91924b69 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 20 Dec 2023 10:03:44 -0300 Subject: [PATCH 37/47] fix: Add options to disable docs and manager --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b62084d..f6e5b396 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ * Fixed the pairing code * Adjusts in typebot * Fix the problem when disconnecting the instance and connecting again using mongodb +* Options to disable docs and manager # 1.6.0 (2023-12-12 17:24) From be026103499650dae8bfdfef74dbc502c7c9d3d9 Mon Sep 17 00:00:00 2001 From: Eduardo Chaves Date: Wed, 20 Dec 2023 10:29:32 -0300 Subject: [PATCH 38/47] Renamed .env to .env.example --- Docker/evolution-api-all-services/{.env => .env.example} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Docker/evolution-api-all-services/{.env => .env.example} (100%) diff --git a/Docker/evolution-api-all-services/.env b/Docker/evolution-api-all-services/.env.example similarity index 100% rename from Docker/evolution-api-all-services/.env rename to Docker/evolution-api-all-services/.env.example From edaa4aff7e0ff8d78a91ae869750b5467db5b562 Mon Sep 17 00:00:00 2001 From: Eduardo Chaves Date: Wed, 20 Dec 2023 10:31:14 -0300 Subject: [PATCH 39/47] Add any .env file to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 2364b077..c55eb628 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ docker-compose.yaml /test/ /src/env.yml /store +*.env /temp/* From a87b7531514b8d9202370c6d75dd65cfa62721cc Mon Sep 17 00:00:00 2001 From: Gabriel Pastori <58153955+gabrielpastori1@users.noreply.github.com> Date: Tue, 19 Dec 2023 20:01:30 -0300 Subject: [PATCH 40/47] Update issue templates --- .github/ISSUE_TEMPLATE/-en--bug-report.md | 38 +++++++++++++++++++ .../ISSUE_TEMPLATE/-en--feature-request.md | 28 ++++++++++++++ .github/ISSUE_TEMPLATE/-pt--reportar-bug.md | 38 +++++++++++++++++++ .../ISSUE_TEMPLATE/-pt--solicitar-recurso.md | 28 ++++++++++++++ 4 files changed, 132 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/-en--bug-report.md create mode 100644 .github/ISSUE_TEMPLATE/-en--feature-request.md create mode 100644 .github/ISSUE_TEMPLATE/-pt--reportar-bug.md create mode 100644 .github/ISSUE_TEMPLATE/-pt--solicitar-recurso.md diff --git a/.github/ISSUE_TEMPLATE/-en--bug-report.md b/.github/ISSUE_TEMPLATE/-en--bug-report.md new file mode 100644 index 00000000..52579cb2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/-en--bug-report.md @@ -0,0 +1,38 @@ +--- +name: "[EN] Bug report" +about: Create a report to help us improve +title: "[EN][BUG]" +labels: bug +assignees: '' + +--- + +### Title: [Brief Description of the Bug] + +#### Description: +Describe in detail the problem you encountered. Include any relevant context that may help understand the origin of the bug. + +#### Steps to Reproduce: +1. List the steps necessary to reproduce the problem. +2. Try to be as specific as possible. +3. If the problem occurs in a specific scenario, describe it here. + +#### Expected Behavior: +Describe what you expected to happen when following the steps above. + +#### Current Behavior: +Explain what actually happens when you follow the steps above. + +#### Screenshots/Videos: +If possible, add screenshots or videos illustrating the problem. This can be extremely helpful in understanding the issue. + +#### Environment: +- **Server:** [e.g., Ubuntu 18.04] +- **API Version:** [e.g., 1.5.4] +- **Other Hardware/Software Specifications:** [e.g., CPU, GPU] + +#### Submitting Logs: +Please attach logs that may be related to the problem. If the logs contain sensitive information, consider sending them privately to one of the project maintainers. + +#### Additional Notes: +Include here any other information that you think might be useful in understanding or resolving the bug. diff --git a/.github/ISSUE_TEMPLATE/-en--feature-request.md b/.github/ISSUE_TEMPLATE/-en--feature-request.md new file mode 100644 index 00000000..df7959c6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/-en--feature-request.md @@ -0,0 +1,28 @@ +--- +name: "[EN] Feature request" +about: Suggest an idea for the API +title: "[EN][FEAT]" +labels: enhancement +assignees: '' + +--- + +### Title: [Brief Description of Feature Request] + +#### Detailed Description: +Clearly and in detail, describe the functionality you wish to be implemented. Explain how this fits into the context of the project. + +#### Rationale: +Explain why this functionality would be useful for the project. This helps in understanding the importance and priority of the request. + +#### Usage Examples: +Provide specific examples of how this feature could be used. This can include scenarios or use cases where the feature would be particularly beneficial. + +#### Possible Implementations: +If you have ideas on how this feature might be implemented, please share them here. This is not mandatory but can be helpful for the development team. + +#### Impact on the Project: +Discuss how this new feature could impact other parts of the project, if applicable. + +#### Additional Notes: +Any other information you believe is relevant to your request. diff --git a/.github/ISSUE_TEMPLATE/-pt--reportar-bug.md b/.github/ISSUE_TEMPLATE/-pt--reportar-bug.md new file mode 100644 index 00000000..7c99f991 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/-pt--reportar-bug.md @@ -0,0 +1,38 @@ +--- +name: "[PT] Reportar bug" +about: Reportar um problema +title: "[PT][BUG]" +labels: bug +assignees: '' + +--- + +### Título: [Breve Descrição do Bug] + +#### Descrição: +Descreva detalhadamente o problema que você encontrou. Inclua qualquer contexto relevante que possa ajudar a entender a origem do bug. + +#### Passos para Reproduzir: +1. Liste os passos necessários para reproduzir o problema. +2. Tente ser o mais específico possível. +3. Se o problema ocorrer em um cenário específico, descreva-o aqui. + +#### Comportamento Esperado: +Descreva o que você esperava que acontecesse quando seguisse os passos acima. + +#### Comportamento Atual: +Explique o que realmente acontece quando você segue os passos acima. + +#### Capturas de Tela/Vídeos: +Se possível, adicione capturas de tela ou vídeos que ilustrem o problema. Isso pode ser extremamente útil para entender o problema. + +#### Ambiente: +- **Servidor:** [ex: Ubuntu 18.04] +- **Versão da API:** [ex: 1.5.4] +- **Outras Especificações de Hardware/Software:** [ex: CPU, GPU] + +#### Envio de Logs: +Por favor, anexe os logs que possam estar relacionados ao problema. Se os logs contiverem informações sensíveis, considere enviá-los de forma privada para um dos mantenedores do projeto. + +#### Notas Adicionais: +Inclua aqui qualquer outra informação que você ache que possa ser útil para entender ou resolver o bug. diff --git a/.github/ISSUE_TEMPLATE/-pt--solicitar-recurso.md b/.github/ISSUE_TEMPLATE/-pt--solicitar-recurso.md new file mode 100644 index 00000000..900389fd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/-pt--solicitar-recurso.md @@ -0,0 +1,28 @@ +--- +name: "[PT] Solicitar recurso" +about: Sugira novos recursos para a API +title: "[PT][FEAT]" +labels: enhancement +assignees: '' + +--- + +### Título: [Breve Descrição da Solicitação de Recurso] + +#### Descrição Detalhada: +Descreva claramente e em detalhes a funcionalidade que você deseja que seja implementada. Explique como isso se encaixa no contexto do projeto. + +#### Racional: +Explique por que essa funcionalidade seria útil para o projeto. Isso ajuda a entender a importância e a prioridade da solicitação. + +#### Exemplos de Uso: +Forneça exemplos específicos de como essa funcionalidade poderia ser utilizada. Isso pode incluir cenários ou casos de uso onde a funcionalidade seria particularmente benéfica. + +#### Possíveis Implementações: +Se você tem ideias sobre como essa funcionalidade pode ser implementada, por favor, compartilhe-as aqui. Isso não é obrigatório, mas pode ser útil para a equipe de desenvolvimento. + +#### Impacto no Projeto: +Discuta como essa nova funcionalidade poderia impactar outras partes do projeto, se aplicável. + +#### Notas Adicionais: +Qualquer outra informação que você acredita ser relevante para a sua solicitação. From 07e8449379ab12adc47f623b30e80adfa52d63cb Mon Sep 17 00:00:00 2001 From: jaison-x Date: Wed, 20 Dec 2023 17:53:37 -0300 Subject: [PATCH 41/47] fix: when deleting a message in whatsapp, delete the message in chatwoot too The message model schema was changed. Old format in message model was field chatwootMessageId. Now we have a document chatwoot with new properties. I cant find a simple way to create a migration function up then the old field was no migrate to new format. --- src/whatsapp/models/message.model.ts | 16 +++- src/whatsapp/repository/message.repository.ts | 10 ++- src/whatsapp/services/chatwoot.service.ts | 78 ++++++++++++++----- src/whatsapp/services/whatsapp.service.ts | 22 +++++- 4 files changed, 100 insertions(+), 26 deletions(-) diff --git a/src/whatsapp/models/message.model.ts b/src/whatsapp/models/message.model.ts index 395b100b..2b59f3a5 100644 --- a/src/whatsapp/models/message.model.ts +++ b/src/whatsapp/models/message.model.ts @@ -10,6 +10,12 @@ class Key { participant?: string; } +class ChatwootMessage { + messageId?: number; + inboxId?: number; + conversationId?: number; +} + export class MessageRaw { _id?: string; key?: Key; @@ -22,7 +28,7 @@ export class MessageRaw { source?: 'android' | 'web' | 'ios'; source_id?: string; source_reply_id?: string; - chatwootMessageId?: string; + chatwoot?: ChatwootMessage; } const messageSchema = new Schema({ @@ -40,10 +46,14 @@ const messageSchema = new Schema({ source: { type: String, minlength: 3, enum: ['android', 'web', 'ios'] }, messageTimestamp: { type: Number, required: true }, owner: { type: String, required: true, minlength: 1 }, - chatwootMessageId: { type: String, required: false }, + chatwoot: { + messageId: { type: Number }, + inboxId: { type: Number }, + conversationId: { type: Number }, + }, }); -messageSchema.index({ chatwootMessageId: 1, owner: 1 }); +messageSchema.index({ 'chatwoot.messageId': 1, owner: 1 }); messageSchema.index({ 'key.id': 1 }); messageSchema.index({ 'key.id': 1, owner: 1 }); messageSchema.index({ owner: 1 }); diff --git a/src/whatsapp/repository/message.repository.ts b/src/whatsapp/repository/message.repository.ts index e212ca3d..d7675977 100644 --- a/src/whatsapp/repository/message.repository.ts +++ b/src/whatsapp/repository/message.repository.ts @@ -91,11 +91,13 @@ export class MessageRepository extends Repository { this.logger.verbose('finding messages'); if (this.dbSettings.ENABLED) { this.logger.verbose('finding messages in db'); - if (query?.where?.key) { - for (const [k, v] of Object.entries(query.where.key)) { - query.where['key.' + k] = v; + for (const [o, p] of Object.entries(query?.where)) { + if (typeof p === 'object' && p !== null && !Array.isArray(p)) { + for (const [k, v] of Object.entries(p)) { + query.where[`${o}.${k}`] = v; + } + delete query.where[o]; } - delete query?.where?.key; } return await this.messageModel diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index ccd01347..26b0cce9 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -14,6 +14,7 @@ import { InstanceDto } from '../dto/instance.dto'; import { Options, Quoted, SendAudioDto, SendMediaDto, SendTextDto } from '../dto/sendMessage.dto'; import { MessageRaw } from '../models'; import { RepositoryBroker } from '../repository/repository.manager'; +import { Events } from '../types/wa.types'; import { WAMonitoringService } from './monitor.service'; export class ChatwootService { @@ -1036,7 +1037,9 @@ export class ChatwootService { const message = await this.repository.message.find({ where: { owner: instance.instanceName, - chatwootMessageId: body.id, + chatwoot: { + messageId: body.id, + }, }, limit: 1, }); @@ -1160,7 +1163,11 @@ export class ChatwootService { ...messageSent, owner: instance.instanceName, }, - body.id, + { + messageId: body.id, + inboxId: body.inbox?.id, + conversationId: body.conversation?.id, + }, instance, ); } @@ -1187,7 +1194,11 @@ export class ChatwootService { ...messageSent, owner: instance.instanceName, }, - body.id, + { + messageId: body.id, + inboxId: body.inbox?.id, + conversationId: body.conversation?.id, + }, instance, ); } @@ -1221,15 +1232,33 @@ export class ChatwootService { } } - private updateChatwootMessageId(message: MessageRaw, chatwootMessageId: string, instance: InstanceDto) { - if (!chatwootMessageId || !message?.key?.id) { + private updateChatwootMessageId( + message: MessageRaw, + chatwootMessageIds: MessageRaw['chatwoot'], + instance: InstanceDto, + ) { + if (!chatwootMessageIds.messageId || !message?.key?.id) { return; } - message.chatwootMessageId = chatwootMessageId; + message.chatwoot = chatwootMessageIds; this.repository.message.update([message], instance.instanceName, true); } + private async getMessageByKeyId(instance: InstanceDto, keyId: string): Promise { + const messages = await this.repository.message.find({ + where: { + key: { + id: keyId, + }, + owner: instance.instanceName, + }, + limit: 1, + }); + + return messages.length ? messages[0] : null; + } + private async getReplyToIds( msg: any, instance: InstanceDto, @@ -1240,17 +1269,9 @@ export class ChatwootService { if (msg) { inReplyToExternalId = msg.message?.extendedTextMessage?.contextInfo?.stanzaId; if (inReplyToExternalId) { - const message = await this.repository.message.find({ - where: { - key: { - id: inReplyToExternalId, - }, - owner: instance.instanceName, - }, - limit: 1, - }); - if (message.length && message[0]?.chatwootMessageId) { - inReplyTo = message[0].chatwootMessageId; + const message = await this.getMessageByKeyId(instance, inReplyToExternalId); + if (message?.chatwoot?.messageId) { + inReplyTo = message.chatwoot.messageId; } } } @@ -1265,7 +1286,9 @@ export class ChatwootService { if (msg?.content_attributes?.in_reply_to) { const message = await this.repository.message.find({ where: { - chatwootMessageId: msg?.content_attributes?.in_reply_to, + chatwoot: { + messageId: msg?.content_attributes?.in_reply_to, + }, owner: instance.instanceName, }, limit: 1, @@ -1757,6 +1780,25 @@ export class ChatwootService { } } + if (event === Events.MESSAGES_DELETE) { + this.logger.verbose('deleting message from instance: ' + instance.instanceName); + + if (!body?.key?.id) { + this.logger.warn('message id not found'); + return; + } + + const message = await this.getMessageByKeyId(instance, body.key.id); + if (message?.chatwoot?.messageId && message?.chatwoot?.conversationId) { + this.logger.verbose('deleting message in chatwoot. Message id: ' + body.key.id); + return await client.messages.delete({ + accountId: this.provider.account_id, + conversationId: message.chatwoot.conversationId, + messageId: message.chatwoot.messageId, + }); + } + } + if (event === 'status.instance') { this.logger.verbose('event status.instance'); const data = body; diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 35c763bb..1e1d5b88 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1798,7 +1798,11 @@ export class WAStartupService { ); if (chatwootSentMessage?.id) { - messageRaw.chatwootMessageId = chatwootSentMessage.id; + messageRaw.chatwoot = { + messageId: chatwootSentMessage.id, + inboxId: chatwootSentMessage.inbox_id, + conversationId: chatwootSentMessage.conversation_id, + }; } } @@ -1941,6 +1945,22 @@ export class WAStartupService { this.instance.name, database.SAVE_DATA.MESSAGE_UPDATE, ); + + if (this.localChatwoot.enabled) { + this.chatwootService.eventWhatsapp( + Events.MESSAGES_DELETE, + { instanceName: this.instance.name }, + { + key: { + remoteJid: key.remoteJid, + fromMe: key.fromMe, + id: key.id, + participant: key.participant, + }, + }, + ); + } + return; } From 89a37a1771397556de1b875eed01512d959def37 Mon Sep 17 00:00:00 2001 From: jaison-x Date: Wed, 20 Dec 2023 18:11:41 -0300 Subject: [PATCH 42/47] fix: show message `Connection successfully established` after a sucessfull connection on chatwoot --- src/whatsapp/services/whatsapp.service.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 1e1d5b88..4fd79e4d 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -265,6 +265,7 @@ export class WAStartupService { pairingCode: this.instance.qrcode?.pairingCode, code: this.instance.qrcode?.code, base64: this.instance.qrcode?.base64, + count: this.instance.qrcode?.count, }; } From 2c0b6293027070b33e4cde04262e1eff9b1e93f7 Mon Sep 17 00:00:00 2001 From: jaison-x Date: Thu, 21 Dec 2023 00:23:33 -0300 Subject: [PATCH 43/47] Update whatsapp.service.ts --- src/whatsapp/services/whatsapp.service.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 4fd79e4d..f222d5b7 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1951,14 +1951,7 @@ export class WAStartupService { this.chatwootService.eventWhatsapp( Events.MESSAGES_DELETE, { instanceName: this.instance.name }, - { - key: { - remoteJid: key.remoteJid, - fromMe: key.fromMe, - id: key.id, - participant: key.participant, - }, - }, + { key: key }, ); } From a44cd0373e984dca6aa6d5750bbb9fa43620849b Mon Sep 17 00:00:00 2001 From: jaison-x Date: Thu, 21 Dec 2023 07:42:33 -0300 Subject: [PATCH 44/47] fix: simple adjust in key object --- src/whatsapp/services/whatsapp.service.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 4fd79e4d..f222d5b7 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1951,14 +1951,7 @@ export class WAStartupService { this.chatwootService.eventWhatsapp( Events.MESSAGES_DELETE, { instanceName: this.instance.name }, - { - key: { - remoteJid: key.remoteJid, - fromMe: key.fromMe, - id: key.id, - participant: key.participant, - }, - }, + { key: key }, ); } From 9128b1f47ddeafae3ffc15424d886d5f9ceb073e Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 22 Dec 2023 11:43:03 -0300 Subject: [PATCH 45/47] fix: when deleting a message in whatsapp, delete the message in chatwoot too --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0ca2d340..b8c413eb 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "cross-env": "^7.0.3", "dayjs": "^1.11.7", "eventemitter2": "^6.4.9", - "evolution-manager": "^0.4.8", + "evolution-manager": "^0.4.11", "exiftool-vendored": "^22.0.0", "express": "^4.18.2", "express-async-errors": "^3.1.1", From dc5dae04ebe81cadcd11f6945a92f09492dc3f62 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 22 Dec 2023 11:43:10 -0300 Subject: [PATCH 46/47] fix: when deleting a message in whatsapp, delete the message in chatwoot too --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6e5b396..29b9cb62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ * Adjusts in typebot * Fix the problem when disconnecting the instance and connecting again using mongodb * Options to disable docs and manager +* When deleting a message in whatsapp, delete the message in chatwoot too # 1.6.0 (2023-12-12 17:24) From 3e358e5d26c92125aece2be15d802270fdb0492b Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 22 Dec 2023 11:43:58 -0300 Subject: [PATCH 47/47] version: 1.6.1 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29b9cb62..1f7f016d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 1.6.1 (develop) +# 1.6.1 (2023-12-22 11:43) ### Fixed