From cf89601269af86a664043e3d8360ae1294d2d216 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 17 Dec 2023 06:59:05 -0300 Subject: [PATCH 1/5] 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 2/5] 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 3/5] 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 4/5] 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 5/5] 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`); }