From 0cc1f18a7eaafaa851194a0955f5bbf9637350bf Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Mon, 24 Jul 2023 19:05:32 -0300 Subject: [PATCH 01/25] =?UTF-8?q?[BUG]=20Corre=C3=A7=C3=A3o=20de=20mencion?= =?UTF-8?q?ar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Caso seja enviado everyOne como false sem passar nada no mentioned --- src/whatsapp/services/whatsapp.service.ts | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 6c7c96f0..833637b2 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1686,20 +1686,13 @@ export class WAStartupService { if (options?.mentions) { this.logger.verbose('Mentions defined'); - if ( - !Array.isArray(options.mentions.mentioned) && - !options.mentions.everyOne - ) { - throw new BadRequestException('Mentions must be an array'); - } - - if (options.mentions.everyOne) { + if (options.mentions?.everyOne) { this.logger.verbose('Mentions everyone'); this.logger.verbose('Getting group metadata'); mentions = groupMetadata.participants.map((participant) => participant.id); this.logger.verbose('Getting group metadata for mentions'); - } else { + } else if(options.mentions?.mentioned?.length) { this.logger.verbose('Mentions manually defined'); mentions = options.mentions.mentioned.map((mention) => { const jid = this.createJid(mention); From ef4be6a612ff50465d1e48925eef14d578592b68 Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Mon, 24 Jul 2023 19:53:03 -0300 Subject: [PATCH 02/25] Start --- src/validate/validate.schema.ts | 1 + src/whatsapp/dto/group.dto.ts | 3 ++- src/whatsapp/services/whatsapp.service.ts | 11 ++++++++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 18a070ab..761f01ba 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -669,6 +669,7 @@ export const createGroupSchema: JSONSchema7 = { subject: { type: 'string' }, description: { type: 'string' }, profilePicture: { type: 'string' }, + promoteParticipants: { type: 'boolean', enum: [true, false] }, participants: { type: 'array', minItems: 1, diff --git a/src/whatsapp/dto/group.dto.ts b/src/whatsapp/dto/group.dto.ts index bc36e27f..6dfdc45c 100644 --- a/src/whatsapp/dto/group.dto.ts +++ b/src/whatsapp/dto/group.dto.ts @@ -1,7 +1,8 @@ export class CreateGroupDto { subject: string; - description?: string; participants: string[]; + description?: string; + promoteParticipants?: boolean; } export class GroupPictureDto { diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index d475988a..4f832852 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -2785,11 +2785,20 @@ export class WAStartupService { this.logger.verbose('Updating group description: ' + create.description); await this.client.groupUpdateDescription(id, create.description); } + + if (create?.promoteParticipants) { + this.logger.verbose('Prometing group participants: ' + create.description); + await this.updateGParticipant({ + groupJid: id, + action: "promote", + participants: participants + }); + } const group = await this.client.groupMetadata(id); this.logger.verbose('Getting group metadata'); - return { groupMetadata: group }; + return group; } catch (error) { this.logger.error(error); throw new InternalServerErrorException('Error creating group', error.toString()); From 58ed6f395fce5ba7a8d8c7cc15592e981204cc15 Mon Sep 17 00:00:00 2001 From: Alan Mosko Date: Mon, 24 Jul 2023 19:59:09 -0300 Subject: [PATCH 03/25] =?UTF-8?q?Valida=C3=A7=C3=A3o=20de=20Grupo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/whatsapp/services/whatsapp.service.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 833637b2..a2767d16 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1517,14 +1517,22 @@ export class WAStartupService { .split(/\:/)[0] .split('@')[0]; + // Verificação de Grupos Antigos + if(number.includes('-') && number.length >= 24){ + this.logger.verbose('Jid created is group: ' + `${number}@g.us`); + number = number.replace(/[^\d-]/g, ''); + return `${number}@g.us`; + } + + number = number.replace(/\D/g, ''); + + // Verificação de Grupos Novos if (number.length >= 18) { this.logger.verbose('Jid created is group: ' + `${number}@g.us`); number = number.replace(/[^\d-]/g, ''); return `${number}@g.us`; } - number = number.replace(/\D/g, ''); - this.logger.verbose('Jid created is whatsapp: ' + `${number}@s.whatsapp.net`); return `${number}@s.whatsapp.net`; } From 84f3f072794d054d0e7097f3495f28569b6a1147 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 20:11:15 -0300 Subject: [PATCH 04/25] fix: Fixed validation is set settings --- src/whatsapp/controllers/settings.controller.ts | 4 ---- src/whatsapp/services/whatsapp.service.ts | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/whatsapp/controllers/settings.controller.ts b/src/whatsapp/controllers/settings.controller.ts index 59031634..f538abe6 100644 --- a/src/whatsapp/controllers/settings.controller.ts +++ b/src/whatsapp/controllers/settings.controller.ts @@ -15,10 +15,6 @@ export class SettingsController { 'requested createSettings from ' + instance.instanceName + ' instance', ); - if (data.reject_call && data.msg_call.trim() == '') { - throw new BadRequestException('msg_call is required'); - } - return this.settingsService.create(instance, data); } diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 833637b2..0cfaf24c 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1692,7 +1692,7 @@ export class WAStartupService { this.logger.verbose('Getting group metadata'); mentions = groupMetadata.participants.map((participant) => participant.id); this.logger.verbose('Getting group metadata for mentions'); - } else if(options.mentions?.mentioned?.length) { + } else if (options.mentions?.mentioned?.length) { this.logger.verbose('Mentions manually defined'); mentions = options.mentions.mentioned.map((mention) => { const jid = this.createJid(mention); From c5824767c845013c83dceb735b2e13a0606985e1 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 20:11:49 -0300 Subject: [PATCH 05/25] fix: Fixed validation is set settings --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7dd59c0d..25812c6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# 1.4.2 (homolog) + +### Fixed + +* Fixed validation is set settings +* Adjusts in group validations + # 1.4.1 (2023-07-24 18:28) ### Fixed From b77f22790bb5ea17133993f005d3613193698f3a Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 20:13:18 -0300 Subject: [PATCH 06/25] fix: Fixed validation is set settings --- src/whatsapp/services/whatsapp.service.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index ade1e951..69e9562a 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1517,16 +1517,14 @@ export class WAStartupService { .split(/\:/)[0] .split('@')[0]; - // Verificação de Grupos Antigos - if(number.includes('-') && number.length >= 24){ + if (number.includes('-') && number.length >= 24) { this.logger.verbose('Jid created is group: ' + `${number}@g.us`); number = number.replace(/[^\d-]/g, ''); return `${number}@g.us`; } - + number = number.replace(/\D/g, ''); - // Verificação de Grupos Novos if (number.length >= 18) { this.logger.verbose('Jid created is group: ' + `${number}@g.us`); number = number.replace(/[^\d-]/g, ''); @@ -2782,13 +2780,13 @@ export class WAStartupService { this.logger.verbose('Updating group description: ' + create.description); await this.client.groupUpdateDescription(id, create.description); } - + if (create?.promoteParticipants) { this.logger.verbose('Prometing group participants: ' + create.description); await this.updateGParticipant({ groupJid: id, - action: "promote", - participants: participants + action: 'promote', + participants: participants, }); } From f475391ba6b3c8af8d0fbdf02819b0a7bfacee80 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 20:32:15 -0300 Subject: [PATCH 07/25] fix: Ajusts in sticker message to chatwoot --- .../controllers/instance.controller.ts | 259 +++++++++--------- src/whatsapp/repository/repository.manager.ts | 5 + src/whatsapp/services/chatwoot.service.ts | 6 +- src/whatsapp/services/whatsapp.service.ts | 7 +- 4 files changed, 141 insertions(+), 136 deletions(-) diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 7322e194..e9e690b3 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -41,77 +41,136 @@ export class InstanceController { chatwoot_url, chatwoot_sign_msg, }: InstanceDto) { - this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); + try { + this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); - if (instanceName !== instanceName.toLowerCase().replace(/[^a-z0-9]/g, '')) { - throw new BadRequestException( - 'The instance name must be lowercase and without special characters', - ); - } - - this.logger.verbose('checking duplicate token'); - await this.authService.checkDuplicateToken(token); - - this.logger.verbose('creating instance'); - const instance = new WAStartupService( - this.configService, - this.eventEmitter, - this.repository, - this.cache, - ); - instance.instanceName = instanceName - .toLowerCase() - .replace(/[^a-z0-9]/g, '') - .replace(' ', ''); - - this.logger.verbose('instance: ' + instance.instanceName + ' created'); - - this.waMonitor.waInstances[instance.instanceName] = instance; - this.waMonitor.delInstanceTime(instance.instanceName); - - this.logger.verbose('generating hash'); - const hash = await this.authService.generateHash( - { - instanceName: instance.instanceName, - }, - token, - ); - - this.logger.verbose('hash: ' + hash + ' generated'); - - let getEvents: string[]; - - if (webhook) { - if (!isURL(webhook, { require_tld: false })) { - throw new BadRequestException('Invalid "url" property in webhook'); + if (instanceName !== instanceName.toLowerCase().replace(/[^a-z0-9]/g, '')) { + throw new BadRequestException( + 'The instance name must be lowercase and without special characters', + ); } - this.logger.verbose('creating webhook'); - try { - this.webhookService.create(instance, { - enabled: true, - url: webhook, - events, + this.logger.verbose('checking duplicate token'); + await this.authService.checkDuplicateToken(token); + + this.logger.verbose('creating instance'); + const instance = new WAStartupService( + this.configService, + this.eventEmitter, + this.repository, + this.cache, + ); + instance.instanceName = instanceName + .toLowerCase() + .replace(/[^a-z0-9]/g, '') + .replace(' ', ''); + + this.logger.verbose('instance: ' + instance.instanceName + ' created'); + + this.waMonitor.waInstances[instance.instanceName] = instance; + this.waMonitor.delInstanceTime(instance.instanceName); + + this.logger.verbose('generating hash'); + const hash = await this.authService.generateHash( + { + instanceName: instance.instanceName, + }, + token, + ); + + this.logger.verbose('hash: ' + hash + ' generated'); + + 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, { + enabled: true, + url: webhook, + events, + webhook_by_events, + }); + + getEvents = (await this.webhookService.find(instance)).events; + } catch (error) { + this.logger.log(error); + } + } + + if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) { + let getQrcode: wa.QrCode; + + if (qrcode) { + this.logger.verbose('creating qrcode'); + await instance.connectToWhatsapp(number); + await delay(5000); + getQrcode = instance.qrCode; + } + + const result = { + instance: { + instanceName: instance.instanceName, + status: 'created', + }, + hash, + webhook, webhook_by_events, + events: getEvents, + qrcode: getQrcode, + }; + + this.logger.verbose('instance created'); + this.logger.verbose(result); + + return result; + } + + if (!chatwoot_account_id) { + throw new BadRequestException('account_id is required'); + } + + if (!chatwoot_token) { + throw new BadRequestException('token is required'); + } + + if (!chatwoot_url) { + throw new BadRequestException('url is required'); + } + + if (!isURL(chatwoot_url, { require_tld: false })) { + throw new BadRequestException('Invalid "url" property in chatwoot'); + } + + const urlServer = this.configService.get('SERVER').URL; + + try { + this.chatwootService.create(instance, { + enabled: true, + account_id: chatwoot_account_id, + token: chatwoot_token, + url: chatwoot_url, + sign_msg: chatwoot_sign_msg || false, + name_inbox: instance.instanceName, + number, }); - getEvents = (await this.webhookService.find(instance)).events; + this.chatwootService.initInstanceChatwoot( + instance, + instance.instanceName, + `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + qrcode, + number, + ); } catch (error) { this.logger.log(error); } - } - if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) { - let getQrcode: wa.QrCode; - - if (qrcode) { - this.logger.verbose('creating qrcode'); - await instance.connectToWhatsapp(number); - await delay(5000); - getQrcode = instance.qrCode; - } - - const result = { + return { instance: { instanceName: instance.instanceName, status: 'created', @@ -120,75 +179,21 @@ export class InstanceController { webhook, webhook_by_events, events: getEvents, - qrcode: getQrcode, + chatwoot: { + enabled: true, + account_id: chatwoot_account_id, + token: chatwoot_token, + url: chatwoot_url, + sign_msg: chatwoot_sign_msg || false, + number, + name_inbox: instance.instanceName, + webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, + }, }; - - this.logger.verbose('instance created'); - this.logger.verbose(result); - - return result; - } - - if (!chatwoot_account_id) { - throw new BadRequestException('account_id is required'); - } - - if (!chatwoot_token) { - throw new BadRequestException('token is required'); - } - - if (!chatwoot_url) { - throw new BadRequestException('url is required'); - } - - if (!isURL(chatwoot_url, { require_tld: false })) { - throw new BadRequestException('Invalid "url" property in chatwoot'); - } - - const urlServer = this.configService.get('SERVER').URL; - - try { - this.chatwootService.create(instance, { - enabled: true, - account_id: chatwoot_account_id, - token: chatwoot_token, - url: chatwoot_url, - sign_msg: chatwoot_sign_msg || false, - name_inbox: instance.instanceName, - number, - }); - - this.chatwootService.initInstanceChatwoot( - instance, - instance.instanceName, - `${urlServer}/chatwoot/webhook/${instance.instanceName}`, - qrcode, - number, - ); } catch (error) { - this.logger.log(error); + console.log(error); + return { error: true, message: error.toString() }; } - - return { - instance: { - instanceName: instance.instanceName, - status: 'created', - }, - hash, - webhook, - webhook_by_events, - events: getEvents, - chatwoot: { - enabled: true, - account_id: chatwoot_account_id, - token: chatwoot_token, - url: chatwoot_url, - sign_msg: chatwoot_sign_msg || false, - number, - name_inbox: instance.instanceName, - webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, - }, - }; } public async connectToWhatsapp({ instanceName, number = null }: InstanceDto) { diff --git a/src/whatsapp/repository/repository.manager.ts b/src/whatsapp/repository/repository.manager.ts index dde636c7..d506cc46 100644 --- a/src/whatsapp/repository/repository.manager.ts +++ b/src/whatsapp/repository/repository.manager.ts @@ -102,7 +102,12 @@ export class RepositoryBroker { this.logger.verbose('creating store path: ' + storePath); const tempDir = join(storePath, 'temp'); + const chatwootDir = join(storePath, 'chatwoot'); + if (!fs.existsSync(chatwootDir)) { + this.logger.verbose('creating chatwoot dir: ' + chatwootDir); + fs.mkdirSync(chatwootDir, { recursive: true }); + } if (!fs.existsSync(tempDir)) { this.logger.verbose('creating temp dir: ' + tempDir); fs.mkdirSync(tempDir, { recursive: true }); diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index c77162ad..6e55d145 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1179,7 +1179,7 @@ export class ChatwootService { videoMessage: msg.videoMessage?.caption, extendedTextMessage: msg.extendedTextMessage?.text, messageContextInfo: msg.messageContextInfo?.stanzaId, - stickerMessage: msg.stickerMessage?.fileSha256.toString('base64'), + stickerMessage: undefined, documentMessage: msg.documentMessage?.caption, documentWithCaptionMessage: msg.documentWithCaptionMessage?.message?.documentMessage?.caption, @@ -1199,10 +1199,6 @@ export class ChatwootService { const result = typeKey ? types[typeKey] : undefined; - if (typeKey === 'stickerMessage') { - return null; - } - if (typeKey === 'contactMessage') { const vCardData = result.split('\n'); const contactInfo = {}; diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 69e9562a..ff6fdd71 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -116,16 +116,15 @@ import { useMultiFileAuthStateDb } from '../../utils/use-multi-file-auth-state-d import Long from 'long'; import { WebhookRaw } from '../models/webhook.model'; import { ChatwootRaw } from '../models/chatwoot.model'; +import { SettingsRaw } from '../models'; import { dbserver } from '../../db/db.connect'; import NodeCache from 'node-cache'; import { useMultiFileAuthStateRedisDb } from '../../utils/use-multi-file-auth-state-redis-db'; import sharp from 'sharp'; import { RedisCache } from '../../db/redis.client'; import { Log } from '../../config/env.config'; -import ProxyAgent from 'proxy-agent'; import { ChatwootService } from './chatwoot.service'; import { waMonitor } from '../whatsapp.module'; -import { SettingsRaw } from '../models'; export class WAStartupService { constructor( @@ -382,7 +381,7 @@ export class WAStartupService { if (!data) { this.logger.verbose('Settings not found'); - throw new NotFoundException('Settings not found'); + return null; } this.logger.verbose(`Settings url: ${data.reject_call}`); @@ -1129,7 +1128,7 @@ export class WAStartupService { received.messageTimestamp = received.messageTimestamp?.toNumber(); } - if (settings.groups_ignore && received.key.remoteJid.includes('@g.us')) { + if (settings?.groups_ignore && received.key.remoteJid.includes('@g.us')) { this.logger.verbose('group ignored'); return; } From c76334a68aab4622d75abd905bbd59eaee8e2fa9 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 20:32:29 -0300 Subject: [PATCH 08/25] fix: Ajusts in sticker message to chatwoot --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 25812c6e..cddb23a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Fixed validation is set settings * Adjusts in group validations +* Ajusts in sticker message to chatwoot # 1.4.1 (2023-07-24 18:28) From 4d9ca4b4511ba997f28b4efa764b9079a180bcb4 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 24 Jul 2023 20:52:34 -0300 Subject: [PATCH 09/25] version: 1.4.2 --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cddb23a1..7429fddc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 1.4.2 (homolog) +# 1.4.2 (2023-07-24 20:52) ### Fixed diff --git a/package.json b/package.json index 1145676d..6489b86c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.4.1", + "version": "1.4.2", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": { From a12231a0aa003a01510cec3dc7db5d8e430fb523 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 25 Jul 2023 09:57:28 -0300 Subject: [PATCH 10/25] fix: Adjusts in settings with options always_online, read_messages and read_status --- CHANGELOG.md | 6 +++++ src/validate/validate.schema.ts | 23 ++++++++++++++---- src/whatsapp/dto/chat.dto.ts | 2 +- src/whatsapp/dto/settings.dto.ts | 3 +++ src/whatsapp/models/settings.model.ts | 6 +++++ src/whatsapp/services/whatsapp.service.ts | 29 +++++++++++++++++++++-- src/whatsapp/types/wa.types.ts | 3 +++ 7 files changed, 65 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7429fddc..bc6da5f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.4.3 (homolog) + +### Fixed + +* Adjusts in settings with options always_online, read_messages and read_status + # 1.4.2 (2023-07-24 20:52) ### Fixed diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 3c1f8d0a..318835b1 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -455,7 +455,7 @@ export const readMessageSchema: JSONSchema7 = { $id: v4(), type: 'object', properties: { - readMessages: { + read_messages: { type: 'array', minItems: 1, uniqueItems: true, @@ -470,7 +470,7 @@ export const readMessageSchema: JSONSchema7 = { }, }, }, - required: ['readMessages'], + required: ['read_messages'], }; export const privacySettingsSchema: JSONSchema7 = { @@ -884,7 +884,22 @@ export const settingsSchema: JSONSchema7 = { reject_call: { type: 'boolean', enum: [true, false] }, msg_call: { type: 'string' }, groups_ignore: { type: 'boolean', enum: [true, false] }, + always_online: { type: 'boolean', enum: [true, false] }, + read_messages: { type: 'boolean', enum: [true, false] }, + read_status: { type: 'boolean', enum: [true, false] }, }, - required: ['reject_call'], - ...isNotEmpty('reject_call'), + required: [ + 'reject_call', + 'groups_ignore', + 'always_online', + 'read_messages', + 'read_status', + ], + ...isNotEmpty( + 'reject_call', + 'groups_ignore', + 'always_online', + 'read_messages', + 'read_status', + ), }; diff --git a/src/whatsapp/dto/chat.dto.ts b/src/whatsapp/dto/chat.dto.ts index 5af66a5e..4681ef76 100644 --- a/src/whatsapp/dto/chat.dto.ts +++ b/src/whatsapp/dto/chat.dto.ts @@ -59,7 +59,7 @@ class Key { remoteJid: string; } export class ReadMessageDto { - readMessages: Key[]; + read_messages: Key[]; } class LastMessage { diff --git a/src/whatsapp/dto/settings.dto.ts b/src/whatsapp/dto/settings.dto.ts index 20a6cba0..594ab3a4 100644 --- a/src/whatsapp/dto/settings.dto.ts +++ b/src/whatsapp/dto/settings.dto.ts @@ -2,4 +2,7 @@ export class SettingsDto { reject_call?: boolean; msg_call?: string; groups_ignore?: boolean; + always_online?: boolean; + read_messages?: boolean; + read_status?: boolean; } diff --git a/src/whatsapp/models/settings.model.ts b/src/whatsapp/models/settings.model.ts index b5eb7fe7..b6d2488d 100644 --- a/src/whatsapp/models/settings.model.ts +++ b/src/whatsapp/models/settings.model.ts @@ -6,6 +6,9 @@ export class SettingsRaw { reject_call?: boolean; msg_call?: string; groups_ignore?: boolean; + always_online?: boolean; + read_messages?: boolean; + read_status?: boolean; } const settingsSchema = new Schema({ @@ -13,6 +16,9 @@ const settingsSchema = new Schema({ reject_call: { type: Boolean, required: true }, msg_call: { type: String, required: true }, groups_ignore: { type: Boolean, required: true }, + always_online: { type: Boolean, required: true }, + read_messages: { type: Boolean, required: true }, + read_status: { type: Boolean, required: true }, }); export const SettingsModel = dbserver?.model( diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index ff6fdd71..66a46aca 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -362,6 +362,15 @@ export class WAStartupService { this.localSettings.groups_ignore = data?.groups_ignore; this.logger.verbose(`Settings groups_ignore: ${this.localSettings.groups_ignore}`); + this.localSettings.always_online = data?.always_online; + this.logger.verbose(`Settings always_online: ${this.localSettings.always_online}`); + + this.localSettings.read_messages = data?.read_messages; + this.logger.verbose(`Settings read_messages: ${this.localSettings.read_messages}`); + + this.localSettings.read_status = data?.read_status; + this.logger.verbose(`Settings read_status: ${this.localSettings.read_status}`); + this.logger.verbose('Settings loaded'); } @@ -371,8 +380,13 @@ export class WAStartupService { this.logger.verbose(`Settings reject_call: ${data.reject_call}`); this.logger.verbose(`Settings msg_call: ${data.msg_call}`); this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`); + this.logger.verbose(`Settings always_online: ${data.always_online}`); + this.logger.verbose(`Settings read_messages: ${data.read_messages}`); + this.logger.verbose(`Settings read_status: ${data.read_status}`); Object.assign(this.localSettings, data); this.logger.verbose('Settings set'); + + this.client?.ws?.close(); } public async findSettings() { @@ -387,6 +401,9 @@ export class WAStartupService { this.logger.verbose(`Settings url: ${data.reject_call}`); this.logger.verbose(`Settings msg_call: ${data.msg_call}`); this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`); + this.logger.verbose(`Settings always_online: ${data.always_online}`); + this.logger.verbose(`Settings read_messages: ${data.read_messages}`); + this.logger.verbose(`Settings read_status: ${data.read_status}`); return data; } @@ -847,6 +864,7 @@ export class WAStartupService { printQRInTerminal: false, browser, version, + markOnlineOnConnect: this.localSettings.always_online, connectTimeoutMs: 60_000, qrTimeout: 40_000, defaultQueryTimeoutMs: undefined, @@ -1143,6 +1161,14 @@ export class WAStartupService { source: getDevice(received.key.id), }; + if (this.localSettings.read_messages && received.key.id !== 'status@broadcast') { + await this.client.readMessages([received.key]); + } + + if (this.localSettings.read_status && received.key.id === 'status@broadcast') { + await this.client.readMessages([received.key]); + } + this.logger.log(messageRaw); this.logger.verbose('Sending data to webhook in event MESSAGES_UPSERT'); @@ -2400,7 +2426,7 @@ export class WAStartupService { this.logger.verbose('Marking message as read'); try { const keys: proto.IMessageKey[] = []; - data.readMessages.forEach((read) => { + data.read_messages.forEach((read) => { if (isJidGroup(read.remoteJid) || isJidUser(read.remoteJid)) { keys.push({ remoteJid: read.remoteJid, @@ -2640,7 +2666,6 @@ export class WAStartupService { await this.client.updateGroupsAddPrivacy(settings.privacySettings.groupadd); this.logger.verbose('Groups add privacy updated'); - // reinicia a instancia this.client?.ws?.close(); return { diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index d0c5f80c..9644b76e 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -61,6 +61,9 @@ export declare namespace wa { reject_call?: boolean; msg_call?: string; groups_ignore?: boolean; + always_online?: boolean; + read_messages?: boolean; + read_status?: boolean; }; export type StateConnection = { From 62e2a8a6e3a882e8350131aa53becc28ee862df7 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 25 Jul 2023 10:23:18 -0300 Subject: [PATCH 11/25] fix: Fixed send webhook for event CALL --- 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 | 4 ++++ src/whatsapp/types/wa.types.ts | 1 + 8 files changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc6da5f1..3d875a4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Fixed * Adjusts in settings with options always_online, read_messages and read_status +* Fixed send webhook for event CALL # 1.4.2 (2023-07-24 20:52) diff --git a/Docker/.env.example b/Docker/.env.example index c3dbe505..f4e8291d 100644 --- a/Docker/.env.example +++ b/Docker/.env.example @@ -73,6 +73,7 @@ WEBHOOK_EVENTS_GROUPS_UPSERT=true WEBHOOK_EVENTS_GROUPS_UPDATE=true WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE=true WEBHOOK_EVENTS_CONNECTION_UPDATE=true +WEBHOOK_EVENTS_CALL=true # This event fires every time a new token is requested via the refresh route WEBHOOK_EVENTS_NEW_JWT_TOKEN=false diff --git a/Dockerfile b/Dockerfile index 93fa60c4..0b3ac950 100644 --- a/Dockerfile +++ b/Dockerfile @@ -74,6 +74,7 @@ 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_CALL=true ENV WEBHOOK_EVENTS_NEW_JWT_TOKEN=false diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 88b718de..78c90ec9 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -89,6 +89,7 @@ export type EventsWebhook = { GROUPS_UPSERT: boolean; GROUP_UPDATE: boolean; GROUP_PARTICIPANTS_UPDATE: boolean; + CALL: boolean; NEW_JWT_TOKEN: boolean; }; @@ -245,6 +246,7 @@ export class ConfigService { GROUP_UPDATE: process.env?.WEBHOOK_EVENTS_GROUPS_UPDATE === 'true', GROUP_PARTICIPANTS_UPDATE: process.env?.WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true', + CALL: process.env?.WEBHOOK_EVENTS_CALL === 'true', NEW_JWT_TOKEN: process.env?.WEBHOOK_EVENTS_NEW_JWT_TOKEN === 'true', }, }, diff --git a/src/dev-env.yml b/src/dev-env.yml index 41368ea4..b45d3201 100644 --- a/src/dev-env.yml +++ b/src/dev-env.yml @@ -110,6 +110,7 @@ WEBHOOK: GROUP_UPDATE: true GROUP_PARTICIPANTS_UPDATE: true CONNECTION_UPDATE: true + CALL: true # This event fires every time a new token is requested via the refresh route NEW_JWT_TOKEN: false diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 318835b1..62b7e41c 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -53,6 +53,7 @@ export const instanceNameSchema: JSONSchema7 = { 'GROUP_UPDATE', 'GROUP_PARTICIPANTS_UPDATE', 'CONNECTION_UPDATE', + 'CALL', 'NEW_JWT_TOKEN', ], }, @@ -854,6 +855,7 @@ export const webhookSchema: JSONSchema7 = { 'GROUP_UPDATE', 'GROUP_PARTICIPANTS_UPDATE', 'CONNECTION_UPDATE', + 'CALL', 'NEW_JWT_TOKEN', ], }, diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 66a46aca..8959197e 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1388,11 +1388,15 @@ export class WAStartupService { text: settings.msg_call, }); + this.logger.verbose('Sending data to event messages.upsert'); this.client.ev.emit('messages.upsert', { messages: [msg], type: 'notify', }); } + + this.logger.verbose('Sending data to webhook in event CALL'); + this.sendDataWebhook(Events.CALL, call); } if (events['connection.update']) { diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index 9644b76e..80aede98 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -22,6 +22,7 @@ export enum Events { GROUPS_UPSERT = 'groups.upsert', GROUPS_UPDATE = 'groups.update', GROUP_PARTICIPANTS_UPDATE = 'group-participants.update', + CALL = 'call', } export declare namespace wa { From c314d00ccd98ae8bcc55b0873e2ccf1497fff88c Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 25 Jul 2023 10:42:34 -0300 Subject: [PATCH 12/25] fix: Create instance with settings --- .../controllers/instance.controller.ts | 24 +++++++++++++++++++ src/whatsapp/dto/instance.dto.ts | 12 +++++++--- src/whatsapp/whatsapp.module.ts | 1 + 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index e9e690b3..9be6ab5d 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -13,6 +13,7 @@ import { Logger } from '../../config/logger.config'; import { wa } from '../types/wa.types'; import { RedisCache } from '../../db/redis.client'; import { isURL } from 'class-validator'; +import { SettingsService } from '../services/settings.service'; export class InstanceController { constructor( @@ -23,6 +24,7 @@ export class InstanceController { private readonly authService: AuthService, private readonly webhookService: WebhookService, private readonly chatwootService: ChatwootService, + private readonly settingsService: SettingsService, private readonly cache: RedisCache, ) {} @@ -40,6 +42,12 @@ export class InstanceController { chatwoot_token, chatwoot_url, chatwoot_sign_msg, + reject_call, + msg_call, + groups_ignore, + always_online, + read_messages, + read_status, }: InstanceDto) { try { this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); @@ -102,6 +110,20 @@ export class InstanceController { } } + this.logger.verbose('creating settings'); + const settings: wa.LocalSettings = { + reject_call: reject_call || false, + msg_call: msg_call || '', + groups_ignore: groups_ignore || false, + always_online: always_online || false, + read_messages: read_messages || false, + read_status: read_status || false, + }; + + this.logger.verbose('settings: ' + JSON.stringify(settings)); + + this.settingsService.create(instance, settings); + if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) { let getQrcode: wa.QrCode; @@ -121,6 +143,7 @@ export class InstanceController { webhook, webhook_by_events, events: getEvents, + settings, qrcode: getQrcode, }; @@ -179,6 +202,7 @@ export class InstanceController { webhook, webhook_by_events, events: getEvents, + settings, chatwoot: { enabled: true, account_id: chatwoot_account_id, diff --git a/src/whatsapp/dto/instance.dto.ts b/src/whatsapp/dto/instance.dto.ts index 9e8a7ec3..ca88a729 100644 --- a/src/whatsapp/dto/instance.dto.ts +++ b/src/whatsapp/dto/instance.dto.ts @@ -1,11 +1,17 @@ export class InstanceDto { instanceName: string; - webhook?: string; - webhook_by_events?: boolean; - events?: string[]; qrcode?: boolean; number?: string; token?: string; + webhook?: string; + webhook_by_events?: boolean; + events?: string[]; + reject_call?: boolean; + msg_call?: string; + groups_ignore?: boolean; + always_online?: boolean; + read_messages?: boolean; + read_status?: boolean; chatwoot_account_id?: string; chatwoot_token?: string; chatwoot_url?: string; diff --git a/src/whatsapp/whatsapp.module.ts b/src/whatsapp/whatsapp.module.ts index 9f2fed00..b8f3b1ad 100644 --- a/src/whatsapp/whatsapp.module.ts +++ b/src/whatsapp/whatsapp.module.ts @@ -94,6 +94,7 @@ export const instanceController = new InstanceController( authService, webhookService, chatwootService, + settingsService, cache, ); export const viewsController = new ViewsController(waMonitor, configService); From fdee1df5b32ef9d867819b83ab2acd9051a360e3 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 25 Jul 2023 10:42:45 -0300 Subject: [PATCH 13/25] fix: Create instance with settings --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d875a4a..7c9472f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Adjusts in settings with options always_online, read_messages and read_status * Fixed send webhook for event CALL +* Create instance with settings # 1.4.2 (2023-07-24 20:52) From 1cd7291068d8818aa6f3e8cfabe6ecfc6fc9fa19 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 25 Jul 2023 10:51:28 -0300 Subject: [PATCH 14/25] version: 1.4.3 --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c9472f9..315ee04d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 1.4.3 (homolog) +# 1.4.3 (2023-07-25 10:51) ### Fixed diff --git a/package.json b/package.json index 6489b86c..716aeec4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.4.2", + "version": "1.4.3", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": { From 4c006970a24c798a701c3a2adc1e573e0b8956be Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 25 Jul 2023 11:52:26 -0300 Subject: [PATCH 15/25] fix: Fixed chatwoot line wrap issue --- CHANGELOG.md | 6 ++++++ package.json | 2 +- src/whatsapp/services/chatwoot.service.ts | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 315ee04d..8eda7c55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.4.4 (homolog) + +### Fixed + +* Fixed chatwoot line wrap issue + # 1.4.3 (2023-07-25 10:51) ### Fixed diff --git a/package.json b/package.json index 716aeec4..8cfd9f8d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.4.3", + "version": "1.4.4", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": { diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 6e55d145..39873651 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1125,12 +1125,12 @@ export class ChatwootService { } if (body.message_type === 'template' && body.event === 'message_created') { - this.logger.verbose('check if is csat'); + this.logger.verbose('check if is template'); const data: SendTextDto = { number: chatId, textMessage: { - text: body.content, + text: body.content.replace(/\\\r\n|\\\n|\n/g, '\n'), }, options: { delay: 1200, From 89f40d54d979b38d0583275b8fc20665d35bff20 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 25 Jul 2023 12:41:54 -0300 Subject: [PATCH 16/25] fix: Solved receive location in chatwoot --- CHANGELOG.md | 1 + src/whatsapp/services/chatwoot.service.ts | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8eda7c55..4a2f5b55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Fixed * Fixed chatwoot line wrap issue +* Solved receive location in chatwoot # 1.4.3 (2023-07-25 10:51) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 39873651..5a981238 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -13,6 +13,7 @@ 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'; +import { type } from 'os'; export class ChatwootService { private messageCacheFile: string; @@ -1186,6 +1187,10 @@ export class ChatwootService { audioMessage: msg.audioMessage?.caption, contactMessage: msg.contactMessage?.vcard, contactsArrayMessage: msg.contactsArrayMessage, + locationMessage: + msg.locationMessage?.degreesLatitude + + ',' + + msg.locationMessage?.degreesLongitude, }; this.logger.verbose('type message: ' + types); @@ -1199,6 +1204,20 @@ export class ChatwootService { const result = typeKey ? types[typeKey] : undefined; + if (typeKey === 'locationMessage') { + const [latitude, longitude] = result.split(','); + + const formattedLocation = `**Location:** + **latitude:** ${latitude} + **longitude:** ${longitude} + https://www.google.com/maps/search/?api=1&query=${latitude},${longitude} + `; + + this.logger.verbose('message content: ' + formattedLocation); + + return formattedLocation; + } + if (typeKey === 'contactMessage') { const vCardData = result.split('\n'); const contactInfo = {}; From 14529f2c3580445a892a46dcdfdc25215e211d1a Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 25 Jul 2023 12:47:35 -0300 Subject: [PATCH 17/25] fix: When requesting the pairing code, it also brings the qr code --- CHANGELOG.md | 1 + src/whatsapp/services/whatsapp.service.ts | 6 +----- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a2f5b55..bb0fd7bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Fixed chatwoot line wrap issue * Solved receive location in chatwoot +* When requesting the pairing code, it also brings the qr code # 1.4.3 (2023-07-25 10:51) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 8959197e..370d9b64 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -242,13 +242,9 @@ export class WAStartupService { public get qrCode(): wa.QrCode { this.logger.verbose('Getting qrcode'); - if (this.instance.qrcode?.pairingCode) { - return { - pairingCode: this.instance.qrcode?.pairingCode, - }; - } return { + pairingCode: this.instance.qrcode?.pairingCode, code: this.instance.qrcode?.code, base64: this.instance.qrcode?.base64, }; From f0d8c2d0954bb5a5f9bf7e3db943b7b53bc6dbf9 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 25 Jul 2023 13:19:15 -0300 Subject: [PATCH 18/25] fix: Solved receive location in chatwoot --- src/whatsapp/services/chatwoot.service.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 5a981238..c660f6d6 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1187,10 +1187,11 @@ export class ChatwootService { audioMessage: msg.audioMessage?.caption, contactMessage: msg.contactMessage?.vcard, contactsArrayMessage: msg.contactsArrayMessage, - locationMessage: - msg.locationMessage?.degreesLatitude + - ',' + - msg.locationMessage?.degreesLongitude, + locationMessage: !msg.protocolMessage + ? msg.locationMessage?.degreesLatitude + + ',' + + msg.locationMessage?.degreesLongitude + : undefined, }; this.logger.verbose('type message: ' + types); From aef92240cc09ab7c74574c24d5ab916de89c0bb6 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 25 Jul 2023 15:20:21 -0300 Subject: [PATCH 19/25] fix: Option conversation_pending in chatwoot endpoint --- CHANGELOG.md | 2 + src/validate/validate.schema.ts | 21 ++++++++- .../controllers/chatwoot.controller.ts | 2 + .../controllers/instance.controller.ts | 24 ++++++++++ src/whatsapp/dto/chatwoot.dto.ts | 2 + src/whatsapp/dto/instance.dto.ts | 2 + src/whatsapp/models/chatwoot.model.ts | 2 + src/whatsapp/services/chatwoot.service.ts | 46 ++++++++++++++----- src/whatsapp/services/whatsapp.service.ts | 18 +++++++- src/whatsapp/types/wa.types.ts | 3 ++ 10 files changed, 107 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb0fd7bb..3922d284 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ * Fixed chatwoot line wrap issue * Solved receive location in chatwoot * When requesting the pairing code, it also brings the qr code +* Option reopen_conversation in chatwoot endpoint +* Option conversation_pending in chatwoot endpoint # 1.4.3 (2023-07-25 10:51) diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 62b7e41c..d7e2ac1e 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -874,9 +874,26 @@ export const chatwootSchema: JSONSchema7 = { token: { type: 'string' }, url: { type: 'string' }, sign_msg: { type: 'boolean', enum: [true, false] }, + reopen_conversation: { type: 'boolean', enum: [true, false] }, + conversation_pending: { type: 'boolean', enum: [true, false] }, }, - required: ['enabled', 'account_id', 'token', 'url', 'sign_msg'], - ...isNotEmpty('account_id', 'token', 'url', 'sign_msg'), + required: [ + 'enabled', + 'account_id', + 'token', + 'url', + 'sign_msg', + 'reopen_conversation', + 'conversation_pending', + ], + ...isNotEmpty( + 'account_id', + 'token', + 'url', + 'sign_msg', + 'reopen_conversation', + 'conversation_pending', + ), }; export const settingsSchema: JSONSchema7 = { diff --git a/src/whatsapp/controllers/chatwoot.controller.ts b/src/whatsapp/controllers/chatwoot.controller.ts index d5e5e841..ad92e607 100644 --- a/src/whatsapp/controllers/chatwoot.controller.ts +++ b/src/whatsapp/controllers/chatwoot.controller.ts @@ -44,6 +44,8 @@ export class ChatwootController { data.token = ''; data.url = ''; data.sign_msg = false; + data.reopen_conversation = false; + data.conversation_pending = false; } data.name_inbox = instance.instanceName; diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 9be6ab5d..d9c351f7 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -42,6 +42,8 @@ export class InstanceController { chatwoot_token, chatwoot_url, chatwoot_sign_msg, + chatwoot_reopen_conversation, + chatwoot_conversation_pending, reject_call, msg_call, groups_ignore, @@ -169,6 +171,24 @@ export class InstanceController { throw new BadRequestException('Invalid "url" property in chatwoot'); } + if (chatwoot_sign_msg !== true && chatwoot_sign_msg !== false) { + throw new BadRequestException('sign_msg is required'); + } + + if ( + chatwoot_reopen_conversation !== true && + chatwoot_reopen_conversation !== false + ) { + throw new BadRequestException('reopen_conversation is required'); + } + + if ( + chatwoot_conversation_pending !== true && + chatwoot_conversation_pending !== false + ) { + throw new BadRequestException('conversation_pending is required'); + } + const urlServer = this.configService.get('SERVER').URL; try { @@ -180,6 +200,8 @@ export class InstanceController { sign_msg: chatwoot_sign_msg || false, name_inbox: instance.instanceName, number, + reopen_conversation: chatwoot_reopen_conversation || false, + conversation_pending: chatwoot_conversation_pending || false, }); this.chatwootService.initInstanceChatwoot( @@ -209,6 +231,8 @@ export class InstanceController { token: chatwoot_token, url: chatwoot_url, sign_msg: chatwoot_sign_msg || false, + reopen_conversation: chatwoot_reopen_conversation || false, + conversation_pending: chatwoot_conversation_pending || false, number, name_inbox: instance.instanceName, webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`, diff --git a/src/whatsapp/dto/chatwoot.dto.ts b/src/whatsapp/dto/chatwoot.dto.ts index a5026a46..b270c869 100644 --- a/src/whatsapp/dto/chatwoot.dto.ts +++ b/src/whatsapp/dto/chatwoot.dto.ts @@ -6,4 +6,6 @@ export class ChatwootDto { name_inbox?: string; sign_msg?: boolean; number?: string; + reopen_conversation?: boolean; + conversation_pending?: boolean; } diff --git a/src/whatsapp/dto/instance.dto.ts b/src/whatsapp/dto/instance.dto.ts index ca88a729..c317060f 100644 --- a/src/whatsapp/dto/instance.dto.ts +++ b/src/whatsapp/dto/instance.dto.ts @@ -16,4 +16,6 @@ export class InstanceDto { chatwoot_token?: string; chatwoot_url?: string; chatwoot_sign_msg?: boolean; + chatwoot_reopen_conversation?: boolean; + chatwoot_conversation_pending?: boolean; } diff --git a/src/whatsapp/models/chatwoot.model.ts b/src/whatsapp/models/chatwoot.model.ts index 54d9e051..bac226e9 100644 --- a/src/whatsapp/models/chatwoot.model.ts +++ b/src/whatsapp/models/chatwoot.model.ts @@ -10,6 +10,8 @@ export class ChatwootRaw { name_inbox?: string; sign_msg?: boolean; number?: string; + reopen_conversation?: boolean; + conversation_pending?: boolean; } const chatwootSchema = new Schema({ diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index c660f6d6..facea536 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -231,12 +231,19 @@ export class ChatwootService { if (qrcode) { this.logger.verbose('create conversation in chatwoot'); + const data = { + contact_id: contactId.toString(), + inbox_id: inboxId.toString(), + }; + + if (this.provider.conversation_pending) { + data['status'] = 'pending'; + } + + console.log('this.provider', this.provider); const conversation = await client.conversations.create({ accountId: this.provider.account_id, - data: { - contact_id: contactId.toString(), - inbox_id: inboxId.toString(), - }, + data, }); if (!conversation) { @@ -521,11 +528,20 @@ export class ChatwootService { })) as any; if (contactConversations) { + let conversation: any; + if (this.provider.reopen_conversation) { + conversation = contactConversations.payload.find( + (conversation) => conversation.inbox_id == filterInbox.id, + ); + } else { + conversation = contactConversations.payload.find( + (conversation) => + conversation.status !== 'resolved' && + conversation.inbox_id == filterInbox.id, + ); + } this.logger.verbose('return conversation if exists'); - const conversation = contactConversations.payload.find( - (conversation) => - conversation.status !== 'resolved' && conversation.inbox_id == filterInbox.id, - ); + if (conversation) { this.logger.verbose('conversation found'); return conversation.id; @@ -533,12 +549,18 @@ export class ChatwootService { } this.logger.verbose('create conversation in chatwoot'); + const data = { + contact_id: contactId.toString(), + inbox_id: filterInbox.id.toString(), + }; + + if (this.provider.conversation_pending) { + data['status'] = 'pending'; + } + const conversation = await client.conversations.create({ accountId: this.provider.account_id, - data: { - contact_id: `${contactId}`, - inbox_id: `${filterInbox.id}`, - }, + data, }); if (!conversation) { diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 370d9b64..ccefcfa0 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -312,6 +312,19 @@ export class WAStartupService { this.localChatwoot.sign_msg = data?.sign_msg; this.logger.verbose(`Chatwoot sign msg: ${this.localChatwoot.sign_msg}`); + this.localChatwoot.number = data?.number; + this.logger.verbose(`Chatwoot number: ${this.localChatwoot.number}`); + + this.localChatwoot.reopen_conversation = data?.reopen_conversation; + this.logger.verbose( + `Chatwoot reopen conversation: ${this.localChatwoot.reopen_conversation}`, + ); + + this.localChatwoot.conversation_pending = data?.conversation_pending; + this.logger.verbose( + `Chatwoot conversation pending: ${this.localChatwoot.conversation_pending}`, + ); + this.logger.verbose('Chatwoot loaded'); } @@ -323,6 +336,8 @@ export class WAStartupService { this.logger.verbose(`Chatwoot url: ${data.url}`); this.logger.verbose(`Chatwoot inbox name: ${data.name_inbox}`); this.logger.verbose(`Chatwoot sign msg: ${data.sign_msg}`); + this.logger.verbose(`Chatwoot reopen conversation: ${data.reopen_conversation}`); + this.logger.verbose(`Chatwoot conversation pending: ${data.conversation_pending}`); Object.assign(this.localChatwoot, data); this.logger.verbose('Chatwoot set'); @@ -342,6 +357,8 @@ export class WAStartupService { this.logger.verbose(`Chatwoot url: ${data.url}`); this.logger.verbose(`Chatwoot inbox name: ${data.name_inbox}`); this.logger.verbose(`Chatwoot sign msg: ${data.sign_msg}`); + this.logger.verbose(`Chatwoot reopen conversation: ${data.reopen_conversation}`); + this.logger.verbose(`Chatwoot conversation pending: ${data.conversation_pending}`); return data; } @@ -618,7 +635,6 @@ export class WAStartupService { color: { light: '#ffffff', dark: '#198754' }, }; - console.log(this.phoneNumber); if (this.phoneNumber) { await delay(2000); this.instance.qrcode.pairingCode = await this.client.requestPairingCode( diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index 80aede98..a0d514d8 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -56,6 +56,9 @@ export declare namespace wa { url?: string; name_inbox?: string; sign_msg?: boolean; + number?: string; + reopen_conversation?: boolean; + conversation_pending?: boolean; }; export type LocalSettings = { From 6bb1abd7f0a186dd535cb11610fc860e078cb219 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 25 Jul 2023 15:29:42 -0300 Subject: [PATCH 20/25] fix: Option conversation_pending in chatwoot endpoint --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3922d284..f3a30ac7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 1.4.4 (homolog) +# 1.4.4 (2023-07-25 15:24) ### Fixed From ecae077c6d50dc480934409efb00ee5f83a87389 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 25 Jul 2023 16:16:49 -0300 Subject: [PATCH 21/25] fix: Option conversation_pending in chatwoot endpoint --- 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 facea536..045c6519 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1209,7 +1209,7 @@ export class ChatwootService { audioMessage: msg.audioMessage?.caption, contactMessage: msg.contactMessage?.vcard, contactsArrayMessage: msg.contactsArrayMessage, - locationMessage: !msg.protocolMessage + locationMessage: msg.locationMessage ? msg.locationMessage?.degreesLatitude + ',' + msg.locationMessage?.degreesLongitude From dd0c1e20a723b835407efbb3b96005de5a5a7680 Mon Sep 17 00:00:00 2001 From: CodePhix Date: Tue, 25 Jul 2023 19:59:42 -0300 Subject: [PATCH 22/25] Update whatsapp.service.ts --- src/whatsapp/services/whatsapp.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index ccefcfa0..bd07f951 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1277,7 +1277,7 @@ export class WAStartupService { 5: 'PLAYED', }; for await (const { key, update } of args) { - if (settings.groups_ignore && key.remoteJid.includes('@g.us')) { + if (settings?.groups_ignore && key.remoteJid.includes('@g.us')) { this.logger.verbose('group ignored'); return; } From de0c9a1eff88aa1d22fad9ba9f8b8676caa4aa96 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 26 Jul 2023 09:34:10 -0300 Subject: [PATCH 23/25] fix: fixed problems in localization template --- CHANGELOG.md | 6 ++++++ src/whatsapp/services/chatwoot.service.ts | 15 ++++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3a30ac7..88129b0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.4.5 (2023-07-26 09:32) + +### Fixed + +* Fixed problems in localization template + # 1.4.4 (2023-07-25 15:24) ### Fixed diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 045c6519..90a0fa1a 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -240,7 +240,6 @@ export class ChatwootService { data['status'] = 'pending'; } - console.log('this.provider', this.provider); const conversation = await client.conversations.create({ accountId: this.provider.account_id, data, @@ -1209,11 +1208,8 @@ export class ChatwootService { audioMessage: msg.audioMessage?.caption, contactMessage: msg.contactMessage?.vcard, contactsArrayMessage: msg.contactsArrayMessage, - locationMessage: msg.locationMessage - ? msg.locationMessage?.degreesLatitude + - ',' + - msg.locationMessage?.degreesLongitude - : undefined, + locationMessage: msg.locationMessage, + liveLocationMessage: msg.liveLocationMessage, }; this.logger.verbose('type message: ' + types); @@ -1227,8 +1223,9 @@ export class ChatwootService { const result = typeKey ? types[typeKey] : undefined; - if (typeKey === 'locationMessage') { - const [latitude, longitude] = result.split(','); + if (typeKey === 'locationMessage' || typeKey === 'liveLocationMessage') { + const latitude = result.degreesLatitude; + const longitude = result.degreesLongitude; const formattedLocation = `**Location:** **latitude:** ${latitude} @@ -1311,7 +1308,7 @@ export class ChatwootService { this.logger.verbose('get conversation message'); const types = this.getTypeMessage(msg); - += const messageContent = this.getMessageContent(types); this.logger.verbose('conversation message: ' + messageContent); From 3f41974a753285fd36fce7f0cdef3c4eb6cf044f Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 26 Jul 2023 09:38:22 -0300 Subject: [PATCH 24/25] fix: Fix mids going duplicated in chatwoot --- CHANGELOG.md | 3 ++- src/whatsapp/services/chatwoot.service.ts | 2 +- src/whatsapp/services/whatsapp.service.ts | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 88129b0e..cf5498ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,8 @@ ### Fixed -* Fixed problems in localization template +* Fixed problems in localization template in chatwoot +* Fix mids going duplicated in chatwoot # 1.4.4 (2023-07-25 15:24) diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 90a0fa1a..2d470c37 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1308,7 +1308,7 @@ export class ChatwootService { this.logger.verbose('get conversation message'); const types = this.getTypeMessage(msg); -= + const messageContent = this.getMessageContent(types); this.logger.verbose('conversation message: ' + messageContent); diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index bd07f951..4c9bf62d 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1147,7 +1147,7 @@ export class WAStartupService { if ( type !== 'notify' || - // received.message?.protocolMessage || + received.message?.protocolMessage || received.message?.pollUpdateMessage ) { this.logger.verbose('message rejected'); From 67e98456bb39bfc7e545c5b90bf76160f458dce6 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 26 Jul 2023 09:39:27 -0300 Subject: [PATCH 25/25] fix: Fix mids going duplicated in chatwoot --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8cfd9f8d..0ef463d7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.4.4", + "version": "1.4.5", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": {