From 6d3e1b0cbea70cb2e799bb9cfb1339a2be043a16 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 16 Jul 2023 15:01:38 -0300 Subject: [PATCH 01/48] fix: Fixed error to send message in large groups --- 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 027a97df..6d845dc9 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -741,6 +741,7 @@ export class WAStartupService { version, connectTimeoutMs: 60_000, qrTimeout: 40_000, + defaultQueryTimeoutMs: undefined, emitOwnEvents: false, msgRetryCounterCache: this.msgRetryCounterCache, getMessage: async (key) => From 64e19699fb31a5a0a809a1039adf86b0514db1de Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 16 Jul 2023 15:05:02 -0300 Subject: [PATCH 02/48] fix: Docker files adjusted --- CHANGELOG.md | 7 +++++++ Docker/mongodb/docker-compose.yaml | 3 ++- Docker/redis/docker-compose.yaml | 3 ++- docker-compose-full.yaml | 3 ++- docker-compose.yaml | 3 ++- start.sh | 1 + 6 files changed, 16 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0afab659..aa07c370 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# 1.2.3 (homolog) + +# Fixed + +* Fixed error to send message in large groups +* Docker files adjusted + # 1.2.2 (2023-07-15 09:36) ### Fixed diff --git a/Docker/mongodb/docker-compose.yaml b/Docker/mongodb/docker-compose.yaml index 957db3ea..896887ea 100644 --- a/Docker/mongodb/docker-compose.yaml +++ b/Docker/mongodb/docker-compose.yaml @@ -39,5 +39,6 @@ volumes: networks: default: - name: evolution-net + external: + name: evolution-net \ No newline at end of file diff --git a/Docker/redis/docker-compose.yaml b/Docker/redis/docker-compose.yaml index 753bb9cb..54828e7f 100644 --- a/Docker/redis/docker-compose.yaml +++ b/Docker/redis/docker-compose.yaml @@ -25,4 +25,5 @@ volumes: networks: default: - name: evolution-net + external: + name: evolution-net diff --git a/docker-compose-full.yaml b/docker-compose-full.yaml index 7c5036da..9b108101 100644 --- a/docker-compose-full.yaml +++ b/docker-compose-full.yaml @@ -68,5 +68,6 @@ volumes: networks: default: - name: evolution-net + external: + name: evolution-net \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index c62e6ff4..8962763f 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -22,5 +22,6 @@ volumes: networks: default: - name: evolution-net + external: + name: evolution-net \ No newline at end of file diff --git a/start.sh b/start.sh index d716d558..06a55e4a 100755 --- a/start.sh +++ b/start.sh @@ -6,6 +6,7 @@ then echo "DOCKER_ENV=$DOCKER_ENV" echo else + mkdir -p ./dist/src cp ./src/env.yml ./dist/src fi echo "> removing dist" From ec7ad704588a3650ed92b0865b870be7f1e804d2 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 16 Jul 2023 17:38:01 -0300 Subject: [PATCH 03/48] fix: Now it's getting the API URL directly in the request, no longer need the variable in the env file --- CHANGELOG.md | 2 + Docker/mongodb/docker-compose.yaml | 2 - package.json | 2 +- src/whatsapp/abstract/abstract.router.ts | 4 -- .../controllers/instance.controller.ts | 47 +++++++++++++------ src/whatsapp/models/webhook.model.ts | 1 + src/whatsapp/routers/instance.router.ts | 6 ++- 7 files changed, 42 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa07c370..007e3233 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ * Fixed error to send message in large groups * Docker files adjusted +* Fixed in the postman collection the webhookByEvent parameter by webhook_by_events +* Now it's getting the API URL directly in the request, no longer need the variable in the env file # 1.2.2 (2023-07-15 09:36) diff --git a/Docker/mongodb/docker-compose.yaml b/Docker/mongodb/docker-compose.yaml index 896887ea..86892877 100644 --- a/Docker/mongodb/docker-compose.yaml +++ b/Docker/mongodb/docker-compose.yaml @@ -15,8 +15,6 @@ services: volumes: - evolution_mongodb_data:/data/db - evolution_mongodb_configdb:/data/configdb - networks: - - evolution-net expose: - 27017 diff --git a/package.json b/package.json index 1f313a5c..87f5f908 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.2.2", + "version": "1.2.3", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": { diff --git a/src/whatsapp/abstract/abstract.router.ts b/src/whatsapp/abstract/abstract.router.ts index e657c2c0..cb224cd6 100644 --- a/src/whatsapp/abstract/abstract.router.ts +++ b/src/whatsapp/abstract/abstract.router.ts @@ -160,8 +160,6 @@ export abstract class RouterBroker { const v = validate(ref, schema); - console.log(v, '@checkei aqui'); - if (!v.valid) { const message: any[] = v.errors.map(({ property, stack, schema }) => { let message: string; @@ -203,8 +201,6 @@ export abstract class RouterBroker { const v = validate(ref, schema); - console.log(v, '@checkei aqui'); - if (!v.valid) { const message: any[] = v.errors.map(({ property, stack, schema }) => { let message: string; diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index a2b432e5..4145acef 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -12,6 +12,7 @@ import { ChatwootService } from '../services/chatwoot.service'; import { Logger } from '../../config/logger.config'; import { wa } from '../types/wa.types'; import { RedisCache } from '../../db/redis.client'; +import { isURL } from 'class-validator'; export class InstanceController { constructor( @@ -27,18 +28,21 @@ export class InstanceController { private readonly logger = new Logger(InstanceController.name); - public async createInstance({ - instanceName, - webhook, - webhook_by_events, - events, - qrcode, - token, - chatwoot_account_id, - chatwoot_token, - chatwoot_url, - chatwoot_sign_msg, - }: InstanceDto) { + public async createInstance( + { + instanceName, + webhook, + webhook_by_events, + events, + qrcode, + token, + chatwoot_account_id, + chatwoot_token, + chatwoot_url, + chatwoot_sign_msg, + }: InstanceDto, + apiURL: string, + ) { this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); const mode = this.configService.get('AUTHENTICATION').INSTANCE.MODE; @@ -82,6 +86,9 @@ export class InstanceController { let getEvents: string[]; if (webhook) { + if (!isURL(webhook, { require_tld: false })) { + throw new BadRequestException('Invalid "url" property in webhook'); + } this.logger.verbose('creating webhook'); try { this.webhookService.create(instance, { @@ -132,7 +139,11 @@ export class InstanceController { throw new BadRequestException('url is required'); } - const urlServer = this.configService.get('SERVER').URL; + if (!isURL(chatwoot_url, { require_tld: false })) { + throw new BadRequestException('Invalid "url" property in chatwoot'); + } + + const urlServer = apiURL; try { this.chatwootService.create(instance, { @@ -203,6 +214,10 @@ export class InstanceController { let getEvents: string[]; if (webhook) { + if (!isURL(webhook, { require_tld: false })) { + throw new BadRequestException('Invalid "url" property in webhook'); + } + this.logger.verbose('creating webhook'); try { this.webhookService.create(instance, { @@ -266,7 +281,11 @@ export class InstanceController { throw new BadRequestException('url is required'); } - const urlServer = this.configService.get('SERVER').URL; + if (!isURL(chatwoot_url, { require_tld: false })) { + throw new BadRequestException('Invalid "url" property in chatwoot'); + } + + const urlServer = apiURL; try { this.chatwootService.create(instance, { diff --git a/src/whatsapp/models/webhook.model.ts b/src/whatsapp/models/webhook.model.ts index 873491bf..62ee38f4 100644 --- a/src/whatsapp/models/webhook.model.ts +++ b/src/whatsapp/models/webhook.model.ts @@ -14,6 +14,7 @@ const webhookSchema = new Schema({ url: { type: String, required: true }, enabled: { type: Boolean, required: true }, events: { type: [String], required: true }, + webhook_by_events: { type: Boolean, required: true }, }); export const WebhookModel = dbserver?.model(WebhookRaw.name, webhookSchema, 'webhook'); diff --git a/src/whatsapp/routers/instance.router.ts b/src/whatsapp/routers/instance.router.ts index 799c8249..7dc35d30 100644 --- a/src/whatsapp/routers/instance.router.ts +++ b/src/whatsapp/routers/instance.router.ts @@ -23,11 +23,15 @@ export class InstanceRouter extends RouterBroker { logger.verbose('request query: '); logger.verbose(req.query); + + const apiURL = req.headers.host || req.hostname; + logger.verbose('API URL: ' + apiURL); + const response = await this.dataValidate({ request: req, schema: instanceNameSchema, ClassRef: InstanceDto, - execute: (instance) => instanceController.createInstance(instance), + execute: (instance) => instanceController.createInstance(instance, apiURL), }); return res.status(HttpStatus.CREATED).json(response); From b9eb8d45b24b7efd15634edd5916b5a530b19f79 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 16 Jul 2023 17:57:37 -0300 Subject: [PATCH 04/48] fix: removed link preview endpoint, now it's done automatically from sending conventional text --- CHANGELOG.md | 1 + src/validate/validate.schema.ts | 18 ------------- .../controllers/sendMessage.controller.ts | 5 ---- src/whatsapp/dto/sendMessage.dto.ts | 8 ------ src/whatsapp/routers/sendMessage.router.ts | 19 -------------- src/whatsapp/services/whatsapp.service.ts | 25 ++++--------------- 6 files changed, 6 insertions(+), 70 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 007e3233..a044499c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Docker files adjusted * Fixed in the postman collection the webhookByEvent parameter by webhook_by_events * Now it's getting the API URL directly in the request, no longer need the variable in the env file +* Removed link preview endpoint, now it's done automatically from sending conventional text # 1.2.2 (2023-07-15 09:36) diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 1fbb331e..21d206d6 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -144,24 +144,6 @@ export const textMessageSchema: JSONSchema7 = { required: ['textMessage', 'number'], }; -export const linkPreviewSchema: JSONSchema7 = { - $id: v4(), - type: 'object', - properties: { - number: { ...numberDefinition }, - options: { ...optionsSchema }, - linkPreview: { - type: 'object', - properties: { - text: { type: 'string' }, - }, - required: ['text'], - ...isNotEmpty('text'), - }, - }, - required: ['linkPreview', 'number'], -}; - export const pollMessageSchema: JSONSchema7 = { $id: v4(), type: 'object', diff --git a/src/whatsapp/controllers/sendMessage.controller.ts b/src/whatsapp/controllers/sendMessage.controller.ts index c2d5298c..86dc6dca 100644 --- a/src/whatsapp/controllers/sendMessage.controller.ts +++ b/src/whatsapp/controllers/sendMessage.controller.ts @@ -119,9 +119,4 @@ export class SendMessageController { logger.verbose('requested sendStatus from ' + instanceName + ' instance'); return await this.waMonitor.waInstances[instanceName].statusMessage(data); } - - public async sendLinkPreview({ instanceName }: InstanceDto, data: SendLinkPreviewDto) { - logger.verbose('requested sendLinkPreview from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].linkPreview(data); - } } diff --git a/src/whatsapp/dto/sendMessage.dto.ts b/src/whatsapp/dto/sendMessage.dto.ts index 4f1ff88b..51a55cec 100644 --- a/src/whatsapp/dto/sendMessage.dto.ts +++ b/src/whatsapp/dto/sendMessage.dto.ts @@ -28,10 +28,6 @@ class TextMessage { text: string; } -class linkPreviewMessage { - text: string; -} - export class StatusMessage { type: string; content: string; @@ -52,10 +48,6 @@ export class SendTextDto extends Metadata { textMessage: TextMessage; } -export class SendLinkPreviewDto extends Metadata { - linkPreview: linkPreviewMessage; -} - export class SendStatusDto extends Metadata { statusMessage: StatusMessage; } diff --git a/src/whatsapp/routers/sendMessage.router.ts b/src/whatsapp/routers/sendMessage.router.ts index d8d3acea..f6f9c3eb 100644 --- a/src/whatsapp/routers/sendMessage.router.ts +++ b/src/whatsapp/routers/sendMessage.router.ts @@ -3,7 +3,6 @@ import { audioMessageSchema, buttonMessageSchema, contactMessageSchema, - linkPreviewSchema, listMessageSchema, locationMessageSchema, mediaMessageSchema, @@ -17,7 +16,6 @@ import { SendAudioDto, SendButtonDto, SendContactDto, - SendLinkPreviewDto, SendListDto, SendLocationDto, SendMediaDto, @@ -199,23 +197,6 @@ export class MessageRouter extends RouterBroker { return res.status(HttpStatus.CREATED).json(response); }) - .post(this.routerPath('sendLinkPreview'), ...guards, async (req, res) => { - logger.verbose('request received in sendLinkPreview'); - logger.verbose('request body: '); - logger.verbose(req.body); - - logger.verbose('request query: '); - logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: linkPreviewSchema, - ClassRef: SendLinkPreviewDto, - execute: (instance, data) => - sendMessageController.sendLinkPreview(instance, data), - }); - - return res.status(HttpStatus.CREATED).json(response); - }) .post(this.routerPath('sendSticker'), ...guards, async (req, res) => { logger.verbose('request received in sendSticker'); logger.verbose('request body: '); diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 6d845dc9..f7f9d7f6 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -76,7 +76,6 @@ import { SendReactionDto, SendTextDto, SendPollDto, - SendLinkPreviewDto, SendStickerDto, SendStatusDto, StatusMessage, @@ -1476,8 +1475,8 @@ export class WAStartupService { if ( !message['audio'] && !message['poll'] && - !message['linkPreview'] && !message['sticker'] && + !message['conversation'] && !sender.includes('@broadcast') ) { if (!message['audio']) { @@ -1496,12 +1495,13 @@ export class WAStartupService { } } - if (message['linkPreview']) { + if (message['conversation']) { + console.log(message['conversation']); this.logger.verbose('Sending message'); return await this.client.sendMessage( sender, { - text: message['linkPreview'].text, + text: message['conversation'], } as unknown as AnyMessageContent, option as unknown as MiscMessageGenerationOptions, ); @@ -1583,19 +1583,6 @@ export class WAStartupService { ); } - public async linkPreview(data: SendLinkPreviewDto) { - this.logger.verbose('Sending link preview'); - return await this.sendMessageWithTyping( - data.number, - { - linkPreview: { - text: data.linkPreview.text, - }, - }, - data?.options, - ); - } - public async pollMessage(data: SendPollDto) { this.logger.verbose('Sending poll message'); return await this.sendMessageWithTyping( @@ -2646,9 +2633,7 @@ export class WAStartupService { const msg = `${description}\n\n${inviteUrl}`; const message = { - linkPreview: { - text: msg, - }, + conversation: msg, }; for await (const number of numbers) { From c00f13214542f28422cc12a1255a3b55b90ed1c9 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 16 Jul 2023 18:01:43 -0300 Subject: [PATCH 05/48] fix: Added group membership validation before sending message to groups --- CHANGELOG.md | 1 + src/whatsapp/controllers/sendMessage.controller.ts | 1 - src/whatsapp/services/whatsapp.service.ts | 7 ++++++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a044499c..633373c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * Fixed in the postman collection the webhookByEvent parameter by webhook_by_events * Now it's getting the API URL directly in the request, no longer need the variable in the env file * Removed link preview endpoint, now it's done automatically from sending conventional text +* Added group membership validation before sending message to groups # 1.2.2 (2023-07-15 09:36) diff --git a/src/whatsapp/controllers/sendMessage.controller.ts b/src/whatsapp/controllers/sendMessage.controller.ts index 86dc6dca..e80cbfcf 100644 --- a/src/whatsapp/controllers/sendMessage.controller.ts +++ b/src/whatsapp/controllers/sendMessage.controller.ts @@ -5,7 +5,6 @@ import { SendAudioDto, SendButtonDto, SendContactDto, - SendLinkPreviewDto, SendListDto, SendLocationDto, SendMediaDto, diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index f7f9d7f6..a10c6223 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1434,6 +1434,12 @@ export class WAStartupService { let mentions: string[]; if (isJidGroup(sender)) { try { + const groupMetadata = await this.client.groupMetadata(sender); + + if (!groupMetadata) { + throw new NotFoundException('Group not found'); + } + if (options?.mentions) { this.logger.verbose('Mentions defined'); @@ -1448,7 +1454,6 @@ export class WAStartupService { this.logger.verbose('Mentions everyone'); this.logger.verbose('Getting group metadata'); - const groupMetadata = await this.client.groupMetadata(sender); mentions = groupMetadata.participants.map((participant) => participant.id); this.logger.verbose('Getting group metadata for mentions'); } else { From e6b0addb6caa31e29e11d496e51f02175b0901df Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 16 Jul 2023 18:16:05 -0300 Subject: [PATCH 06/48] feat: added messages.delete event --- CHANGELOG.md | 1 + Docker/.env.example | 1 + Dockerfile | 1 + src/config/env.config.ts | 2 ++ src/dev-env.yml | 1 + src/validate/validate.schema.ts | 2 ++ src/whatsapp/services/whatsapp.service.ts | 17 ++++++++++++----- src/whatsapp/types/wa.types.ts | 1 + 8 files changed, 21 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 633373c0..32b2bb26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Now it's getting the API URL directly in the request, no longer need the variable in the env file * Removed link preview endpoint, now it's done automatically from sending conventional text * Added group membership validation before sending message to groups +* Added messages.delete event # 1.2.2 (2023-07-15 09:36) diff --git a/Docker/.env.example b/Docker/.env.example index f4e665aa..3c0bfb9e 100644 --- a/Docker/.env.example +++ b/Docker/.env.example @@ -55,6 +55,7 @@ WEBHOOK_EVENTS_QRCODE_UPDATED=true WEBHOOK_EVENTS_MESSAGES_SET=true WEBHOOK_EVENTS_MESSAGES_UPSERT=true WEBHOOK_EVENTS_MESSAGES_UPDATE=true +WEBHOOK_EVENTS_MESSAGES_DELETE=true WEBHOOK_EVENTS_SEND_MESSAGE=true WEBHOOK_EVENTS_CONTACTS_SET=true WEBHOOK_EVENTS_CONTACTS_UPSERT=true diff --git a/Dockerfile b/Dockerfile index a7e558f3..497d1507 100644 --- a/Dockerfile +++ b/Dockerfile @@ -59,6 +59,7 @@ ENV WEBHOOK_EVENTS_QRCODE_UPDATED=$WEBHOOK_EVENTS_QRCODE_UPDATED ENV WEBHOOK_EVENTS_MESSAGES_SET=$WEBHOOK_EVENTS_MESSAGES_SET ENV WEBHOOK_EVENTS_MESSAGES_UPSERT=$WEBHOOK_EVENTS_MESSAGES_UPSERT ENV WEBHOOK_EVENTS_MESSAGES_UPDATE=$WEBHOOK_EVENTS_MESSAGES_UPDATE +ENV WEBHOOK_EVENTS_MESSAGES_DELETE=$WEBHOOK_EVENTS_MESSAGES_DELETE ENV WEBHOOK_EVENTS_SEND_MESSAGE=$WEBHOOK_EVENTS_SEND_MESSAGE ENV WEBHOOK_EVENTS_CONTACTS_SET=$WEBHOOK_EVENTS_CONTACTS_SET ENV WEBHOOK_EVENTS_CONTACTS_UPSERT=$WEBHOOK_EVENTS_CONTACTS_UPSERT diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 76bb55ea..ac608ede 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -76,6 +76,7 @@ export type EventsWebhook = { MESSAGES_SET: boolean; MESSAGES_UPSERT: boolean; MESSAGES_UPDATE: boolean; + MESSAGES_DELETE: boolean; SEND_MESSAGE: boolean; CONTACTS_SET: boolean; CONTACTS_UPDATE: boolean; @@ -238,6 +239,7 @@ export class ConfigService { MESSAGES_SET: process.env?.WEBHOOK_EVENTS_MESSAGES_SET === 'true', MESSAGES_UPSERT: process.env?.WEBHOOK_EVENTS_MESSAGES_UPSERT === 'true', MESSAGES_UPDATE: process.env?.WEBHOOK_EVENTS_MESSAGES_UPDATE === 'true', + MESSAGES_DELETE: process.env?.WEBHOOK_EVENTS_MESSAGES_DELETE === 'true', SEND_MESSAGE: process.env?.WEBHOOK_EVENTS_SEND_MESSAGE === 'true', CONTACTS_SET: process.env?.WEBHOOK_EVENTS_CONTACTS_SET === 'true', CONTACTS_UPDATE: process.env?.WEBHOOK_EVENTS_CONTACTS_UPDATE === 'true', diff --git a/src/dev-env.yml b/src/dev-env.yml index 244ff73d..1f43c2ad 100644 --- a/src/dev-env.yml +++ b/src/dev-env.yml @@ -96,6 +96,7 @@ WEBHOOK: MESSAGES_SET: true MESSAGES_UPSERT: true MESSAGES_UPDATE: true + MESSAGES_DELETE: true SEND_MESSAGE: true CONTACTS_SET: true CONTACTS_UPSERT: true diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 21d206d6..77e05f19 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -39,6 +39,7 @@ export const instanceNameSchema: JSONSchema7 = { 'MESSAGES_SET', 'MESSAGES_UPSERT', 'MESSAGES_UPDATE', + 'MESSAGES_DELETE', 'SEND_MESSAGE', 'CONTACTS_SET', 'CONTACTS_UPSERT', @@ -828,6 +829,7 @@ export const webhookSchema: JSONSchema7 = { 'MESSAGES_SET', 'MESSAGES_UPSERT', 'MESSAGES_UPDATE', + 'MESSAGES_DELETE', 'SEND_MESSAGE', 'CONTACTS_SET', 'CONTACTS_UPSERT', diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index a10c6223..01d0323e 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1116,6 +1116,7 @@ export class WAStartupService { }, 'messages.update': async (args: WAMessageUpdate[], database: Database) => { + console.log(args); this.logger.verbose('Event received: messages.update'); const status: Record = { 0: 'ERROR', @@ -1126,11 +1127,7 @@ export class WAStartupService { 5: 'PLAYED', }; for await (const { key, update } of args) { - if ( - key.remoteJid !== 'status@broadcast' && - !key?.remoteJid?.match(/(:\d+)/) && - key.fromMe - ) { + if (key.remoteJid !== 'status@broadcast' && !key?.remoteJid?.match(/(:\d+)/)) { this.logger.verbose('Message update is valid'); let pollUpdates: any; @@ -1150,6 +1147,16 @@ export class WAStartupService { } } + if (status[update.status] === 'READ' && !key.fromMe) return; + + if (update.message === null && update.status === undefined) { + this.logger.verbose('Message deleted'); + + this.logger.verbose('Sending data to webhook in event MESSAGE_DELETE'); + await this.sendDataWebhook(Events.MESSAGES_DELETE, key); + return; + } + const message: MessageUpdateRaw = { ...key, status: status[update.status], diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index 1ebe3b40..169df515 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -9,6 +9,7 @@ export enum Events { MESSAGES_SET = 'messages.set', MESSAGES_UPSERT = 'messages.upsert', MESSAGES_UPDATE = 'messages.update', + MESSAGES_DELETE = 'messages.delete', SEND_MESSAGE = 'send.message', CONTACTS_SET = 'contacts.set', CONTACTS_UPSERT = 'contacts.upsert', From 66a8ceb27ac5d6a874ea7d8c39b3965f366ad888 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 16 Jul 2023 18:16:51 -0300 Subject: [PATCH 07/48] feat: added messages.delete event --- CHANGELOG.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32b2bb26..6767db37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ -# 1.2.3 (homolog) +# 1.3.0 (homolog) -# Fixed +### Features + +* Added messages.delete event + +### Fixed * Fixed error to send message in large groups * Docker files adjusted @@ -8,7 +12,6 @@ * Now it's getting the API URL directly in the request, no longer need the variable in the env file * Removed link preview endpoint, now it's done automatically from sending conventional text * Added group membership validation before sending message to groups -* Added messages.delete event # 1.2.2 (2023-07-15 09:36) From 2e91a2ecdb9fed0fa317b06507e8ffd6925a989f Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 16 Jul 2023 18:26:53 -0300 Subject: [PATCH 08/48] fix: adjusts in env files --- Docker/.env.example | 2 +- src/dev-env.yml | 2 +- src/whatsapp/services/whatsapp.service.ts | 30 +++++++++++++---------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/Docker/.env.example b/Docker/.env.example index 3c0bfb9e..392c6f3e 100644 --- a/Docker/.env.example +++ b/Docker/.env.example @@ -7,7 +7,7 @@ CORS_CREDENTIALS=true # Determine the logs to be displayed LOG_LEVEL='ERROR,WARN,DEBUG,INFO,LOG,VERBOSE,DARK,WEBHOOKS' LOG_COLOR=true -LOG_BAILEYS=error # "fatal" | "error" | "warn" | "info" | "debug" | "trace" +LOG_BAILEYS=error # fatal | error | warn | info | debug | trace # Determine how long the instance should be deleted from memory in case of no connection. # Default time: 5 minutes diff --git a/src/dev-env.yml b/src/dev-env.yml index 1f43c2ad..c0f907fc 100644 --- a/src/dev-env.yml +++ b/src/dev-env.yml @@ -39,7 +39,7 @@ LOG: - DARK - WEBHOOKS COLOR: true - BAILEYS: error # "fatal" | "error" | "warn" | "info" | "debug" | "trace" + BAILEYS: error # fatal | error | warn | info | debug | trace # Determine how long the instance should be deleted from memory in case of no connection. # Default time: 5 minutes diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 01d0323e..bd694790 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1339,27 +1339,31 @@ export class WAStartupService { private createJid(number: string): string { this.logger.verbose('Creating jid with number: ' + number); - if (number.includes('@g.us') || number.includes('@s.whatsapp.net')) { + + const numberReplace = number.replace(/[^0-9]/g, ''); + + console.log('number', numberReplace); + if (numberReplace.includes('@g.us') || numberReplace.includes('@s.whatsapp.net')) { this.logger.verbose('Number already contains @g.us or @s.whatsapp.net'); - return number; + return numberReplace; } - if (number.includes('@broadcast')) { + if (numberReplace.includes('@broadcast')) { this.logger.verbose('Number already contains @broadcast'); - return number; + return numberReplace; } - const formattedBRNumber = this.formatBRNumber(number); - if (formattedBRNumber !== number) { + const formattedBRNumber = this.formatBRNumber(numberReplace); + if (formattedBRNumber !== numberReplace) { this.logger.verbose( 'Jid created is whatsapp in format BR: ' + `${formattedBRNumber}@s.whatsapp.net`, ); return `${formattedBRNumber}@s.whatsapp.net`; } - const formattedMXARNumber = this.formatMXOrARNumber(number); + const formattedMXARNumber = this.formatMXOrARNumber(numberReplace); - if (formattedMXARNumber !== number) { + if (formattedMXARNumber !== numberReplace) { this.logger.verbose( 'Jid created is whatsapp in format MXAR: ' + `${formattedMXARNumber}@s.whatsapp.net`, @@ -1367,13 +1371,13 @@ export class WAStartupService { return `${formattedMXARNumber}@s.whatsapp.net`; } - if (number.includes('-')) { - this.logger.verbose('Jid created is group: ' + `${number}@g.us`); - return `${number}@g.us`; + if (numberReplace.includes('-')) { + this.logger.verbose('Jid created is group: ' + `${numberReplace}@g.us`); + return `${numberReplace}@g.us`; } - this.logger.verbose('Jid created is whatsapp: ' + `${number}@s.whatsapp.net`); - return `${number}@s.whatsapp.net`; + this.logger.verbose('Jid created is whatsapp: ' + `${numberReplace}@s.whatsapp.net`); + return `${numberReplace}@s.whatsapp.net`; } public async profilePicture(number: string) { From 0654627478787083ae6e6485a8851c45beac8d19 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 16 Jul 2023 18:35:48 -0300 Subject: [PATCH 09/48] fix: adjusts in dockerfile --- Docker/.env.example | 2 - Dockerfile | 159 +++++++++++----------- src/config/env.config.ts | 4 +- src/whatsapp/services/whatsapp.service.ts | 5 - 4 files changed, 81 insertions(+), 89 deletions(-) diff --git a/Docker/.env.example b/Docker/.env.example index 392c6f3e..af8927d8 100644 --- a/Docker/.env.example +++ b/Docker/.env.example @@ -1,5 +1,3 @@ -SERVER_URL='' # ex.: http://localhost:3333 - CORS_ORIGIN='*' # Or separate by commas - ex.: 'yourdomain1.com, yourdomain2.com' CORS_METHODS='POST,GET,PUT,DELETE' CORS_CREDENTIALS=true diff --git a/Dockerfile b/Dockerfile index 497d1507..91c770c1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,87 +13,88 @@ COPY ./package.json . ENV DOCKER_ENV=true -ENV SERVER_TYPE="http" -ENV SERVER_PORT=8080 -ENV SERVER_URL=$SERVER_URL - -ENV CORS_ORIGIN="*" -ENV CORS_METHODS="POST,GET,PUT,DELETE" +ENV CORS_ORIGIN=* +ENV CORS_METHODS=POST,GET,PUT,DELETE ENV CORS_CREDENTIALS=true -ENV LOG_LEVEL=$LOG_LEVEL -ENV LOG_COLOR=$LOG_COLOR - -ENV DEL_INSTANCE=$DEL_INSTANCE - -ENV STORE_MESSAGES=$STORE_MESSAGE -ENV STORE_MESSAGE_UP=$STORE_MESSAGE_UP -ENV STORE_CONTACTS=$STORE_CONTACTS -ENV STORE_CHATS=$STORE_CHATS - -ENV CLEAN_STORE_CLEANING_INTERVAL=$CLEAN_STORE_CLEANING_INTERVAL -ENV CLEAN_STORE_MESSAGES=$CLEAN_STORE_MESSAGE -ENV CLEAN_STORE_MESSAGE_UP=$CLEAN_STORE_MESSAGE_UP -ENV CLEAN_STORE_CONTACTS=$CLEAN_STORE_CONTACTS -ENV CLEAN_STORE_CHATS=$CLEAN_STORE_CHATS - -ENV DATABASE_ENABLED=$DATABASE_ENABLED -ENV DATABASE_CONNECTION_URI=$DATABASE_CONNECTION_URI -ENV DATABASE_CONNECTION_DB_PREFIX_NAME=$DATABASE_CONNECTION_DB_PREFIX_NAME -ENV DATABASE_SAVE_DATA_INSTANCE=$DATABASE_SAVE_DATA_INSTANCE -ENV DATABASE_SAVE_DATA_NEW_MESSAGE=$DATABASE_SAVE_DATA_NEW_MESSAGE -ENV DATABASE_SAVE_MESSAGE_UPDATE=$DATABASE_SAVE_MESSAGE_UPDATE -ENV DATABASE_SAVE_DATA_CONTACTS=$DATABASE_SAVE_DATA_CONTACTS -ENV DATABASE_SAVE_DATA_CHATS=$DATABASE_SAVE_DATA_CHATS - -ENV REDIS_ENABLED=$REDIS_ENABLED -ENV REDIS_URI=$REDIS_URI -ENV REDIS_PREFIX_KEY=$REDIS_PREFIX_KEY - -ENV WEBHOOK_GLOBAL_URL=$WEBHOOK_GLOBAL_URL -ENV WEBHOOK_GLOBAL_ENABLED=$WEBHOOK_GLOBAL_ENABLED -ENV WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS=$WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS - -ENV WEBHOOK_EVENTS_APPLICATION_STARTUP=$WEBHOOK_EVENTS_APPLICATION_STARTUP -ENV WEBHOOK_EVENTS_QRCODE_UPDATED=$WEBHOOK_EVENTS_QRCODE_UPDATED -ENV WEBHOOK_EVENTS_MESSAGES_SET=$WEBHOOK_EVENTS_MESSAGES_SET -ENV WEBHOOK_EVENTS_MESSAGES_UPSERT=$WEBHOOK_EVENTS_MESSAGES_UPSERT -ENV WEBHOOK_EVENTS_MESSAGES_UPDATE=$WEBHOOK_EVENTS_MESSAGES_UPDATE -ENV WEBHOOK_EVENTS_MESSAGES_DELETE=$WEBHOOK_EVENTS_MESSAGES_DELETE -ENV WEBHOOK_EVENTS_SEND_MESSAGE=$WEBHOOK_EVENTS_SEND_MESSAGE -ENV WEBHOOK_EVENTS_CONTACTS_SET=$WEBHOOK_EVENTS_CONTACTS_SET -ENV WEBHOOK_EVENTS_CONTACTS_UPSERT=$WEBHOOK_EVENTS_CONTACTS_UPSERT -ENV WEBHOOK_EVENTS_CONTACTS_UPDATE=$WEBHOOK_EVENTS_CONTACTS_UPDATE -ENV WEBHOOK_EVENTS_PRESENCE_UPDATE=$WEBHOOK_EVENTS_PRESENCE_UPDATE -ENV WEBHOOK_EVENTS_CHATS_SET=$WEBHOOK_EVENTS_CHATS_SET -ENV WEBHOOK_EVENTS_CHATS_UPSERT=$WEBHOOK_EVENTS_CHATS_UPSERT -ENV WEBHOOK_EVENTS_CHATS_UPDATE=$WEBHOOK_EVENTS_CHATS_UPDATE -ENV WEBHOOK_EVENTS_CONNECTION_UPDATE=$WEBHOOK_EVENTS_CONNECTION_UPDATE -ENV WEBHOOK_EVENTS_GROUPS_UPSERT=$WEBHOOK_EVENTS_GROUPS_UPSERT -ENV WEBHOOK_EVENTS_GROUPS_UPDATE=$WEBHOOK_EVENTS_GROUPS_UPDATE -ENV WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE=$WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE - -ENV WEBHOOK_EVENTS_NEW_JWT_TOKEN=$WEBHOOK_EVENTS_NEW_JWT_TOKEN - -ENV CONFIG_SESSION_PHONE_CLIENT=$CONFIG_SESSION_PHONE_CLIENT -ENV CONFIG_SESSION_PHONE_NAME=$CONFIG_SESSION_PHONE_NAME - -ENV QRCODE_LIMIT=$QRCODE_LIMIT - -ENV AUTHENTICATION_TYPE=$AUTHENTICATION_TYPE - -ENV AUTHENTICATION_API_KEY=$AUTHENTICATION_API_KEY -ENV AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=$AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES - -ENV AUTHENTICATION_JWT_EXPIRIN_IN=$AUTHENTICATION_JWT_EXPIRIN_IN -ENV AUTHENTICATION_JWT_SECRET="L=0YWt]b2w[WF>#>:&E`" - -ENV AUTHENTICATION_INSTANCE_NAME=$AUTHENTICATION_INSTANCE_NAME -ENV AUTHENTICATION_INSTANCE_WEBHOOK_URL=$AUTHENTICATION_INSTANCE_WEBHOOK_URL -ENV AUTHENTICATION_INSTANCE_CHATWOOT_ACCOUNT_ID=$AUTHENTICATION_INSTANCE_CHATWOOT_ACCOUNT_ID -ENV AUTHENTICATION_INSTANCE_CHATWOOT_TOKEN=$AUTHENTICATION_INSTANCE_CHATWOOT_TOKEN -ENV AUTHENTICATION_INSTANCE_CHATWOOT_URL=$AUTHENTICATION_INSTANCE_CHATWOOT_URL -ENV AUTHENTICATION_INSTANCE_MODE=$AUTHENTICATION_INSTANCE_MODE +ENV LOG_LEVEL=ERROR,WARN,DEBUG,INFO,LOG,VERBOSE,DARK,WEBHOOKS +ENV LOG_COLOR=true +ENV LOG_BAILEYS=error + +ENV DEL_INSTANCE=false + +ENV STORE_MESSAGES=true +ENV STORE_MESSAGE_UP=true +ENV STORE_CONTACTS=true +ENV STORE_CHATS=true + +ENV CLEAN_STORE_CLEANING_INTERVAL=7200 +ENV CLEAN_STORE_MESSAGES=true +ENV CLEAN_STORE_MESSAGE_UP=true +ENV CLEAN_STORE_CONTACTS=true +ENV CLEAN_STORE_CHATS=true + +ENV DATABASE_ENABLED=false +ENV DATABASE_CONNECTION_URI=mongodb://root:root@mongodb:27017/?authSource=admin&readPreference=primary&ssl=false&directConnection=true +ENV DATABASE_CONNECTION_DB_PREFIX_NAME=evolution + +ENV DATABASE_SAVE_DATA_INSTANCE=false +ENV DATABASE_SAVE_DATA_NEW_MESSAGE=false +ENV DATABASE_SAVE_MESSAGE_UPDATE=false +ENV DATABASE_SAVE_DATA_CONTACTS=false +ENV DATABASE_SAVE_DATA_CHATS=false + +ENV REDIS_ENABLED=false +ENV REDIS_URI=redis://redis:6379 +ENV REDIS_PREFIX_KEY=evolution + +ENV WEBHOOK_GLOBAL_URL= +ENV WEBHOOK_GLOBAL_ENABLED=false + +ENV WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS=false + +ENV WEBHOOK_EVENTS_APPLICATION_STARTUP=false +ENV WEBHOOK_EVENTS_QRCODE_UPDATED=true +ENV WEBHOOK_EVENTS_MESSAGES_SET=true +ENV WEBHOOK_EVENTS_MESSAGES_UPSERT=true +ENV WEBHOOK_EVENTS_MESSAGES_UPDATE=true +ENV WEBHOOK_EVENTS_MESSAGES_DELETE=true +ENV WEBHOOK_EVENTS_SEND_MESSAGE=true +ENV WEBHOOK_EVENTS_CONTACTS_SET=true +ENV WEBHOOK_EVENTS_CONTACTS_UPSERT=true +ENV WEBHOOK_EVENTS_CONTACTS_UPDATE=true +ENV WEBHOOK_EVENTS_PRESENCE_UPDATE=true +ENV WEBHOOK_EVENTS_CHATS_SET=true +ENV WEBHOOK_EVENTS_CHATS_UPSERT=true +ENV WEBHOOK_EVENTS_CHATS_UPDATE=true +ENV WEBHOOK_EVENTS_CHATS_DELETE=true +ENV WEBHOOK_EVENTS_GROUPS_UPSERT=true +ENV WEBHOOK_EVENTS_GROUPS_UPDATE=true +ENV WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE=true +ENV WEBHOOK_EVENTS_CONNECTION_UPDATE=true + +ENV WEBHOOK_EVENTS_NEW_JWT_TOKEN=false + +ENV CONFIG_SESSION_PHONE_CLIENT=Evolution +ENV CONFIG_SESSION_PHONE_NAME=chrome + +ENV QRCODE_LIMIT=30 + +ENV AUTHENTICATION_TYPE=apikey + +ENV AUTHENTICATION_API_KEY=B6D711FCDE4D4FD5936544120E713976 +ENV AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=true + +ENV AUTHENTICATION_JWT_EXPIRIN_IN=0 +ENV AUTHENTICATION_JWT_SECRET=L0YWtjb2w554WFqPG + +ENV AUTHENTICATION_INSTANCE_MODE=server + +ENV AUTHENTICATION_INSTANCE_NAME=evolution +ENV AUTHENTICATION_INSTANCE_WEBHOOK_URL= +ENV AUTHENTICATION_INSTANCE_CHATWOOT_ACCOUNT_ID=1 +ENV AUTHENTICATION_INSTANCE_CHATWOOT_TOKEN=123456 +ENV AUTHENTICATION_INSTANCE_CHATWOOT_URL= RUN npm install diff --git a/src/config/env.config.ts b/src/config/env.config.ts index ac608ede..76149199 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -1,10 +1,9 @@ import { readFileSync } from 'fs'; import { load } from 'js-yaml'; import { join } from 'path'; -import { SRC_DIR } from './path.config'; import { isBooleanString } from 'class-validator'; -export type HttpServer = { TYPE: 'http' | 'https'; PORT: number; URL: string }; +export type HttpServer = { TYPE: 'http' | 'https'; PORT: number }; export type HttpMethods = 'POST' | 'GET' | 'PUT' | 'DELETE'; export type Cors = { @@ -174,7 +173,6 @@ export class ConfigService { SERVER: { TYPE: process.env.SERVER_TYPE as 'http' | 'https', PORT: Number.parseInt(process.env.SERVER_PORT), - URL: process.env.SERVER_URL, }, CORS: { ORIGIN: process.env.CORS_ORIGIN.split(','), diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index bd694790..98ad8d17 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -342,7 +342,6 @@ export class WAStartupService { public async sendDataWebhook(event: Events, data: T, local = true) { const webhookGlobal = this.configService.get('WEBHOOK'); - const urlServer = this.configService.get('SERVER').URL; const webhookLocal = this.localWebhook.events; const we = event.replace(/[\.-]/gm, '_').toUpperCase(); const transformedWe = we.replace(/_/gm, '-').toLowerCase(); @@ -367,7 +366,6 @@ export class WAStartupService { instance: this.instance.name, data, destination: this.localWebhook.url, - urlServer, }); } @@ -379,7 +377,6 @@ export class WAStartupService { instance: this.instance.name, data, destination: this.localWebhook.url, - urlServer, }); } } catch (error) { @@ -427,7 +424,6 @@ export class WAStartupService { instance: this.instance.name, data, destination: localUrl, - urlServer, }); } @@ -439,7 +435,6 @@ export class WAStartupService { instance: this.instance.name, data, destination: localUrl, - urlServer, }); } } catch (error) { From f28d5c7781e15689352e8f954633633d7d81d95d Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 16 Jul 2023 18:44:10 -0300 Subject: [PATCH 10/48] fix: adjusts in dockerfile --- CHANGELOG.md | 1 + Dockerfile | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6767db37..852e6a7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * Now it's getting the API URL directly in the request, no longer need the variable in the env file * Removed link preview endpoint, now it's done automatically from sending conventional text * Added group membership validation before sending message to groups +* Adjusts in Dockerfile # 1.2.2 (2023-07-15 09:36) diff --git a/Dockerfile b/Dockerfile index 91c770c1..b05dc02e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -75,7 +75,7 @@ ENV WEBHOOK_EVENTS_CONNECTION_UPDATE=true ENV WEBHOOK_EVENTS_NEW_JWT_TOKEN=false -ENV CONFIG_SESSION_PHONE_CLIENT=Evolution +ENV CONFIG_SESSION_PHONE_CLIENT='Evolution API' ENV CONFIG_SESSION_PHONE_NAME=chrome ENV QRCODE_LIMIT=30 @@ -86,7 +86,7 @@ ENV AUTHENTICATION_API_KEY=B6D711FCDE4D4FD5936544120E713976 ENV AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=true ENV AUTHENTICATION_JWT_EXPIRIN_IN=0 -ENV AUTHENTICATION_JWT_SECRET=L0YWtjb2w554WFqPG +ENV AUTHENTICATION_JWT_SECRET='L=0YWt]b2w[WF>#>:&E`' ENV AUTHENTICATION_INSTANCE_MODE=server From b90736ed2542a686122dcdc5cdff506140ed7072 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 16 Jul 2023 18:51:03 -0300 Subject: [PATCH 11/48] fix: adjusts in dockerfile --- src/config/env.config.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 76149199..1c7cc9ce 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -98,9 +98,9 @@ export type Instance = { NAME: string; WEBHOOK_URL: string; MODE: string; - CHATWOOT_ACCOUNT_ID?: string; - CHATWOOT_TOKEN?: string; - CHATWOOT_URL?: string; + CHATWOOT_ACCOUNT_ID: string; + CHATWOOT_TOKEN: string; + CHATWOOT_URL: string; }; export type Auth = { API_KEY: ApiKey; @@ -192,7 +192,7 @@ export class ConfigService { CLEAN_STORE: { CLEANING_INTERVAL: Number.isInteger(process.env?.CLEAN_STORE_CLEANING_TERMINAL) ? Number.parseInt(process.env.CLEAN_STORE_CLEANING_TERMINAL) - : undefined, + : 7200, MESSAGES: process.env?.CLEAN_STORE_MESSAGES === 'true', MESSAGE_UP: process.env?.CLEAN_STORE_MESSAGE_UP === 'true', CONTACTS: process.env?.CLEAN_STORE_CONTACTS === 'true', @@ -224,7 +224,7 @@ export class ConfigService { }, DEL_INSTANCE: isBooleanString(process.env?.DEL_INSTANCE) ? process.env.DEL_INSTANCE === 'true' - : Number.parseInt(process.env.DEL_INSTANCE), + : Number.parseInt(process.env.DEL_INSTANCE) || false, WEBHOOK: { GLOBAL: { URL: process.env?.WEBHOOK_GLOBAL_URL, @@ -256,11 +256,11 @@ export class ConfigService { }, }, CONFIG_SESSION_PHONE: { - CLIENT: process.env?.CONFIG_SESSION_PHONE_CLIENT, - NAME: process.env?.CONFIG_SESSION_PHONE_NAME, + CLIENT: process.env?.CONFIG_SESSION_PHONE_CLIENT || 'Evolution API', + NAME: process.env?.CONFIG_SESSION_PHONE_NAME || 'chrome', }, QRCODE: { - LIMIT: Number.parseInt(process.env.QRCODE_LIMIT), + LIMIT: Number.parseInt(process.env.QRCODE_LIMIT) || 30, }, AUTHENTICATION: { TYPE: process.env.AUTHENTICATION_TYPE as 'jwt', From 4b32485e3cc7fda306bfdb56833af90df25ced0f Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 16 Jul 2023 18:52:21 -0300 Subject: [PATCH 12/48] fix: adjusts in dockerfile --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 852e6a7b..9bebe903 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * Fixed error to send message in large groups * Docker files adjusted * Fixed in the postman collection the webhookByEvent parameter by webhook_by_events +* Added validations in create instance * Now it's getting the API URL directly in the request, no longer need the variable in the env file * Removed link preview endpoint, now it's done automatically from sending conventional text * Added group membership validation before sending message to groups From 3c15fc1b0de2264c8ad9519ce19880ad393006d3 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 16 Jul 2023 19:05:17 -0300 Subject: [PATCH 13/48] fix: adjusts in dockerfile --- CHANGELOG.md | 1 - Docker/.env.example | 2 ++ Dockerfile | 2 ++ src/config/env.config.ts | 3 +- .../controllers/instance.controller.ts | 31 +++++++++---------- src/whatsapp/routers/instance.router.ts | 5 +-- 6 files changed, 21 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bebe903..3809d59b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,6 @@ * Docker files adjusted * Fixed in the postman collection the webhookByEvent parameter by webhook_by_events * Added validations in create instance -* Now it's getting the API URL directly in the request, no longer need the variable in the env file * Removed link preview endpoint, now it's done automatically from sending conventional text * Added group membership validation before sending message to groups * Adjusts in Dockerfile diff --git a/Docker/.env.example b/Docker/.env.example index af8927d8..f8511732 100644 --- a/Docker/.env.example +++ b/Docker/.env.example @@ -1,3 +1,5 @@ +SERVER_URL='http://localhost:8080' # http://localhost:3333 | http://localhost:3333/api/v1 + CORS_ORIGIN='*' # Or separate by commas - ex.: 'yourdomain1.com, yourdomain2.com' CORS_METHODS='POST,GET,PUT,DELETE' CORS_CREDENTIALS=true diff --git a/Dockerfile b/Dockerfile index b05dc02e..088f6fa1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,6 +13,8 @@ COPY ./package.json . ENV DOCKER_ENV=true +ENV SERVER_URL='http://localhost:8080' + ENV CORS_ORIGIN=* ENV CORS_METHODS=POST,GET,PUT,DELETE ENV CORS_CREDENTIALS=true diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 1c7cc9ce..7221f474 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -3,7 +3,7 @@ import { load } from 'js-yaml'; import { join } from 'path'; import { isBooleanString } from 'class-validator'; -export type HttpServer = { TYPE: 'http' | 'https'; PORT: number }; +export type HttpServer = { TYPE: 'http' | 'https'; PORT: number; URL: string }; export type HttpMethods = 'POST' | 'GET' | 'PUT' | 'DELETE'; export type Cors = { @@ -173,6 +173,7 @@ export class ConfigService { SERVER: { TYPE: process.env.SERVER_TYPE as 'http' | 'https', PORT: Number.parseInt(process.env.SERVER_PORT), + URL: process.env.SERVER_URL, }, CORS: { ORIGIN: process.env.CORS_ORIGIN.split(','), diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 4145acef..8bb35e35 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -28,21 +28,18 @@ export class InstanceController { private readonly logger = new Logger(InstanceController.name); - public async createInstance( - { - instanceName, - webhook, - webhook_by_events, - events, - qrcode, - token, - chatwoot_account_id, - chatwoot_token, - chatwoot_url, - chatwoot_sign_msg, - }: InstanceDto, - apiURL: string, - ) { + public async createInstance({ + instanceName, + webhook, + webhook_by_events, + events, + qrcode, + token, + chatwoot_account_id, + chatwoot_token, + chatwoot_url, + chatwoot_sign_msg, + }: InstanceDto) { this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); const mode = this.configService.get('AUTHENTICATION').INSTANCE.MODE; @@ -143,7 +140,7 @@ export class InstanceController { throw new BadRequestException('Invalid "url" property in chatwoot'); } - const urlServer = apiURL; + const urlServer = this.configService.get('SERVER').URL; try { this.chatwootService.create(instance, { @@ -285,7 +282,7 @@ export class InstanceController { throw new BadRequestException('Invalid "url" property in chatwoot'); } - const urlServer = apiURL; + const urlServer = this.configService.get('SERVER').URL; try { this.chatwootService.create(instance, { diff --git a/src/whatsapp/routers/instance.router.ts b/src/whatsapp/routers/instance.router.ts index 7dc35d30..850ffebd 100644 --- a/src/whatsapp/routers/instance.router.ts +++ b/src/whatsapp/routers/instance.router.ts @@ -24,14 +24,11 @@ export class InstanceRouter extends RouterBroker { logger.verbose('request query: '); logger.verbose(req.query); - const apiURL = req.headers.host || req.hostname; - logger.verbose('API URL: ' + apiURL); - const response = await this.dataValidate({ request: req, schema: instanceNameSchema, ClassRef: InstanceDto, - execute: (instance) => instanceController.createInstance(instance, apiURL), + execute: (instance) => instanceController.createInstance(instance), }); return res.status(HttpStatus.CREATED).json(response); From 654400c0cf80cff7e5468f66769c30904f6d2d66 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 16 Jul 2023 19:14:00 -0300 Subject: [PATCH 14/48] fix: adjusts in dockerfile --- Docker/mongodb/docker-compose.yaml | 11 ++++++++--- Docker/redis/docker-compose.yaml | 8 +++++--- docker-compose.yaml | 11 ++++++++--- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/Docker/mongodb/docker-compose.yaml b/Docker/mongodb/docker-compose.yaml index 86892877..8f6b1125 100644 --- a/Docker/mongodb/docker-compose.yaml +++ b/Docker/mongodb/docker-compose.yaml @@ -33,10 +33,15 @@ services: volumes: evolution_mongodb_data: + name: evolution_mongodb_data + external: true + evolution_mongodb_configdb: + name: evolution_mongodb_configdb + external: true networks: - default: - external: - name: evolution-net + evolution-net: + name: evolution-net + external: true \ No newline at end of file diff --git a/Docker/redis/docker-compose.yaml b/Docker/redis/docker-compose.yaml index 54828e7f..4873b4a0 100644 --- a/Docker/redis/docker-compose.yaml +++ b/Docker/redis/docker-compose.yaml @@ -22,8 +22,10 @@ services: volumes: evolution_redis: + name: evolution_redis + external: true networks: - default: - external: - name: evolution-net + evolution-net: + name: evolution-net + external: true diff --git a/docker-compose.yaml b/docker-compose.yaml index 8962763f..b89ed2b0 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -18,10 +18,15 @@ services: volumes: evolution_instances: + name: evolution_instances + external: true + evolution_store: + name: evolution_store + external: true networks: - default: - external: - name: evolution-net + evolution-net: + name: evolution-net + external: true \ No newline at end of file From dfa6dd50114ea614a10959b8867923dcfe2e3e4f Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 16 Jul 2023 19:15:39 -0300 Subject: [PATCH 15/48] fix: adjusts in dockerfile --- Docker/mongodb/docker-compose.yaml | 5 ----- Docker/redis/docker-compose.yaml | 2 -- docker-compose.yaml | 5 ----- 3 files changed, 12 deletions(-) diff --git a/Docker/mongodb/docker-compose.yaml b/Docker/mongodb/docker-compose.yaml index 8f6b1125..de1b7e2b 100644 --- a/Docker/mongodb/docker-compose.yaml +++ b/Docker/mongodb/docker-compose.yaml @@ -33,12 +33,7 @@ services: volumes: evolution_mongodb_data: - name: evolution_mongodb_data - external: true - evolution_mongodb_configdb: - name: evolution_mongodb_configdb - external: true networks: evolution-net: diff --git a/Docker/redis/docker-compose.yaml b/Docker/redis/docker-compose.yaml index 4873b4a0..dce371f2 100644 --- a/Docker/redis/docker-compose.yaml +++ b/Docker/redis/docker-compose.yaml @@ -22,8 +22,6 @@ services: volumes: evolution_redis: - name: evolution_redis - external: true networks: evolution-net: diff --git a/docker-compose.yaml b/docker-compose.yaml index b89ed2b0..51f5bd43 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -18,12 +18,7 @@ services: volumes: evolution_instances: - name: evolution_instances - external: true - evolution_store: - name: evolution_store - external: true networks: evolution-net: From 7a2fcc3469844b57eacd69fdd6629c9dd4b6e208 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 16 Jul 2023 19:21:17 -0300 Subject: [PATCH 16/48] fix: adjusts in dockerfile --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 87f5f908..5feef990 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.2.3", + "version": "1.3.0", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": { From 69353892d92b410971354621409841eec85fa7ae Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sun, 16 Jul 2023 21:55:12 -0300 Subject: [PATCH 17/48] feat: Added restart instance endpoint --- CHANGELOG.md | 1 + .../controllers/instance.controller.ts | 20 ++----------------- src/whatsapp/services/whatsapp.service.ts | 3 --- 3 files changed, 3 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3809d59b..14aa12c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Features * Added messages.delete event +* Added restart instance endpoint ### Fixed diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 8bb35e35..cf8678c1 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -357,24 +357,8 @@ export class InstanceController { try { this.logger.verbose('requested restartInstance from ' + instanceName + ' instance'); - this.logger.verbose('deleting instance: ' + instanceName); - delete this.waMonitor.waInstances[instanceName]; - - this.logger.verbose('creating instance: ' + instanceName); - const instance = new WAStartupService( - this.configService, - this.eventEmitter, - this.repository, - this.cache, - ); - - instance.instanceName = instanceName; - - this.logger.verbose('instance: ' + instance.instanceName + ' created'); - - this.logger.verbose('connecting instance: ' + instanceName); - await instance.connectToWhatsapp(); - this.waMonitor.waInstances[instance.instanceName] = instance; + this.logger.verbose('logging out instance: ' + instanceName); + this.waMonitor.waInstances[instanceName]?.client?.ws?.close(); return { error: false, message: 'Instance restarted' }; } catch (error) { diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 98ad8d17..360c8905 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1111,7 +1111,6 @@ export class WAStartupService { }, 'messages.update': async (args: WAMessageUpdate[], database: Database) => { - console.log(args); this.logger.verbose('Event received: messages.update'); const status: Record = { 0: 'ERROR', @@ -1337,7 +1336,6 @@ export class WAStartupService { const numberReplace = number.replace(/[^0-9]/g, ''); - console.log('number', numberReplace); if (numberReplace.includes('@g.us') || numberReplace.includes('@s.whatsapp.net')) { this.logger.verbose('Number already contains @g.us or @s.whatsapp.net'); return numberReplace; @@ -1507,7 +1505,6 @@ export class WAStartupService { } if (message['conversation']) { - console.log(message['conversation']); this.logger.verbose('Sending message'); return await this.client.sendMessage( sender, From 8a14141021f3a00594c2081fc4ee1ff088fbce18 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 17 Jul 2023 11:33:08 -0300 Subject: [PATCH 18/48] fix: adjusts in returns in endpoints chatwoot and webhook --- .../controllers/chatwoot.controller.ts | 12 ++++++++ src/whatsapp/services/webhook.service.ts | 12 ++++++-- src/whatsapp/services/whatsapp.service.ts | 28 +++++++++---------- 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/src/whatsapp/controllers/chatwoot.controller.ts b/src/whatsapp/controllers/chatwoot.controller.ts index a4367833..d66901ef 100644 --- a/src/whatsapp/controllers/chatwoot.controller.ts +++ b/src/whatsapp/controllers/chatwoot.controller.ts @@ -66,6 +66,18 @@ export class ChatwootController { const urlServer = this.configService.get('SERVER').URL; + if (Object.keys(result).length === 0) { + return { + enabled: false, + url: '', + account_id: '', + token: '', + sign_msg: false, + name_inbox: '', + webhook_url: '', + }; + } + const response = { ...result, webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, diff --git a/src/whatsapp/services/webhook.service.ts b/src/whatsapp/services/webhook.service.ts index dbc98d7c..2370e05b 100644 --- a/src/whatsapp/services/webhook.service.ts +++ b/src/whatsapp/services/webhook.service.ts @@ -18,9 +18,17 @@ export class WebhookService { public async find(instance: InstanceDto): Promise { try { this.logger.verbose('find webhook: ' + instance.instanceName); - return await this.waMonitor.waInstances[instance.instanceName].findWebhook(); + const result = await this.waMonitor.waInstances[ + instance.instanceName + ].findWebhook(); + + if (Object.keys(result).length === 0) { + throw new Error('Webhook not found'); + } + + return result; } catch (error) { - return { enabled: null, url: '' }; + return { enabled: false, url: '', events: [], webhook_by_events: false }; } } } diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 360c8905..ff19b309 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1334,29 +1334,27 @@ export class WAStartupService { private createJid(number: string): string { this.logger.verbose('Creating jid with number: ' + number); - const numberReplace = number.replace(/[^0-9]/g, ''); - - if (numberReplace.includes('@g.us') || numberReplace.includes('@s.whatsapp.net')) { + if (number.includes('@g.us') || number.includes('@s.whatsapp.net')) { this.logger.verbose('Number already contains @g.us or @s.whatsapp.net'); - return numberReplace; + return number; } - if (numberReplace.includes('@broadcast')) { + if (number.includes('@broadcast')) { this.logger.verbose('Number already contains @broadcast'); - return numberReplace; + return number; } - const formattedBRNumber = this.formatBRNumber(numberReplace); - if (formattedBRNumber !== numberReplace) { + const formattedBRNumber = this.formatBRNumber(number); + if (formattedBRNumber !== number) { this.logger.verbose( 'Jid created is whatsapp in format BR: ' + `${formattedBRNumber}@s.whatsapp.net`, ); return `${formattedBRNumber}@s.whatsapp.net`; } - const formattedMXARNumber = this.formatMXOrARNumber(numberReplace); + const formattedMXARNumber = this.formatMXOrARNumber(number); - if (formattedMXARNumber !== numberReplace) { + if (formattedMXARNumber !== number) { this.logger.verbose( 'Jid created is whatsapp in format MXAR: ' + `${formattedMXARNumber}@s.whatsapp.net`, @@ -1364,13 +1362,13 @@ export class WAStartupService { return `${formattedMXARNumber}@s.whatsapp.net`; } - if (numberReplace.includes('-')) { - this.logger.verbose('Jid created is group: ' + `${numberReplace}@g.us`); - return `${numberReplace}@g.us`; + if (number.includes('-')) { + this.logger.verbose('Jid created is group: ' + `${number}@g.us`); + return `${number}@g.us`; } - this.logger.verbose('Jid created is whatsapp: ' + `${numberReplace}@s.whatsapp.net`); - return `${numberReplace}@s.whatsapp.net`; + this.logger.verbose('Jid created is whatsapp: ' + `${number}@s.whatsapp.net`); + return `${number}@s.whatsapp.net`; } public async profilePicture(number: string) { From a2448ea4c10b25a876c26935b7442990dc9d2dd1 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 17 Jul 2023 11:33:18 -0300 Subject: [PATCH 19/48] fix: adjusts in returns in endpoints chatwoot and webhook --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14aa12c3..a3065d08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ * Removed link preview endpoint, now it's done automatically from sending conventional text * Added group membership validation before sending message to groups * Adjusts in Dockerfile +* Adjusts in returns in endpoints chatwoot and webhook # 1.2.2 (2023-07-15 09:36) From 71a3e75ae2326a171775d4764b09c11b42e7f823 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 17 Jul 2023 14:57:52 -0300 Subject: [PATCH 20/48] fix: Fixed ghost mentions in send text message --- CHANGELOG.md | 1 + src/whatsapp/services/whatsapp.service.ts | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3065d08..20c8772a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ * Added group membership validation before sending message to groups * Adjusts in Dockerfile * Adjusts in returns in endpoints chatwoot and webhook +* Fixed ghost mentions in send text message # 1.2.2 (2023-07-15 09:36) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index ff19b309..fbe5f100 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -343,6 +343,7 @@ export class WAStartupService { public async sendDataWebhook(event: Events, data: T, local = true) { const webhookGlobal = this.configService.get('WEBHOOK'); const webhookLocal = this.localWebhook.events; + const serverUrl = this.configService.get('SERVER').URL; const we = event.replace(/[\.-]/gm, '_').toUpperCase(); const transformedWe = we.replace(/_/gm, '-').toLowerCase(); const instance = this.configService.get('AUTHENTICATION').INSTANCE; @@ -366,6 +367,7 @@ export class WAStartupService { instance: this.instance.name, data, destination: this.localWebhook.url, + server_url: serverUrl, }); } @@ -377,6 +379,7 @@ export class WAStartupService { instance: this.instance.name, data, destination: this.localWebhook.url, + server_url: serverUrl, }); } } catch (error) { @@ -390,6 +393,7 @@ export class WAStartupService { stack: error?.stack, name: error?.name, url: baseURL, + server_url: serverUrl, }); } } @@ -424,6 +428,7 @@ export class WAStartupService { instance: this.instance.name, data, destination: localUrl, + server_url: serverUrl, }); } @@ -435,6 +440,7 @@ export class WAStartupService { instance: this.instance.name, data, destination: localUrl, + server_url: serverUrl, }); } } catch (error) { @@ -448,6 +454,7 @@ export class WAStartupService { stack: error?.stack, name: error?.name, url: globalURL, + server_url: serverUrl, }); } } @@ -1508,6 +1515,7 @@ export class WAStartupService { sender, { text: message['conversation'], + mentions, } as unknown as AnyMessageContent, option as unknown as MiscMessageGenerationOptions, ); From 0cb87e6ed92b6aa13543eab89f849dcc83e74352 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 17 Jul 2023 15:37:49 -0300 Subject: [PATCH 21/48] feat: Created automation for creating instances in the chatwoot bot with the command #inbox_whatsapp: --- CHANGELOG.md | 1 + .../controllers/chatwoot.controller.ts | 2 +- src/whatsapp/services/chatwoot.service.ts | 39 ++++++++++++++++++- src/whatsapp/services/whatsapp.service.ts | 2 +- src/whatsapp/whatsapp.module.ts | 2 +- 5 files changed, 42 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20c8772a..a51323a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Added messages.delete event * Added restart instance endpoint +* Created automation for creating instances in the chatwoot bot with the command #inbox_whatsapp: ### Fixed diff --git a/src/whatsapp/controllers/chatwoot.controller.ts b/src/whatsapp/controllers/chatwoot.controller.ts index d66901ef..de0aef7a 100644 --- a/src/whatsapp/controllers/chatwoot.controller.ts +++ b/src/whatsapp/controllers/chatwoot.controller.ts @@ -90,7 +90,7 @@ export class ChatwootController { logger.verbose( 'requested receiveWebhook from ' + instance.instanceName + ' instance', ); - const chatwootService = new ChatwootService(waMonitor); + const chatwootService = new ChatwootService(waMonitor, this.configService); return chatwootService.receiveWebhook(instance, data); } diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 384cedd8..2493e334 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -12,6 +12,7 @@ import mimeTypes from 'mime-types'; import { SendAudioDto } from '../dto/sendMessage.dto'; import { SendMediaDto } from '../dto/sendMessage.dto'; import { ROOT_DIR } from '../../config/path.config'; +import { ConfigService, HttpServer } from '../../config/env.config'; export class ChatwootService { private messageCacheFile: string; @@ -21,7 +22,10 @@ export class ChatwootService { private provider: any; - constructor(private readonly waMonitor: WAMonitoringService) { + constructor( + private readonly waMonitor: WAMonitoringService, + private readonly configService: ConfigService, + ) { this.messageCache = new Set(); } @@ -981,6 +985,39 @@ export class ChatwootService { await waInstance?.client?.logout('Log out instance: ' + instance.instanceName); await waInstance?.client?.ws?.close(); } + + if (command.includes('#inbox_whatsapp')) { + console.log('command include #inbox_whatsapp'); + + const urlServer = this.configService.get('SERVER').URL; + const apiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; + + console.log('url server: ' + urlServer); + console.log('api key: ' + apiKey); + const data = { + instanceName: command.split(':')[1], + qrcode: true, + chatwoot_account_id: this.provider.account_id, + chatwoot_token: this.provider.token, + chatwoot_url: this.provider.url, + chatwoot_sign_msg: this.provider.sign_msg, + }; + + const config = { + method: 'post', + maxBodyLength: Infinity, + url: `${urlServer}/instance/create`, + headers: { + 'Content-Type': 'application/json', + apikey: apiKey, + }, + data: data, + }; + + const { data: response } = await axios.request(config); + + console.log(response); + } } if ( diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index fbe5f100..fc5ae8b9 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -149,7 +149,7 @@ export class WAStartupService { private endSession = false; private logBaileys = this.configService.get('LOG').BAILEYS; - private chatwootService = new ChatwootService(waMonitor); + private chatwootService = new ChatwootService(waMonitor, this.configService); public set instanceName(name: string) { this.logger.verbose(`Initializing instance '${name}'`); diff --git a/src/whatsapp/whatsapp.module.ts b/src/whatsapp/whatsapp.module.ts index c57b9bf8..46f8ecd1 100644 --- a/src/whatsapp/whatsapp.module.ts +++ b/src/whatsapp/whatsapp.module.ts @@ -72,7 +72,7 @@ const webhookService = new WebhookService(waMonitor); export const webhookController = new WebhookController(webhookService); -const chatwootService = new ChatwootService(waMonitor); +const chatwootService = new ChatwootService(waMonitor, configService); export const chatwootController = new ChatwootController(chatwootService, configService); From 0b07fb6a495d38cf5baf70017524d5b48974df4a Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 17 Jul 2023 15:40:46 -0300 Subject: [PATCH 22/48] fix: fixed bug that saved contacts from groups came without number in chatwoot --- CHANGELOG.md | 1 + src/whatsapp/services/chatwoot.service.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a51323a0..b805bb1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ * Adjusts in Dockerfile * Adjusts in returns in endpoints chatwoot and webhook * Fixed ghost mentions in send text message +* Fixed bug that saved contacts from groups came without number in chatwoot # 1.2.2 (2023-07-15 09:36) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 2493e334..ff3e069f 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -437,7 +437,7 @@ export class ChatwootService { instance, body.key.participant.split('@')[0], filterInbox.id, - isGroup, + false, body.pushName, picture_url.profilePictureUrl || null, ); From 7e996ad6fad43a0d6ccbd47b560d7ab4bd98a3e8 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 18 Jul 2023 10:56:26 -0300 Subject: [PATCH 23/48] fix: change Baileys version, fixed problem to receive csat in chatwoot --- package.json | 2 +- src/whatsapp/services/chatwoot.service.ts | 7 ++++++- src/whatsapp/services/whatsapp.service.ts | 6 ++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 5feef990..1e577870 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "@ffmpeg-installer/ffmpeg": "^1.1.0", "@figuro/chatwoot-sdk": "^1.1.14", "@hapi/boom": "^10.0.1", - "@whiskeysockets/baileys": "github:DavidsonGomes/Baileys", + "@whiskeysockets/baileys": "^6.4.0", "axios": "^1.3.5", "class-validator": "^0.13.2", "compression": "^1.7.4", diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index ff3e069f..2f75b11e 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1096,7 +1096,12 @@ export class ChatwootService { } } - if (body.message_type === 'template' && body.content_type === 'input_csat') { + if ( + body.message_type === 'template' && + body.content_type === 'input_csat' && + body.event === 'message_created' + ) { + console.log(body); this.logger.verbose('check if is csat'); const data: SendTextDto = { diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index fc5ae8b9..3a0b5280 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1305,6 +1305,7 @@ export class WAStartupService { const regexp = new RegExp(/^(\d{2})(\d{2})\d{1}(\d{8})$/); if (regexp.test(jid)) { const match = regexp.exec(jid); + if (match && (match[1] === '52' || match[1] === '54')) { const joker = Number.parseInt(match[3][0]); const ddd = Number.parseInt(match[2]); @@ -1360,6 +1361,7 @@ export class WAStartupService { } const formattedMXARNumber = this.formatMXOrARNumber(number); + console.log(formattedMXARNumber, number); if (formattedMXARNumber !== number) { this.logger.verbose( @@ -1491,7 +1493,7 @@ export class WAStartupService { !message['poll'] && !message['sticker'] && !message['conversation'] && - !sender.includes('@broadcast') + sender !== 'status@broadcast' ) { if (!message['audio']) { this.logger.verbose('Sending message'); @@ -1521,7 +1523,7 @@ export class WAStartupService { ); } - if (sender.includes('@broadcast')) { + if (sender === 'status@broadcast') { this.logger.verbose('Sending message'); return await this.client.sendMessage( sender, From 718563fe6a2892e8d3a02c5c747df02d69f92c9a Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 18 Jul 2023 10:58:53 -0300 Subject: [PATCH 24/48] fix: adjusts in docker files --- CHANGELOG.md | 2 + Docker/mongodb/docker-compose.yaml | 1 - Docker/redis/docker-compose.yaml | 1 - docker-compose-full.yaml | 73 ------------------------------ docker-compose.yaml | 1 - 5 files changed, 2 insertions(+), 76 deletions(-) delete mode 100644 docker-compose-full.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index b805bb1f..62d64ba0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * Added messages.delete event * Added restart instance endpoint * Created automation for creating instances in the chatwoot bot with the command #inbox_whatsapp: +* Change Baileys version to: 6.4.0 ### Fixed @@ -18,6 +19,7 @@ * Adjusts in returns in endpoints chatwoot and webhook * Fixed ghost mentions in send text message * Fixed bug that saved contacts from groups came without number in chatwoot +* Fixed problem to receive csat in chatwoot # 1.2.2 (2023-07-15 09:36) diff --git a/Docker/mongodb/docker-compose.yaml b/Docker/mongodb/docker-compose.yaml index de1b7e2b..698ca50c 100644 --- a/Docker/mongodb/docker-compose.yaml +++ b/Docker/mongodb/docker-compose.yaml @@ -37,6 +37,5 @@ volumes: networks: evolution-net: - name: evolution-net external: true \ No newline at end of file diff --git a/Docker/redis/docker-compose.yaml b/Docker/redis/docker-compose.yaml index dce371f2..6409b851 100644 --- a/Docker/redis/docker-compose.yaml +++ b/Docker/redis/docker-compose.yaml @@ -25,5 +25,4 @@ volumes: networks: evolution-net: - name: evolution-net external: true diff --git a/docker-compose-full.yaml b/docker-compose-full.yaml deleted file mode 100644 index 9b108101..00000000 --- a/docker-compose-full.yaml +++ /dev/null @@ -1,73 +0,0 @@ -version: '3.3' - -services: - redis: - image: redis:latest - container_name: redis - ports: - - 6379:6379 - - rebrow: - image: marian/rebrow - ports: - - 5001:5001 - links: - - redis - - mongodb: - container_name: mongodb - image: mongo - restart: always - volumes: - - evolution_mongodb_data:/data/db - - evolution_mongodb_configdb:/data/configdb - ports: - - 27017:27017 - environment: - MONGO_INITDB_ROOT_USERNAME: root - MONGO_INITDB_ROOT_PASSWORD: root - expose: - - 27017 - - mongo-express: - image: mongo-express - environment: - ME_CONFIG_BASICAUTH_USERNAME: root - ME_CONFIG_BASICAUTH_PASSWORD: root - ME_CONFIG_MONGODB_SERVER: mongodb - ME_CONFIG_MONGODB_ADMINUSERNAME: root - ME_CONFIG_MONGODB_ADMINPASSWORD: root - ports: - - 8081:8081 - links: - - mongodb - api: - container_name: evolution_api - image: evolution/api:local - restart: always - ports: - - 8080:8080 - volumes: - - evolution_instances:/evolution/instances - - evolution_store:/evolution/store - env_file: - - ./Docker/.env - command: ['node', './dist/src/main.js'] - expose: - - 8080 - links: - - mongodb - - redis - -volumes: - evolution_instances: - evolution_store: - evolution_mongodb_data: - evolution_mongodb_configdb: - evolution_redis: - -networks: - default: - external: - name: evolution-net - \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index 51f5bd43..c6d1bc73 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -22,6 +22,5 @@ volumes: networks: evolution-net: - name: evolution-net external: true \ No newline at end of file From f4af3eaf5d8a0e233723e5846830e592889f84c6 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 18 Jul 2023 11:00:40 -0300 Subject: [PATCH 25/48] fix: adjusts in docker files --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62d64ba0..a9209058 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ * Added validations in create instance * Removed link preview endpoint, now it's done automatically from sending conventional text * Added group membership validation before sending message to groups -* Adjusts in Dockerfile +* Adjusts in docker files * Adjusts in returns in endpoints chatwoot and webhook * Fixed ghost mentions in send text message * Fixed bug that saved contacts from groups came without number in chatwoot From 19940953e2f13588abc8aa15a2898d50d37ebc61 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 18 Jul 2023 11:21:55 -0300 Subject: [PATCH 26/48] fix: Fixed require fileName for document only in base64 for send media message --- CHANGELOG.md | 1 + src/whatsapp/controllers/sendMessage.controller.ts | 10 ++++++++-- src/whatsapp/services/whatsapp.service.ts | 3 ++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9209058..613f0838 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ * Fixed ghost mentions in send text message * Fixed bug that saved contacts from groups came without number in chatwoot * Fixed problem to receive csat in chatwoot +* Fixed require fileName for document only in base64 for send media message # 1.2.2 (2023-07-15 09:36) diff --git a/src/whatsapp/controllers/sendMessage.controller.ts b/src/whatsapp/controllers/sendMessage.controller.ts index e80cbfcf..fb942a9c 100644 --- a/src/whatsapp/controllers/sendMessage.controller.ts +++ b/src/whatsapp/controllers/sendMessage.controller.ts @@ -30,9 +30,15 @@ export class SendMessageController { public async sendMedia({ instanceName }: InstanceDto, data: SendMediaDto) { logger.verbose('requested sendMedia from ' + instanceName + ' instance'); - if (isBase64(data?.mediaMessage?.media) && !data?.mediaMessage?.fileName) { - throw new BadRequestException('For bse64 the file name must be informed.'); + + if ( + isBase64(data?.mediaMessage?.media) && + !data?.mediaMessage?.fileName && + data?.mediaMessage?.mediatype === 'document' + ) { + throw new BadRequestException('For base64 the file name must be informed.'); } + logger.verbose( 'isURL: ' + isURL(data?.mediaMessage?.media) + diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 3a0b5280..6cb85857 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1361,7 +1361,6 @@ export class WAStartupService { } const formattedMXARNumber = this.formatMXOrARNumber(number); - console.log(formattedMXARNumber, number); if (formattedMXARNumber !== number) { this.logger.verbose( @@ -1870,6 +1869,8 @@ export class WAStartupService { this.logger.verbose('Sending media message'); const generate = await this.prepareMediaMessage(data.mediaMessage); + console.log('generate', generate); + return await this.sendMessageWithTyping( data.number, { ...generate.message }, From 819ed168daaaa4cd36f5c73d2cde4a9a643612d4 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 18 Jul 2023 11:23:40 -0300 Subject: [PATCH 27/48] fix: Fixed require fileName for document only in base64 for send media message --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 613f0838..d6c7853c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ * Added messages.delete event * Added restart instance endpoint -* Created automation for creating instances in the chatwoot bot with the command #inbox_whatsapp: +* Created automation for creating instances in the chatwoot bot with the command '#inbox_whatsapp:' * Change Baileys version to: 6.4.0 ### Fixed From c1226062b1911345b62a41c2c788325f91d35f4d Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 18 Jul 2023 11:25:34 -0300 Subject: [PATCH 28/48] test: contacts update --- src/whatsapp/services/chatwoot.service.ts | 46 +++++++++++------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 2f75b11e..17ccf19b 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1444,29 +1444,29 @@ export class ChatwootService { } } - if (event === 'contacts.update') { - this.logger.verbose('event contacts.update'); - const data = body; - - if (data.length) { - this.logger.verbose('contacts found'); - for (const item of data) { - const number = item.id.split('@')[0]; - const photo = item.profilePictureUrl || null; - this.logger.verbose('find contact in chatwoot'); - const find = await this.findContact(instance, number); - - if (find) { - this.logger.verbose('contact found'); - - this.logger.verbose('update contact in chatwoot'); - await this.updateContact(instance, find.id, { - avatar_url: photo, - }); - } - } - } - } + // if (event === 'contacts.update') { + // this.logger.verbose('event contacts.update'); + // const data = body; + + // if (data.length) { + // this.logger.verbose('contacts found'); + // for (const item of data) { + // const number = item.id.split('@')[0]; + // const photo = item.profilePictureUrl || null; + // this.logger.verbose('find contact in chatwoot'); + // const find = await this.findContact(instance, number); + + // if (find) { + // this.logger.verbose('contact found'); + + // this.logger.verbose('update contact in chatwoot'); + // await this.updateContact(instance, find.id, { + // avatar_url: photo, + // }); + // } + // } + // } + // } if (event === 'qrcode.updated') { this.logger.verbose('event qrcode.updated'); From 0db8f7295b493654f65ec83351c92ad05eb5588d Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 18 Jul 2023 12:33:55 -0300 Subject: [PATCH 29/48] feat: Send contact in chatwoot --- CHANGELOG.md | 1 + package.json | 1 + src/main.ts | 29 ++++++++++ src/whatsapp/services/chatwoot.service.ts | 67 +++++++++++++++-------- 4 files changed, 75 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6c7853c..ae69826a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ * Fixed bug that saved contacts from groups came without number in chatwoot * Fixed problem to receive csat in chatwoot * Fixed require fileName for document only in base64 for send media message +* Bug fix when sending mobile message change contact name to number in chatwoot # 1.2.2 (2023-07-15 09:36) diff --git a/package.json b/package.json index 1e577870..5c182838 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "@ffmpeg-installer/ffmpeg": "^1.1.0", "@figuro/chatwoot-sdk": "^1.1.14", "@hapi/boom": "^10.0.1", + "@sentry/node": "^7.59.2", "@whiskeysockets/baileys": "^6.4.0", "axios": "^1.3.5", "class-validator": "^0.13.2", diff --git a/src/main.ts b/src/main.ts index 7d16b5c6..ac66e7b5 100644 --- a/src/main.ts +++ b/src/main.ts @@ -10,6 +10,7 @@ import { waMonitor } from './whatsapp/whatsapp.module'; import { HttpStatus, router } from './whatsapp/routers/index.router'; import 'express-async-errors'; import { ServerUP } from './utils/server-up'; +import * as Sentry from '@sentry/node'; function initWA() { waMonitor.loadInstance(); @@ -19,6 +20,27 @@ function bootstrap() { const logger = new Logger('SERVER'); const app = express(); + // Sentry.init({ + // dsn: '', + // integrations: [ + // // enable HTTP calls tracing + // new Sentry.Integrations.Http({ tracing: true }), + // // enable Express.js middleware tracing + // new Sentry.Integrations.Express({ app }), + // // Automatically instrument Node.js libraries and frameworks + // ...Sentry.autoDiscoverNodePerformanceMonitoringIntegrations(), + // ], + + // // Set tracesSampleRate to 1.0 to capture 100% + // // of transactions for performance monitoring. + // // We recommend adjusting this value in production + // tracesSampleRate: 1.0, + // }); + + // app.use(Sentry.Handlers.requestHandler()); + + // app.use(Sentry.Handlers.tracingHandler()); + app.use( cors({ origin(requestOrigin, callback) { @@ -43,6 +65,13 @@ function bootstrap() { app.use('/', router); + // app.use(Sentry.Handlers.errorHandler()); + + // app.use(function onError(err, req, res, next) { + // res.statusCode = 500; + // res.end(res.sentry + '\n'); + // }); + app.use( (err: Error, req: Request, res: Response, next: NextFunction) => { if (err) { diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 17ccf19b..d93ab3be 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -453,21 +453,24 @@ export class ChatwootService { const findContact = await this.findContact(instance, chatId); let contact: any; - - if (findContact) { - contact = await this.updateContact(instance, findContact.id, { - name: nameContact, - avatar_url: picture_url.profilePictureUrl || null, - }); + if (body.key.fromMe) { + contact = findContact; } else { - contact = await this.createContact( - instance, - chatId, - filterInbox.id, - isGroup, - nameContact, - picture_url.profilePictureUrl || null, - ); + if (findContact) { + contact = await this.updateContact(instance, findContact.id, { + name: nameContact, + avatar_url: picture_url.profilePictureUrl || null, + }); + } else { + contact = await this.createContact( + instance, + chatId, + filterInbox.id, + isGroup, + nameContact, + picture_url.profilePictureUrl || null, + ); + } } if (!contact) { @@ -475,7 +478,8 @@ export class ChatwootService { return null; } - const contactId = contact.payload.id || contact.payload.contact.id; + const contactId = + contact?.payload?.id || contact?.payload?.contact?.id || contact?.id; if (!body.key.fromMe && contact.name === chatId && nameContact !== chatId) { this.logger.verbose('update contact name in chatwoot'); @@ -987,13 +991,9 @@ export class ChatwootService { } if (command.includes('#inbox_whatsapp')) { - console.log('command include #inbox_whatsapp'); - const urlServer = this.configService.get('SERVER').URL; const apiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; - console.log('url server: ' + urlServer); - console.log('api key: ' + apiKey); const data = { instanceName: command.split(':')[1], qrcode: true, @@ -1014,9 +1014,7 @@ export class ChatwootService { data: data, }; - const { data: response } = await axios.request(config); - - console.log(response); + await axios.request(config); } } @@ -1101,7 +1099,6 @@ export class ChatwootService { body.content_type === 'input_csat' && body.event === 'message_created' ) { - console.log(body); this.logger.verbose('check if is csat'); const data: SendTextDto = { @@ -1161,6 +1158,7 @@ export class ChatwootService { documentWithCaptionMessage: msg.documentWithCaptionMessage?.message?.documentMessage?.caption, audioMessage: msg.audioMessage?.caption, + contactMessage: msg.contactMessage?.vcard, }; this.logger.verbose('type message: ' + types); @@ -1174,6 +1172,25 @@ export class ChatwootService { const result = typeKey ? types[typeKey] : undefined; + if (typeKey === 'contactMessage') { + const vCardData = result.split('\n'); + const contactInfo = {}; + + vCardData.forEach((line) => { + const [key, value] = line.split(':'); + if (key && value) { + contactInfo[key] = value; + } + }); + + const formattedContact = `**Contact:** + **name:** ${contactInfo['FN']} + **number:** ${contactInfo['item1.TEL;waid=5511952801378']}`; + + this.logger.verbose('message content: ' + formattedContact); + return formattedContact; + } + this.logger.verbose('message content: ' + result); return result; @@ -1184,8 +1201,12 @@ export class ChatwootService { const types = this.getTypeMessage(msg); + console.log('types', types); + const messageContent = this.getMessageContent(types); + console.log('messageContent', messageContent); + this.logger.verbose('conversation message: ' + messageContent); return messageContent; From 44bf39f7b7ad1f71f22b2fcdc32b91c9a3c852d4 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 18 Jul 2023 12:36:26 -0300 Subject: [PATCH 30/48] feat: Send contact in chatwoot --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae69826a..48acae3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Added restart instance endpoint * Created automation for creating instances in the chatwoot bot with the command '#inbox_whatsapp:' * Change Baileys version to: 6.4.0 +* Send contact in chatwoot ### Fixed From 7cacf7bbaf28e441c4ee2e86652ae9f8609f255e Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 18 Jul 2023 12:47:03 -0300 Subject: [PATCH 31/48] fix: Bug fix when connecting whatsapp does not send confirmation message --- CHANGELOG.md | 1 + src/whatsapp/services/chatwoot.service.ts | 3 ++- src/whatsapp/services/whatsapp.service.ts | 11 +++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48acae3d..d960aa9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ * Fixed problem to receive csat in chatwoot * Fixed require fileName for document only in base64 for send media message * Bug fix when sending mobile message change contact name to number in chatwoot +* Bug fix when connecting whatsapp does not send confirmation message # 1.2.2 (2023-07-15 09:36) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index d93ab3be..c1d800d1 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1457,7 +1457,8 @@ export class ChatwootService { if (event === 'connection.update') { this.logger.verbose('event connection.update'); - if (body.state === 'open') { + console.log('connection.update', body); + if (body.status === 'open') { const msgConnection = `🚀 Conexão realizada com sucesso!`; this.logger.verbose('send message to chatwoot'); diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 6cb85857..0acca202 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -624,6 +624,17 @@ export class WAStartupService { │ CONNECTED TO WHATSAPP │ └──────────────────────────────┘`.replace(/^ +/gm, ' '), ); + + if (this.localChatwoot.enabled) { + this.chatwootService.eventWhatsapp( + Events.CONNECTION_UPDATE, + { instanceName: this.instance.name }, + { + instance: this.instance.name, + status: 'open', + }, + ); + } } } From a9fafec79dc6e4027435794809faf0563490660b Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 18 Jul 2023 12:50:18 -0300 Subject: [PATCH 32/48] fix: Bug fix when connecting whatsapp does not send confirmation message --- 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 c1d800d1..2ccf0671 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1459,7 +1459,7 @@ export class ChatwootService { this.logger.verbose('event connection.update'); console.log('connection.update', body); if (body.status === 'open') { - const msgConnection = `🚀 Conexão realizada com sucesso!`; + const msgConnection = `🚀 Conexão estabelecida com sucesso!`; this.logger.verbose('send message to chatwoot'); await this.createBotMessage(instance, msgConnection, 'incoming'); From b3e213c133b28100b947a6a96416c2639cae64ac Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 18 Jul 2023 12:58:53 -0300 Subject: [PATCH 33/48] fix: Added replace special caracters and espaces in instanceName --- src/whatsapp/controllers/instance.controller.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index cf8678c1..f0adb3a3 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -64,7 +64,10 @@ export class InstanceController { this.repository, this.cache, ); - instance.instanceName = instanceName; + instance.instanceName = instanceName + .toLowerCase() + .replace(/[^a-z0-9]/g, '') + .replace(' ', ''); this.logger.verbose('instance: ' + instance.instanceName + ' created'); this.waMonitor.waInstances[instance.instanceName] = instance; @@ -191,7 +194,10 @@ export class InstanceController { this.repository, this.cache, ); - instance.instanceName = instanceName; + instance.instanceName = instanceName + .toLowerCase() + .replace(/[^a-z0-9]/g, '') + .replace(' ', ''); this.logger.verbose('instance: ' + instance.instanceName + ' created'); From 7b1a4554ad9bccaebf978c04150bc866967f58cd Mon Sep 17 00:00:00 2001 From: w3nder Date: Tue, 18 Jul 2023 13:08:53 -0300 Subject: [PATCH 34/48] fix: create folder store --- src/whatsapp/repository/repository.manager.ts | 65 ++++++++++--------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/src/whatsapp/repository/repository.manager.ts b/src/whatsapp/repository/repository.manager.ts index 9740b436..ca6e09c7 100644 --- a/src/whatsapp/repository/repository.manager.ts +++ b/src/whatsapp/repository/repository.manager.ts @@ -5,12 +5,13 @@ import { MessageUpRepository } from './messageUp.repository'; import { MongoClient } from 'mongodb'; import { WebhookRepository } from './webhook.repository'; import { ChatwootRepository } from './chatwoot.repository'; + import { AuthRepository } from './auth.repository'; import { Auth, ConfigService, Database } from '../../config/env.config'; import { execSync } from 'child_process'; import { join } from 'path'; +import fs from 'fs'; import { Logger } from '../../config/logger.config'; - export class RepositoryBroker { constructor( public readonly message: MessageRepository, @@ -23,7 +24,6 @@ export class RepositoryBroker { private configService: ConfigService, dbServer?: MongoClient, ) { - this.logger.verbose('initializing repository broker'); this.dbClient = dbServer; this.__init_repo_without_db__(); } @@ -38,39 +38,46 @@ export class RepositoryBroker { private __init_repo_without_db__() { this.logger.verbose('initializing repository without db'); if (!this.configService.get('DATABASE').ENABLED) { - this.logger.verbose('database is disabled'); - const storePath = join(process.cwd(), 'store'); - this.logger.verbose('creating store path: ' + storePath); - execSync( - `mkdir -p ${join( + try { + const authDir = join( storePath, 'auth', this.configService.get('AUTHENTICATION').TYPE, - )}`, - ); - - this.logger.verbose('creating chats path: ' + join(storePath, 'chats')); - execSync(`mkdir -p ${join(storePath, 'chats')}`); - - this.logger.verbose('creating contacts path: ' + join(storePath, 'contacts')); - execSync(`mkdir -p ${join(storePath, 'contacts')}`); - - this.logger.verbose('creating messages path: ' + join(storePath, 'messages')); - execSync(`mkdir -p ${join(storePath, 'messages')}`); - - this.logger.verbose('creating message-up path: ' + join(storePath, 'message-up')); - execSync(`mkdir -p ${join(storePath, 'message-up')}`); - - this.logger.verbose('creating webhook path: ' + join(storePath, 'webhook')); - execSync(`mkdir -p ${join(storePath, 'webhook')}`); - - this.logger.verbose('creating chatwoot path: ' + join(storePath, 'chatwoot')); - execSync(`mkdir -p ${join(storePath, 'chatwoot')}`); + ); + const chatsDir = join(storePath, 'chats'); + const contactsDir = join(storePath, 'contacts'); + const messagesDir = join(storePath, 'messages'); + const messageUpDir = join(storePath, 'message-up'); + const webhookDir = join(storePath, 'webhook'); + const chatwootDir = join(storePath, 'chatwoot'); - this.logger.verbose('creating temp path: ' + join(storePath, 'temp')); - execSync(`mkdir -p ${join(storePath, 'temp')}`); + // Check if directories exist, create them if not + if (!fs.existsSync(authDir)) { + fs.mkdirSync(authDir, { recursive: true }); + } + if (!fs.existsSync(chatsDir)) { + fs.mkdirSync(chatsDir, { recursive: true }); + } + if (!fs.existsSync(contactsDir)) { + fs.mkdirSync(contactsDir, { recursive: true }); + } + if (!fs.existsSync(messagesDir)) { + fs.mkdirSync(messagesDir, { recursive: true }); + } + if (!fs.existsSync(messageUpDir)) { + fs.mkdirSync(messageUpDir, { recursive: true }); + } + if (!fs.existsSync(webhookDir)) { + fs.mkdirSync(webhookDir, { recursive: true }); + } + if (!fs.existsSync(chatwootDir)) { + fs.mkdirSync(chatwootDir, { recursive: true }); + } + } catch (error) { + console.error(error); + } } } } From 69e1622e82c3f45771adff3ba42fc4cfd7763faa Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 18 Jul 2023 13:17:03 -0300 Subject: [PATCH 35/48] feat: Send contact array in chatwoot --- CHANGELOG.md | 1 + src/whatsapp/services/chatwoot.service.ts | 43 +++++++++++++++++++---- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d960aa9f..133dc37c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * Created automation for creating instances in the chatwoot bot with the command '#inbox_whatsapp:' * Change Baileys version to: 6.4.0 * Send contact in chatwoot +* Send contact array in chatwoot ### Fixed diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 2ccf0671..1997dcc5 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1159,6 +1159,7 @@ export class ChatwootService { msg.documentWithCaptionMessage?.message?.documentMessage?.caption, audioMessage: msg.audioMessage?.caption, contactMessage: msg.contactMessage?.vcard, + contactsArrayMessage: msg.contactsArrayMessage, }; this.logger.verbose('type message: ' + types); @@ -1183,14 +1184,48 @@ export class ChatwootService { } }); + const telKey = Object.keys(contactInfo).find((key) => + key.startsWith('item1.TEL;waid='), + ); + const formattedContact = `**Contact:** **name:** ${contactInfo['FN']} - **number:** ${contactInfo['item1.TEL;waid=5511952801378']}`; + **number:** ${contactInfo[telKey]}`; this.logger.verbose('message content: ' + formattedContact); return formattedContact; } + if (typeKey === 'contactsArrayMessage') { + const formattedContacts = result.contacts.map((contact) => { + const vCardData = contact.vcard.split('\n'); + const contactInfo = {}; + + vCardData.forEach((line) => { + const [key, value] = line.split(':'); + if (key && value) { + contactInfo[key] = value; + } + }); + + const telKey = Object.keys(contactInfo).find((key) => + key.startsWith('item1.TEL;waid='), + ); + + const formattedContact = `**Contact:** + **name:** ${contact.displayName} + **number:** ${contactInfo[telKey]}`; + + return formattedContact; + }); + + const formattedContactsArray = formattedContacts.join('\n\n'); + + this.logger.verbose('formatted contacts: ' + formattedContactsArray); + + return formattedContactsArray; + } + this.logger.verbose('message content: ' + result); return result; @@ -1201,12 +1236,8 @@ export class ChatwootService { const types = this.getTypeMessage(msg); - console.log('types', types); - const messageContent = this.getMessageContent(types); - console.log('messageContent', messageContent); - this.logger.verbose('conversation message: ' + messageContent); return messageContent; @@ -1457,7 +1488,7 @@ export class ChatwootService { if (event === 'connection.update') { this.logger.verbose('event connection.update'); - console.log('connection.update', body); + if (body.status === 'open') { const msgConnection = `🚀 Conexão estabelecida com sucesso!`; From 8c7b0698f32671ca78316a6b976d022f98a2b8f1 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 18 Jul 2023 14:30:40 -0300 Subject: [PATCH 36/48] feat: Added apiKey in webhook and serverUrl in fetchInstance if EXPOSE_IN_FETCH_INSTANCES: true --- CHANGELOG.md | 1 + src/whatsapp/services/monitor.service.ts | 98 +++++++++-------------- src/whatsapp/services/whatsapp.service.ts | 48 +++++++++-- 3 files changed, 81 insertions(+), 66 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 133dc37c..c2279292 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Change Baileys version to: 6.4.0 * Send contact in chatwoot * Send contact array in chatwoot +* Added apiKey in webhook and serverUrl in fetchInstance if EXPOSE_IN_FETCH_INSTANCES: true ### Fixed diff --git a/src/whatsapp/services/monitor.service.ts b/src/whatsapp/services/monitor.service.ts index 462c9f96..8b347c21 100644 --- a/src/whatsapp/services/monitor.service.ts +++ b/src/whatsapp/services/monitor.service.ts @@ -99,72 +99,54 @@ export class WAMonitoringService { if (value.connectionStatus.state === 'open') { this.logger.verbose('instance: ' + key + ' - connectionStatus: open'); - let apikey: string; + + const instanceData = { + instance: { + instanceName: key, + 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) { - this.logger.verbose( - 'instance: ' + key + ' - hash exposed in fetch instances', - ); - const tokenStore = await this.repository.auth.find(key); - apikey = tokenStore.apikey || 'Apikey not found'; - - instances.push({ - instance: { - instanceName: key, - owner: value.wuid, - profileName: (await value.getProfileName()) || 'not loaded', - profilePictureUrl: value.profilePictureUrl, - profileStatus: (await value.getProfileStatus()) || '', - status: value.connectionStatus.state, - apikey, - chatwoot, - }, - }); - } else { - this.logger.verbose( - 'instance: ' + key + ' - hash not exposed in fetch instances', - ); - instances.push({ - instance: { - instanceName: key, - owner: value.wuid, - profileName: (await value.getProfileName()) || 'not loaded', - profilePictureUrl: value.profilePictureUrl, - profileStatus: (await value.getProfileStatus()) || '', - status: value.connectionStatus.state, - }, - }); + 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, ); - let apikey: string; + + const instanceData = { + instance: { + instanceName: key, + status: value.connectionStatus.state, + }, + }; + if (this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) { - this.logger.verbose( - 'instance: ' + key + ' - hash exposed in fetch instances', - ); - const tokenStore = await this.repository.auth.find(key); - apikey = tokenStore.apikey || 'Apikey not found'; - - instances.push({ - instance: { - instanceName: key, - status: value.connectionStatus.state, - apikey, - chatwoot, - }, - }); - } else { - this.logger.verbose( - 'instance: ' + key + ' - hash not exposed in fetch instances', - ); - instances.push({ - instance: { - instanceName: key, - status: value.connectionStatus.state, - }, - }); + 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); } } } diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 0acca202..bc9d8355 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -348,6 +348,13 @@ export class WAStartupService { const transformedWe = we.replace(/_/gm, '-').toLowerCase(); const instance = this.configService.get('AUTHENTICATION').INSTANCE; + const expose = + this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES; + const tokenStore = await this.repository.auth.find(this.instanceName); + const instanceApikey = tokenStore.apikey || 'Apikey not found'; + + const globalApiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY; + if (local && instance.MODE !== 'container') { if (Array.isArray(webhookLocal) && webhookLocal.includes(we)) { this.logger.verbose('Sending data to webhook local'); @@ -360,7 +367,7 @@ export class WAStartupService { } if (this.configService.get('LOG').LEVEL.includes('WEBHOOKS')) { - this.logger.log({ + const logData = { local: WAStartupService.name + '.sendDataWebhook-local', url: baseURL, event, @@ -368,19 +375,32 @@ export class WAStartupService { data, destination: this.localWebhook.url, server_url: serverUrl, - }); + apikey: (expose && instanceApikey) || null, + }; + + if (expose && instanceApikey) { + logData['apikey'] = instanceApikey; + } + + this.logger.log(logData); } try { if (this.localWebhook.enabled && isURL(this.localWebhook.url)) { const httpService = axios.create({ baseURL }); - await httpService.post('', { + const postData = { event, instance: this.instance.name, data, destination: this.localWebhook.url, server_url: serverUrl, - }); + }; + + if (expose && instanceApikey) { + postData['apikey'] = instanceApikey; + } + + await httpService.post('', postData); } } catch (error) { this.logger.error({ @@ -421,7 +441,7 @@ export class WAStartupService { } if (this.configService.get('LOG').LEVEL.includes('WEBHOOKS')) { - this.logger.log({ + const logData = { local: WAStartupService.name + '.sendDataWebhook-global', url: globalURL, event, @@ -429,19 +449,31 @@ export class WAStartupService { data, destination: localUrl, server_url: serverUrl, - }); + }; + + if (expose && globalApiKey) { + logData['apikey'] = globalApiKey; + } + + this.logger.log(logData); } try { if (globalWebhook && globalWebhook?.ENABLED && isURL(globalURL)) { const httpService = axios.create({ baseURL: globalURL }); - await httpService.post('', { + const postData = { event, instance: this.instance.name, data, destination: localUrl, server_url: serverUrl, - }); + }; + + if (expose && globalApiKey) { + postData['apikey'] = globalApiKey; + } + + await httpService.post('', postData); } } catch (error) { this.logger.error({ From 6727b1cfca93716568b22f018e1be30429cf5841 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 18 Jul 2023 14:49:38 -0300 Subject: [PATCH 37/48] fix: Adjusts to receive contact with more numbers --- src/whatsapp/services/chatwoot.service.ts | 33 ++++++++++++++--------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 1997dcc5..67d39aee 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1174,6 +1174,7 @@ export class ChatwootService { const result = typeKey ? types[typeKey] : undefined; if (typeKey === 'contactMessage') { + console.log(result); const vCardData = result.split('\n'); const contactInfo = {}; @@ -1184,13 +1185,17 @@ export class ChatwootService { } }); - const telKey = Object.keys(contactInfo).find((key) => - key.startsWith('item1.TEL;waid='), - ); + let formattedContact = `**Contact:** + **name:** ${contactInfo['FN']}`; - const formattedContact = `**Contact:** - **name:** ${contactInfo['FN']} - **number:** ${contactInfo[telKey]}`; + let numberCount = 1; + Object.keys(contactInfo).forEach((key) => { + if (key.startsWith('item') && key.includes('TEL;waid=')) { + const phoneNumber = contactInfo[key]; + formattedContact += `\n**number ${numberCount}:** ${phoneNumber}`; + numberCount++; + } + }); this.logger.verbose('message content: ' + formattedContact); return formattedContact; @@ -1208,13 +1213,17 @@ export class ChatwootService { } }); - const telKey = Object.keys(contactInfo).find((key) => - key.startsWith('item1.TEL;waid='), - ); + let formattedContact = `**Contact:** + **name:** ${contact.displayName}`; - const formattedContact = `**Contact:** - **name:** ${contact.displayName} - **number:** ${contactInfo[telKey]}`; + let numberCount = 1; + Object.keys(contactInfo).forEach((key) => { + if (key.startsWith('item') && key.includes('TEL;waid=')) { + const phoneNumber = contactInfo[key]; + formattedContact += `\n**number ${numberCount}:** ${phoneNumber}`; + numberCount++; + } + }); return formattedContact; }); From dc432a19a3ce62c9a40893e361e607b74370e682 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 18 Jul 2023 14:57:18 -0300 Subject: [PATCH 38/48] fix: Adjusts to receive contact with more numbers --- src/whatsapp/services/chatwoot.service.ts | 1 - src/whatsapp/services/whatsapp.service.ts | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 67d39aee..bad95c92 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1174,7 +1174,6 @@ export class ChatwootService { const result = typeKey ? types[typeKey] : undefined; if (typeKey === 'contactMessage') { - console.log(result); const vCardData = result.split('\n'); const contactInfo = {}; diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index bc9d8355..18547998 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1912,8 +1912,6 @@ export class WAStartupService { this.logger.verbose('Sending media message'); const generate = await this.prepareMediaMessage(data.mediaMessage); - console.log('generate', generate); - return await this.sendMessageWithTyping( data.number, { ...generate.message }, From 584f0cbac0ff2caa8d050c8f8d6c956bda8635b1 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 18 Jul 2023 15:13:41 -0300 Subject: [PATCH 39/48] fix: Adjusts to receive contact with more numbers --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c2279292..8c2fe170 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,10 @@ * Bug fix when sending mobile message change contact name to number in chatwoot * Bug fix when connecting whatsapp does not send confirmation message +### Integrations + +- Chatwoot: v2.18.0 + # 1.2.2 (2023-07-15 09:36) ### Fixed From 1db23b5277d7fa08ad5dd7f271c7c3f679ad03d2 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 18 Jul 2023 15:53:53 -0300 Subject: [PATCH 40/48] fix: Adjusts to receive contact with no whatsapp --- src/whatsapp/services/chatwoot.service.ts | 30 +++++++++++------------ 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index bad95c92..656c3664 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -247,7 +247,7 @@ export class ChatwootService { accountId: this.provider.account_id, conversationId: conversation.id, data: { - content: '/iniciar', + content: '/init', message_type: 'outgoing', }, }); @@ -936,8 +936,8 @@ export class ChatwootService { const command = messageReceived.replace('/', ''); - if (command === 'iniciar') { - this.logger.verbose('command iniciar found'); + if (command === 'init') { + this.logger.verbose('command init found'); const state = waInstance?.connectionStatus?.state; if (state !== 'open') { @@ -947,7 +947,7 @@ export class ChatwootService { this.logger.verbose('whatsapp already connected'); await this.createBotMessage( instance, - `🚨 Instância ${body.inbox.name} já está conectada.`, + `🚨 ${body.inbox.name} instance is connected.`, 'incoming', ); } @@ -962,7 +962,7 @@ export class ChatwootService { this.logger.verbose('state not found'); await this.createBotMessage( instance, - `⚠️ Instância ${body.inbox.name} não existe.`, + `⚠️ ${body.inbox.name} instance not found.`, 'incoming', ); } @@ -971,16 +971,16 @@ export class ChatwootService { this.logger.verbose('state: ' + state + ' found'); await this.createBotMessage( instance, - `⚠️ Status da instância ${body.inbox.name}: *${state}*`, + `⚠️ ${body.inbox.name} instance status: *${state}*`, 'incoming', ); } } - if (command === 'desconectar') { - this.logger.verbose('command desconectar found'); + if (command === 'disconnect') { + this.logger.verbose('command disconnect found'); - const msgLogout = `🚨 Desconectando Whatsapp da caixa de entrada *${body.inbox.name}*: `; + const msgLogout = `🚨 Disconnecting Whatsapp from inbox *${body.inbox.name}*: `; this.logger.verbose('send message to chatwoot'); await this.createBotMessage(instance, msgLogout, 'incoming'); @@ -1189,7 +1189,7 @@ export class ChatwootService { let numberCount = 1; Object.keys(contactInfo).forEach((key) => { - if (key.startsWith('item') && key.includes('TEL;waid=')) { + if (key.startsWith('item') && key.includes('TEL')) { const phoneNumber = contactInfo[key]; formattedContact += `\n**number ${numberCount}:** ${phoneNumber}`; numberCount++; @@ -1217,7 +1217,7 @@ export class ChatwootService { let numberCount = 1; Object.keys(contactInfo).forEach((key) => { - if (key.startsWith('item') && key.includes('TEL;waid=')) { + if (key.startsWith('item') && key.includes('TEL')) { const phoneNumber = contactInfo[key]; formattedContact += `\n**number ${numberCount}:** ${phoneNumber}`; numberCount++; @@ -1488,7 +1488,7 @@ export class ChatwootService { return; } - const msgStatus = `⚡️ Status da instância ${inbox.name}: ${data.status}`; + const msgStatus = `⚡️ Instance status ${inbox.name}: ${data.status}`; this.logger.verbose('send message to chatwoot'); await this.createBotMessage(instance, msgStatus, 'incoming'); @@ -1498,7 +1498,7 @@ export class ChatwootService { this.logger.verbose('event connection.update'); if (body.status === 'open') { - const msgConnection = `🚀 Conexão estabelecida com sucesso!`; + const msgConnection = `🚀 Connection successfully established!`; this.logger.verbose('send message to chatwoot'); await this.createBotMessage(instance, msgConnection, 'incoming'); @@ -1533,7 +1533,7 @@ export class ChatwootService { this.logger.verbose('event qrcode.updated'); if (body.statusCode === 500) { this.logger.verbose('qrcode error'); - const erroQRcode = `🚨 Limite de geração de QRCode atingido, para gerar um novo QRCode, envie a mensagem /iniciar novamente.`; + const erroQRcode = `🚨 QRCode generation limit reached, to generate a new QRCode, send the /init message again.`; this.logger.verbose('send message to chatwoot'); return await this.createBotMessage(instance, erroQRcode, 'incoming'); @@ -1563,7 +1563,7 @@ export class ChatwootService { fileName, ); - const msgQrCode = `⚡️ QRCode gerado com sucesso!\n\nDigitalize este código QR nos próximos 40 segundos:`; + const msgQrCode = `⚡️ QRCode successfully generated!\n\nScan this QR code within the next 40 seconds:`; this.logger.verbose('send message to chatwoot'); await this.createBotMessage(instance, msgQrCode, 'incoming'); From a4ef9fb9b71db4923ac3f77dc7f0565b241c4e1f Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 18 Jul 2023 15:55:24 -0300 Subject: [PATCH 41/48] feat: translation set to default (english) in chatwoot --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c2fe170..1f1a3414 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * Send contact in chatwoot * Send contact array in chatwoot * Added apiKey in webhook and serverUrl in fetchInstance if EXPOSE_IN_FETCH_INSTANCES: true +* Translation set to default (english) in chatwoot ### Fixed From 41fa700fb3d86f6b4fd24339c088deab5aadc412 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 18 Jul 2023 16:01:05 -0300 Subject: [PATCH 42/48] feat: translation set to default (english) in chatwoot --- 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 656c3664..ba0c5d0b 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1558,7 +1558,7 @@ export class ChatwootService { this.logger.verbose('send qrcode to chatwoot'); await this.createBotQr( instance, - 'QRCode gerado com sucesso!', + 'QRCode successfully generated!', 'incoming', fileName, ); From 3cf0ced62e73dc0319a6e7ef62ca16577b3bffdf Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 18 Jul 2023 20:23:18 -0300 Subject: [PATCH 43/48] test: status/stories --- CHANGELOG.md | 1 + src/validate/validate.schema.ts | 4 ++-- src/whatsapp/guards/instance.guard.ts | 1 - src/whatsapp/services/chatwoot.service.ts | 4 ++-- src/whatsapp/services/whatsapp.service.ts | 16 ++++++++++++++-- 5 files changed, 19 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f1a3414..0a62e4f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ * Fixed require fileName for document only in base64 for send media message * Bug fix when sending mobile message change contact name to number in chatwoot * Bug fix when connecting whatsapp does not send confirmation message +* Fixed quoted message with id or message directly ### Integrations diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 77e05f19..2b9ce19a 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -82,8 +82,8 @@ const quotedOptionsSchema: JSONSchema7 = { remoteJid: { type: 'string' }, fromMe: { type: 'boolean', enum: [true, false] }, }, - required: ['id', 'remoteJid', 'fromMe'], - ...isNotEmpty('id', 'remoteJid'), + required: ['id'], + ...isNotEmpty('id'), }, message: { type: 'object' }, }, diff --git a/src/whatsapp/guards/instance.guard.ts b/src/whatsapp/guards/instance.guard.ts index 9e7a0e4b..1e79ff1d 100644 --- a/src/whatsapp/guards/instance.guard.ts +++ b/src/whatsapp/guards/instance.guard.ts @@ -11,7 +11,6 @@ import { import { InstanceDto } from '../dto/instance.dto'; import { cache, waMonitor } from '../whatsapp.module'; import { Database, Redis, configService } from '../../config/env.config'; -import { RedisCache } from '../../db/redis.client'; async function getInstance(instanceName: string) { const db = configService.get('DATABASE'); diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index ba0c5d0b..49fd4e7d 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -936,7 +936,7 @@ export class ChatwootService { const command = messageReceived.replace('/', ''); - if (command === 'init') { + if (command === 'init' || command === 'iniciar') { this.logger.verbose('command init found'); const state = waInstance?.connectionStatus?.state; @@ -977,7 +977,7 @@ export class ChatwootService { } } - if (command === 'disconnect') { + if (command === 'disconnect' || command === 'desconectar') { this.logger.verbose('command disconnect found'); const msgLogout = `🚨 Disconnecting Whatsapp from inbox *${body.inbox.name}*: `; diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 18547998..ba167c53 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1480,7 +1480,17 @@ export class WAStartupService { let quoted: WAMessage; if (options?.quoted) { - quoted = options?.quoted; + const m = options?.quoted; + + const msg = m?.message + ? m + : ((await this.getMessage(m.key, true)) as proto.IWebMessageInfo); + + if (!msg) { + throw 'Message not found'; + } + + quoted = msg; this.logger.verbose('Quoted message'); } @@ -1776,8 +1786,10 @@ export class WAStartupService { public async statusMessage(data: SendStatusDto) { this.logger.verbose('Sending status message'); + const status = await this.formatStatusMessage(data.statusMessage); + return await this.sendMessageWithTyping('status@broadcast', { - status: await this.formatStatusMessage(data.statusMessage), + status, }); } From aa7538066234d6810440716649246e87b77cbb72 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 19 Jul 2023 08:02:24 -0300 Subject: [PATCH 44/48] fix: Adjust in validation for mexican and argentine numbers --- CHANGELOG.md | 1 + src/whatsapp/services/whatsapp.service.ts | 51 +++++++++++++---------- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a62e4f5..2fe7eb26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ * Bug fix when sending mobile message change contact name to number in chatwoot * Bug fix when connecting whatsapp does not send confirmation message * Fixed quoted message with id or message directly +* Adjust in validation for mexican and argentine numbers ### Integrations diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index ba167c53..8fefd460 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1345,17 +1345,12 @@ export class WAStartupService { // Check if the number is MX or AR private formatMXOrARNumber(jid: string): string { - const regexp = new RegExp(/^(\d{2})(\d{2})\d{1}(\d{8})$/); - if (regexp.test(jid)) { - const match = regexp.exec(jid); + const countryCode = jid.substring(0, 2); - if (match && (match[1] === '52' || match[1] === '54')) { - const joker = Number.parseInt(match[3][0]); - const ddd = Number.parseInt(match[2]); - if (joker < 7 || ddd < 11) { - return match[0]; - } - return match[1] === '52' ? '52' + match[3] : '54' + match[3]; + if (Number(countryCode) === 52 || Number(countryCode) === 54) { + if (jid.length === 13) { + const number = countryCode + jid.substring(3); + return number; } return jid; @@ -1395,22 +1390,31 @@ export class WAStartupService { return number; } - const formattedBRNumber = this.formatBRNumber(number); - if (formattedBRNumber !== number) { - this.logger.verbose( - 'Jid created is whatsapp in format BR: ' + `${formattedBRNumber}@s.whatsapp.net`, - ); - return `${formattedBRNumber}@s.whatsapp.net`; + const countryCode = number.substring(0, 2); + + if (Number(countryCode) === 55) { + const formattedBRNumber = this.formatBRNumber(number); + if (formattedBRNumber !== number) { + this.logger.verbose( + 'Jid created is whatsapp in format BR: ' + + `${formattedBRNumber}@s.whatsapp.net`, + ); + return `${formattedBRNumber}@s.whatsapp.net`; + } } - const formattedMXARNumber = this.formatMXOrARNumber(number); + if (Number(countryCode) === 52 || Number(countryCode) === 54) { + console.log('numero mexicano'); - if (formattedMXARNumber !== number) { - this.logger.verbose( - 'Jid created is whatsapp in format MXAR: ' + - `${formattedMXARNumber}@s.whatsapp.net`, - ); - return `${formattedMXARNumber}@s.whatsapp.net`; + const formattedMXARNumber = this.formatMXOrARNumber(number); + + if (formattedMXARNumber !== number) { + this.logger.verbose( + 'Jid created is whatsapp in format MXAR: ' + + `${formattedMXARNumber}@s.whatsapp.net`, + ); + return `${formattedMXARNumber}@s.whatsapp.net`; + } } if (number.includes('-')) { @@ -2168,6 +2172,7 @@ export class WAStartupService { const onWhatsapp: OnWhatsAppDto[] = []; for await (const number of data.numbers) { const jid = this.createJid(number); + // const jid = `${number}@s.whatsapp.net`; if (isJidGroup(jid)) { const group = await this.findGroup({ groupJid: jid }, 'inner'); From f42928f88f0e74f11b067f3925fac8da04c0657a Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 19 Jul 2023 08:13:59 -0300 Subject: [PATCH 45/48] fix: Adjust in create store files --- src/whatsapp/repository/repository.manager.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/whatsapp/repository/repository.manager.ts b/src/whatsapp/repository/repository.manager.ts index ca6e09c7..cdf15498 100644 --- a/src/whatsapp/repository/repository.manager.ts +++ b/src/whatsapp/repository/repository.manager.ts @@ -39,6 +39,7 @@ export class RepositoryBroker { this.logger.verbose('initializing repository without db'); if (!this.configService.get('DATABASE').ENABLED) { const storePath = join(process.cwd(), 'store'); + this.logger.verbose('creating store path: ' + storePath); try { const authDir = join( @@ -55,28 +56,35 @@ export class RepositoryBroker { // Check if directories exist, create them if not if (!fs.existsSync(authDir)) { + this.logger.verbose('creating auth dir: ' + authDir); fs.mkdirSync(authDir, { recursive: true }); } if (!fs.existsSync(chatsDir)) { + this.logger.verbose('creating chats dir: ' + chatsDir); fs.mkdirSync(chatsDir, { recursive: true }); } if (!fs.existsSync(contactsDir)) { + this.logger.verbose('creating contacts dir: ' + contactsDir); fs.mkdirSync(contactsDir, { recursive: true }); } if (!fs.existsSync(messagesDir)) { + this.logger.verbose('creating messages dir: ' + messagesDir); fs.mkdirSync(messagesDir, { recursive: true }); } if (!fs.existsSync(messageUpDir)) { + this.logger.verbose('creating message-up dir: ' + messageUpDir); fs.mkdirSync(messageUpDir, { recursive: true }); } if (!fs.existsSync(webhookDir)) { + this.logger.verbose('creating webhook dir: ' + webhookDir); fs.mkdirSync(webhookDir, { recursive: true }); } if (!fs.existsSync(chatwootDir)) { + this.logger.verbose('creating chatwoot dir: ' + chatwootDir); fs.mkdirSync(chatwootDir, { recursive: true }); } } catch (error) { - console.error(error); + this.logger.error(error); } } } From 429d1ac1836f040a4329a621803c38128cb57620 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 19 Jul 2023 08:14:11 -0300 Subject: [PATCH 46/48] fix: Adjust in create store files --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fe7eb26..a960254f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ * Bug fix when connecting whatsapp does not send confirmation message * Fixed quoted message with id or message directly * Adjust in validation for mexican and argentine numbers +* Adjust in create store files ### Integrations From 7767a2607e92cbc3a821c68961a4a5723eecfcb6 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 19 Jul 2023 08:18:07 -0300 Subject: [PATCH 47/48] test: chatwoot --- src/whatsapp/services/chatwoot.service.ts | 24 ----------------------- src/whatsapp/services/whatsapp.service.ts | 8 -------- 2 files changed, 32 deletions(-) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 49fd4e7d..decb5822 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1505,30 +1505,6 @@ export class ChatwootService { } } - // if (event === 'contacts.update') { - // this.logger.verbose('event contacts.update'); - // const data = body; - - // if (data.length) { - // this.logger.verbose('contacts found'); - // for (const item of data) { - // const number = item.id.split('@')[0]; - // const photo = item.profilePictureUrl || null; - // this.logger.verbose('find contact in chatwoot'); - // const find = await this.findContact(instance, number); - - // if (find) { - // this.logger.verbose('contact found'); - - // this.logger.verbose('update contact in chatwoot'); - // await this.updateContact(instance, find.id, { - // avatar_url: photo, - // }); - // } - // } - // } - // } - if (event === 'qrcode.updated') { this.logger.verbose('event qrcode.updated'); if (body.statusCode === 500) { diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 8fefd460..65cb40bb 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -953,14 +953,6 @@ export class WAStartupService { this.logger.verbose('Sending data to webhook in event CONTACTS_UPDATE'); await this.sendDataWebhook(Events.CONTACTS_UPDATE, contactsRaw); - if (this.localChatwoot.enabled) { - await this.chatwootService.eventWhatsapp( - Events.CONTACTS_UPDATE, - { instanceName: this.instance.name }, - contactsRaw, - ); - } - this.logger.verbose('Updating contacts in database'); await this.repository.contact.update( contactsRaw, From 83cf859da3b665063b05e743df52610d4b855a58 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 19 Jul 2023 11:33:23 -0300 Subject: [PATCH 48/48] version: 1.3.0 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a960254f..4f8e26f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 1.3.0 (homolog) +# 1.3.0 (2023-07-19 11:33) ### Features