From f6d8ebd8d3b8ebdd1f011b8adb6d3a80ea2eca22 Mon Sep 17 00:00:00 2001 From: Amilton Morais Date: Tue, 3 Oct 2023 16:39:04 -0300 Subject: [PATCH 01/32] Update dev-env.yml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Inserido nova variável WEBHOOK_BASE64 para recuperar Base64 da media enviar por webhook. --- src/dev-env.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dev-env.yml b/src/dev-env.yml index 7af78d40..cadfe105 100644 --- a/src/dev-env.yml +++ b/src/dev-env.yml @@ -97,6 +97,7 @@ WEBHOOK: WEBHOOK_BY_EVENTS: false # Automatically maps webhook paths # Set the events you want to hear + WEBHOOK_BASE64: false EVENTS: APPLICATION_STARTUP: false QRCODE_UPDATED: true From d007fc49d89c60319997c1dfc2f82b088be6d000 Mon Sep 17 00:00:00 2001 From: Amilton Morais Date: Tue, 3 Oct 2023 16:45:05 -0300 Subject: [PATCH 02/32] Update instance.controller.ts Foi criado novas propriedades para recuperar Base64 da media enviada por webhook. --- src/whatsapp/controllers/instance.controller.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index a2903f59..3ead8690 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -41,6 +41,7 @@ export class InstanceController { instanceName, webhook, webhook_by_events, + webhook_base64, events, qrcode, number, @@ -139,6 +140,7 @@ export class InstanceController { url: webhook, events: newEvents, webhook_by_events, + webhook_base64, }); webhookEvents = (await this.webhookService.find(instance)).events; @@ -297,6 +299,7 @@ export class InstanceController { webhook: { webhook, webhook_by_events, + webhook_base64, events: webhookEvents, }, websocket: { @@ -390,6 +393,7 @@ export class InstanceController { webhook: { webhook, webhook_by_events, + webhook_base64, events: webhookEvents, }, websocket: { From b8f1e8a7ef025f6c8ae8c0bf849cd071cfbe5573 Mon Sep 17 00:00:00 2001 From: Amilton Morais Date: Tue, 3 Oct 2023 16:56:44 -0300 Subject: [PATCH 03/32] Update instance.dto.ts Foi criado novas propriedades "webhook_base64?: boolean;" para recuperar Base64 da media enviada por webhook. --- src/whatsapp/dto/instance.dto.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/whatsapp/dto/instance.dto.ts b/src/whatsapp/dto/instance.dto.ts index 7807d1a5..700fa099 100644 --- a/src/whatsapp/dto/instance.dto.ts +++ b/src/whatsapp/dto/instance.dto.ts @@ -5,6 +5,7 @@ export class InstanceDto { token?: string; webhook?: string; webhook_by_events?: boolean; + webhook_base64?: boolean; events?: string[]; reject_call?: boolean; msg_call?: string; From f8e3b76a4ae079957f54e8a6a0d40339ef22852d Mon Sep 17 00:00:00 2001 From: Amilton Morais Date: Tue, 3 Oct 2023 16:59:06 -0300 Subject: [PATCH 04/32] Update webhook.model.ts Foi criado novas propriedades para recuperar Base64 da media enviada por webhook. --- src/whatsapp/models/webhook.model.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/whatsapp/models/webhook.model.ts b/src/whatsapp/models/webhook.model.ts index 05a222e0..9a1bb43d 100644 --- a/src/whatsapp/models/webhook.model.ts +++ b/src/whatsapp/models/webhook.model.ts @@ -8,6 +8,7 @@ export class WebhookRaw { enabled?: boolean; events?: string[]; webhook_by_events?: boolean; + webhook_base64?: boolean; } const webhookSchema = new Schema({ @@ -16,6 +17,7 @@ const webhookSchema = new Schema({ enabled: { type: Boolean, required: true }, events: { type: [String], required: true }, webhook_by_events: { type: Boolean, required: true }, + webhook_base64: { type: Boolean, required: true }, }); export const WebhookModel = dbserver?.model(WebhookRaw.name, webhookSchema, 'webhook'); From f76a9247005f598aabdb5b6dd6294f2bf5638bc5 Mon Sep 17 00:00:00 2001 From: Amilton Morais Date: Tue, 3 Oct 2023 17:13:58 -0300 Subject: [PATCH 05/32] Update webhook.service.ts Foi criado novo variavel "webhook_base64:false' para retorno erro. --- src/whatsapp/services/webhook.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/whatsapp/services/webhook.service.ts b/src/whatsapp/services/webhook.service.ts index dd0a88cd..7dbb9d36 100644 --- a/src/whatsapp/services/webhook.service.ts +++ b/src/whatsapp/services/webhook.service.ts @@ -26,7 +26,7 @@ export class WebhookService { return result; } catch (error) { - return { enabled: false, url: '', events: [], webhook_by_events: false }; + return { enabled: false, url: '', events: [], webhook_by_events: false, webhook_base64 : false }; } } } From f085343a999682d0badce1e5680a6d9769d9504e Mon Sep 17 00:00:00 2001 From: Amilton Morais Date: Tue, 3 Oct 2023 17:18:58 -0300 Subject: [PATCH 06/32] Update whatsapp.service.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Foi criado novo código para recuperar Base64 da media enviada por webhook. --- src/whatsapp/services/whatsapp.service.ts | 49 ++++++++++++++++++----- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 567a587e..2c39f500 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -276,6 +276,10 @@ export class WAStartupService { this.localWebhook.webhook_by_events = data?.webhook_by_events; this.logger.verbose(`Webhook by events: ${this.localWebhook.webhook_by_events}`); + this.localWebhook.webhook_base64 = data?.webhook_base64; + this.logger.verbose(`Webhook by webhook_base64: ${this.localWebhook.webhook_base64}`); + + this.logger.verbose('Webhook loaded'); } @@ -1528,15 +1532,42 @@ export class WAStartupService { return; } - const messageRaw: MessageRaw = { - key: received.key, - pushName: received.pushName, - message: { ...received.message }, - messageType: getContentType(received.message), - messageTimestamp: received.messageTimestamp as number, - owner: this.instance.name, - source: getDevice(received.key.id), - }; + let messageRaw: MessageRaw; + const globalWebhook = this.configService.get('WEBHOOK').GLOBAL; + if (this.localWebhook.webhook_base64 === true && received?.message.documentMessage || received?.message.imageMessage ) { + const buffer = await downloadMediaMessage( + { key: received.key, message: received?.message }, + 'buffer', + {}, + { + logger: P({ level: 'error' }), + reuploadRequest: this.client.updateMediaMessage, + }, + ); + console.log(buffer); + messageRaw = { + key: received.key, + pushName: received.pushName, + message: { + ...received.message, + base64: buffer ? buffer.toString('base64') : undefined, + }, + messageType: getContentType(received.message), + messageTimestamp: received.messageTimestamp as number, + owner: this.instance.name, + source: getDevice(received.key.id), + }; + } else { + messageRaw = { + key: received.key, + pushName: received.pushName, + message: { ...received.message }, + messageType: getContentType(received.message), + messageTimestamp: received.messageTimestamp as number, + owner: this.instance.name, + source: getDevice(received.key.id), + }; + } if (this.localSettings.read_messages && received.key.id !== 'status@broadcast') { await this.client.readMessages([received.key]); From 523f3301c0f9527ac5eaf2d4792b81d72c2ed110 Mon Sep 17 00:00:00 2001 From: Amilton Morais Date: Tue, 3 Oct 2023 17:20:14 -0300 Subject: [PATCH 07/32] Update wa.types.ts Foi criado novas propriedades para recuperar Base64 da media enviada por webhook. --- src/whatsapp/types/wa.types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index 2025e7f7..9f326c8a 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -50,6 +50,7 @@ export declare namespace wa { url?: string; events?: string[]; webhook_by_events?: boolean; + webhook_base64?: boolean; }; export type LocalChatwoot = { From 6a3f82ed7e2912e548578741a17ed19271b4728a Mon Sep 17 00:00:00 2001 From: Wender Teixeira Date: Thu, 5 Oct 2023 11:43:18 -0300 Subject: [PATCH 08/32] Fix: Variables null --- src/whatsapp/services/typebot.service.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/whatsapp/services/typebot.service.ts b/src/whatsapp/services/typebot.service.ts index 659309e1..c329a169 100644 --- a/src/whatsapp/services/typebot.service.ts +++ b/src/whatsapp/services/typebot.service.ts @@ -114,9 +114,11 @@ export class TypebotService { instanceName: instance.instanceName, }; - variables.forEach((variable) => { - prefilledVariables[variable.name] = variable.value; - }); + if (variables?.length) { + variables.forEach((variable: { name: string | number; value: string }) => { + prefilledVariables[variable.name] = variable.value; + }); + } if (startSession) { const response = await this.createNewSession(instance, { From 46aa22953102477ae22c46bdef2bd642beee987a Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 5 Oct 2023 15:54:46 -0300 Subject: [PATCH 09/32] fix: adjusts in swagger --- src/docs/swagger.yaml | 712 ++++++++++++++++------ src/whatsapp/services/whatsapp.service.ts | 3 +- 2 files changed, 513 insertions(+), 202 deletions(-) diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml index 77693bcc..a6170263 100644 --- a/src/docs/swagger.yaml +++ b/src/docs/swagger.yaml @@ -23,7 +23,7 @@ info: This project is based on the [evolution](https://github.com/code-chat-br/whatsapp-api). The original project is an implementation of [Baileys](https://github.com/WhiskeySockets/Baileys), serving as a Restful API service that controls WhatsApp functions.
The code allows the creation of multiservice chats, service bots, or any other system that utilizes WhatsApp. The documentation provides instructions on how to set up and use the project, as well as additional information about its features and configuration options. - + [![Run in Postman](https://run.pstmn.io/button.svg)](https://god.gw.postman.com/run-collection/26869335-5546d063-156b-4529-915f-909dd628c090?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D26869335-5546d063-156b-4529-915f-909dd628c090%26entityType%3Dcollection%26workspaceId%3D339a4ee7-378b-45c9-b5b8-fd2c0a9c2442) version: 1.5.2 contact: @@ -83,13 +83,13 @@ paths: type: boolean description: QR Code of the instance (optional). example: - instanceName: 'exampleInstance' - token: '87F3F7D0-4B8A-45D0-8618-7399E4AD6469' + instanceName: "exampleInstance" + token: "87F3F7D0-4B8A-45D0-8618-7399E4AD6469" qrcode: true security: - apikeyAuth: [] responses: - '200': + "200": description: Successful response content: application/json: {} @@ -106,15 +106,15 @@ paths: schema: type: string description: Retrieve one or all instances (optional). - example: 'evolution' + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: schema: type: array - items: + items: type: object properties: instance: @@ -148,9 +148,9 @@ paths: schema: type: string description: Connect to your instance. - example: 'evolution' + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: @@ -162,6 +162,24 @@ paths: base64: type: string description: The QR Code as a string. + /instance/restart/{instanceName}: + put: + tags: + - Instance Controller + summary: Instance Restart + parameters: + - name: instanceName + in: path + required: true + schema: + type: string + description: Connect to your instance. + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} /instance/connectionState/{instanceName}: get: tags: @@ -174,9 +192,9 @@ paths: schema: type: string description: Check the connection state of your instance. - example: 'evolution' + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} @@ -192,9 +210,9 @@ paths: schema: type: string description: Logout from your instance. - example: 'evolution' + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} @@ -210,9 +228,9 @@ paths: schema: type: string description: Delete your instance. - example: 'evolution' + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} @@ -232,14 +250,14 @@ paths: number: type: string description: The recipient's phone number. - example: '1234567890' + example: "1234567890" textMessage: type: object properties: text: type: string description: The content of the text message. - example: 'Hello, World!' + example: "Hello, World!" options: type: object properties: @@ -248,8 +266,43 @@ paths: description: Delay time before sending the message. presence: type: string - enum: ['composing', 'recording', 'paused'] + enum: ["composing", "recording", "paused"] description: Indicates the sender's action/status. + linkPreview: + type: boolean + description: Indicates whether to enable link preview. + quoted: + type: object + properties: + key: + type: object + properties: + remoteJid: + type: string + description: The ID of the recipient of the original message. + fromMe: + type: boolean + description: Indicates if the message was sent from the user. + id: + type: string + description: The ID of the original message. + message: + type: object + properties: + conversation: + type: string + description: The content of the quoted message. + mentions: + type: object + properties: + everyone: + type: boolean + description: Indicates whether to mention everyone. + mentioned: + type: array + items: + type: string + description: The phone numbers of the users to be mentioned. required: - number - textMessage @@ -260,9 +313,61 @@ paths: schema: type: string description: The name of the instance to which the message should be sent. - example: 'evolution' + example: "evolution" responses: - '200': + "200": + description: Successful response + content: + application/json: {} + /message/sendStatus/{instanceName}: + post: + tags: + - Send Message Controller + summary: Send a status message. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + statusMessage: + type: object + properties: + type: + type: string + enum: ["text", "image", "video", "audio"] + description: Type of the status message. + content: + type: string + description: The content of the status message. + backgroundColor: + type: string + description: The background color of the status message. + font: + type: integer + enum: [1, 2, 3, 4, 5] + description: The font of the status message. + allContacts: + type: boolean + description: Indicates whether to send the status message to all contacts. + statusJidList: + type: array + items: + type: string + description: The phone numbers of the users to whom the status message should be sent. + required: + - type + parameters: + - name: instanceName + in: path + required: true + schema: + type: string + description: The name of the instance to which the status message should be sent. + example: "evolution" + responses: + "200": description: Successful response content: application/json: {} @@ -281,13 +386,13 @@ paths: number: type: string description: The recipient's phone number. - example: '1234567890' + example: "1234567890" mediaMessage: type: object properties: mediatype: type: string - enum: ['image', 'document', 'video', 'audio'] + enum: ["image", "document", "video", "audio"] description: Type of the media content. fileName: type: string @@ -309,8 +414,43 @@ paths: description: Delay time before sending the message. presence: type: string - enum: ['composing', 'recording', 'paused'] + enum: ["composing", "recording", "paused"] description: Indicates the sender's action/status. + linkPreview: + type: boolean + description: Indicates whether to enable link preview. + quoted: + type: object + properties: + key: + type: object + properties: + remoteJid: + type: string + description: The ID of the recipient of the original message. + fromMe: + type: boolean + description: Indicates if the message was sent from the user. + id: + type: string + description: The ID of the original message. + message: + type: object + properties: + conversation: + type: string + description: The content of the quoted message. + mentions: + type: object + properties: + everyone: + type: boolean + description: Indicates whether to mention everyone. + mentioned: + type: array + items: + type: string + description: The phone numbers of the users to be mentioned. parameters: - name: instanceName in: path @@ -318,60 +458,146 @@ paths: schema: type: string description: The name of the instance to which the media message should be sent. - example: 'evolution' + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} - /message/sendMediaFile/{instanceName}: + /message/sendWhatsAppAudio/{instanceName}: post: tags: - Send Message Controller - summary: Send a media file (image, video, document, audio) directly to a specified instance. + summary: Send an audio message via WhatsApp to a specified instance. + description: This endpoint allows users to share an audio message. requestBody: required: true content: - multipart/form-data: + application/json: schema: type: object properties: number: type: string description: The recipient's phone number. - example: '1234567890' - caption: - type: string - description: Caption to accompany the media (optional). - attachment: - type: string - format: binary - description: The media file to be sent. - mediatype: - type: string - enum: ['image', 'document', 'video', 'audio'] - description: Type of the media content. - presence: - type: string - enum: ['composing', 'recording', 'paused'] - description: Indicates the sender's action/status (optional). - delay: - type: integer - description: Delay time before sending the message (optional). + example: "1234567890" + audioMessage: + type: object + properties: + audio: + type: string + description: URL of the audio file to be sent. + required: + - audio + options: + type: object + properties: + delay: + type: integer + description: Delay time before sending the message. + presence: + type: string + enum: ["composing", "recording", "paused"] + description: Indicates the sender's action/status. + linkPreview: + type: boolean + description: Indicates whether to enable link preview. + quoted: + type: object + properties: + key: + type: object + properties: + remoteJid: + type: string + description: The ID of the recipient of the original message. + fromMe: + type: boolean + description: Indicates if the message was sent from the user. + id: + type: string + description: The ID of the original message. + message: + type: object + properties: + conversation: + type: string + description: The content of the quoted message. + mentions: + type: object + properties: + everyone: + type: boolean + description: Indicates whether to mention everyone. + mentioned: + type: array + items: + type: string + description: The phone numbers of the users to be mentioned. required: - number - - attachment - - mediatype + - audioMessage.audio parameters: - name: instanceName in: path required: true schema: type: string - description: The name of the instance to which the media file should be sent. - example: 'evolution' + description: The name of the instance to which the audio should be sent. + example: "evolution" responses: - '200': + "200": + description: Successful response + content: + application/json: {} + /message/sendSticker/{instanceName}: + post: + tags: + - Send Message Controller + summary: Send an sticker to a specified instance. + description: This endpoint allows users to share an sticker message. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + number: + type: string + description: The recipient's phone number. + example: "1234567890" + stickerMessage: + type: object + properties: + image: + type: string + description: URL of the audio file to be sent. + required: + - image + options: + type: object + properties: + delay: + type: integer + description: Delay time before sending the message. + presence: + type: string + enum: ["composing", "recording", "paused"] + description: Indicates the sender's action/status. + required: + - number + - audioMessage.audio + parameters: + - name: instanceName + in: path + required: true + schema: + type: string + description: The name of the instance to which the audio should be sent. + example: "evolution" + responses: + "200": description: Successful response content: application/json: {} @@ -391,7 +617,7 @@ paths: number: type: string description: The recipient's phone number. - example: '1234567890' + example: "1234567890" locationMessage: type: object properties: @@ -417,8 +643,43 @@ paths: description: Delay time before sending the message. presence: type: string - enum: ['composing', 'recording', 'paused'] + enum: ["composing", "recording", "paused"] description: Indicates the sender's action/status. + linkPreview: + type: boolean + description: Indicates whether to enable link preview. + quoted: + type: object + properties: + key: + type: object + properties: + remoteJid: + type: string + description: The ID of the recipient of the original message. + fromMe: + type: boolean + description: Indicates if the message was sent from the user. + id: + type: string + description: The ID of the original message. + message: + type: object + properties: + conversation: + type: string + description: The content of the quoted message. + mentions: + type: object + properties: + everyone: + type: boolean + description: Indicates whether to mention everyone. + mentioned: + type: array + items: + type: string + description: The phone numbers of the users to be mentioned. required: - number - locationMessage.latitude @@ -430,9 +691,9 @@ paths: schema: type: string description: The name of the instance to which the location should be sent. - example: 'evolution' + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} @@ -452,7 +713,7 @@ paths: number: type: string description: The recipient's phone number. - example: '1234567890' + example: "1234567890" contactMessage: type: array items: @@ -467,6 +728,15 @@ paths: phoneNumber: type: string description: Phone number of the contact. + organization: + type: string + description: Organization of the contact. + email: + type: string + description: Email address of the contact. + url: + type: string + description: Url of the contact. required: - fullName - wuid @@ -476,11 +746,46 @@ paths: properties: delay: type: integer - description: Delay time before sending the contact. + description: Delay time before sending the message. presence: type: string - enum: ['composing', 'recording', 'paused'] + enum: ["composing", "recording", "paused"] description: Indicates the sender's action/status. + linkPreview: + type: boolean + description: Indicates whether to enable link preview. + quoted: + type: object + properties: + key: + type: object + properties: + remoteJid: + type: string + description: The ID of the recipient of the original message. + fromMe: + type: boolean + description: Indicates if the message was sent from the user. + id: + type: string + description: The ID of the original message. + message: + type: object + properties: + conversation: + type: string + description: The content of the quoted message. + mentions: + type: object + properties: + everyone: + type: boolean + description: Indicates whether to mention everyone. + mentioned: + type: array + items: + type: string + description: The phone numbers of the users to be mentioned. required: - number parameters: @@ -490,9 +795,9 @@ paths: schema: type: string description: The name of the instance to which the contacts should be sent. - example: 'evolution' + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} @@ -540,18 +845,18 @@ paths: schema: type: string description: The name of the instance to which the reaction should be sent. - example: 'evolution' + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} - /message/sendWhatsAppAudio/{instanceName}: + /message/sendPoll/{instanceName}: post: tags: - Send Message Controller - summary: Send an audio message via WhatsApp to a specified instance. - description: This endpoint allows users to share an audio message. + summary: Send a poll to a specified instance. + description: This endpoint allows users to send a poll to a chat. requestBody: required: true content: @@ -562,75 +867,76 @@ paths: number: type: string description: The recipient's phone number. - example: '1234567890' - audioMessage: + example: "1234567890" + pollMessage: type: object properties: - audio: + name: type: string - description: URL of the audio file to be sent. - required: - - audio + description: Name or title of the poll. + selectableCount: + type: integer + description: Number of selectable options. + values: + type: array + items: + type: string + description: The options of the poll. options: type: object properties: delay: type: integer - description: Delay time before sending the audio message. - required: - - number - - audioMessage.audio + description: Delay time before sending the message. + presence: + type: string + enum: ["composing", "recording", "paused"] + description: Indicates the sender's action/status. + linkPreview: + type: boolean + description: Indicates whether to enable link preview. + quoted: + type: object + properties: + key: + type: object + properties: + remoteJid: + type: string + description: The ID of the recipient of the original message. + fromMe: + type: boolean + description: Indicates if the message was sent from the user. + id: + type: string + description: The ID of the original message. + message: + type: object + properties: + conversation: + type: string + description: The content of the quoted message. + mentions: + type: object + properties: + everyone: + type: boolean + description: Indicates whether to mention everyone. + mentioned: + type: array + items: + type: string + description: The phone numbers of the users to be mentioned. parameters: - name: instanceName in: path required: true schema: type: string - description: The name of the instance to which the audio should be sent. - example: 'evolution' + description: The name of the instance to which the poll should be sent. + example: "evolution" responses: - '200': - description: Successful response - content: - application/json: {} - /message/sendWhatsAppAudioFile/{instanceName}: - post: - tags: - - Send Message Controller - summary: Upload and send a WhatsApp audio file to a specified instance. - description: This endpoint allows users to upload and send an audio file via WhatsApp. - requestBody: - required: true - content: - multipart/form-data: - schema: - type: object - properties: - number: - type: string - description: The recipient's phone number. - example: '1234567890' - attachment: - type: string - description: Audio file to be sent. - format: binary - delay: - type: integer - description: Delay time before sending the audio message. - example: 5 - required: - - number - - attachment - parameters: - - name: instanceName - in: path - required: true - schema: - type: string - description: The name of the instance to which the reaction should be sent. - example: 'evolution' - responses: - '200': + "200": description: Successful response content: application/json: {} @@ -654,7 +960,7 @@ paths: type: string description: WhatsApp phone number. example: - - '1234567890' + - "1234567890" required: - numbers parameters: @@ -664,9 +970,9 @@ paths: schema: type: string description: The name of the instance to which the reaction should be sent. - example: 'evolution' + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} @@ -683,7 +989,7 @@ paths: schema: type: object properties: - readMessages: + read_messages: type: array items: type: object @@ -702,7 +1008,7 @@ paths: - fromMe - id required: - - readMessages + - read_messages parameters: - name: instanceName in: path @@ -710,9 +1016,9 @@ paths: schema: type: string description: The name of the instance to which the reaction should be sent. - example: 'evolution' + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} @@ -762,9 +1068,9 @@ paths: schema: type: string description: The name of the instance to which the reaction should be sent. - example: 'evolution' + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} @@ -781,9 +1087,9 @@ paths: schema: type: string description: The name of the instance to which the reaction should be sent. - example: 'evolution' + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} @@ -812,9 +1118,9 @@ paths: schema: type: string description: The name of the instance to which the reaction should be sent. - example: 'evolution' + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} @@ -845,9 +1151,9 @@ paths: schema: type: string description: The name of the instance to which the reaction should be sent. - example: 'evolution' + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} @@ -863,14 +1169,18 @@ paths: schema: type: object properties: - key: + message: type: object properties: - id: - type: string - description: Unique ID of the media message to be converted. - required: - - id + key: + type: object + properties: + id: string + description: Unique ID of the message. + convertToMp4: + type: boolean + description: Indicates whether to convert the media to MP4 format. + example: true parameters: - name: instanceName in: path @@ -878,9 +1188,9 @@ paths: schema: type: string description: The name of the instance to which the reaction should be sent. - example: 'evolution' + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} @@ -929,9 +1239,9 @@ paths: schema: type: string description: The name of the instance to which the reaction should be sent. - example: 'evolution' + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} @@ -962,9 +1272,9 @@ paths: schema: type: string description: The name of the instance to which the reaction should be sent. - example: 'evolution' + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} @@ -981,9 +1291,9 @@ paths: schema: type: string description: The name of the instance to which the reaction should be sent. - example: 'evolution' + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} @@ -1002,25 +1312,25 @@ paths: properties: subject: type: string - description: '- required - The name of the group.' + description: "- required - The name of the group." description: type: string - description: '- optional - A brief description or summary of the group.' + description: "- optional - A brief description or summary of the group." participants: type: array items: type: string - description: '- required - List of participant phone numbers.' + description: "- required - List of participant phone numbers." parameters: - name: instanceName in: path schema: type: string required: true - description: '- required' - example: 'evolution' + description: "- required" + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} @@ -1038,23 +1348,23 @@ paths: properties: image: type: string - description: '- required - URL of the new group picture.' + description: "- required - URL of the new group picture." parameters: - name: groupJid in: query schema: type: string - description: '- required - The unique identifier of the group.' - example: '120363046555718472@g.us' + description: "- required - The unique identifier of the group." + example: "120363046555718472@g.us" - name: instanceName in: path schema: type: string required: true - description: '- required' - example: 'evolution' + description: "- required" + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} @@ -1068,17 +1378,17 @@ paths: in: query schema: type: string - description: '- required - The unique identifier of the group.' - example: '120363046555718472@g.us' + description: "- required - The unique identifier of the group." + example: "120363046555718472@g.us" - name: instanceName in: path schema: type: string required: true - description: '- required' - example: 'evolution' + description: "- required" + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} @@ -1092,17 +1402,17 @@ paths: in: query schema: type: string - description: '- required - The unique identifier of the group.' - example: '120363046555718472@g.us' + description: "- required - The unique identifier of the group." + example: "120363046555718472@g.us" - name: instanceName in: path schema: type: string required: true - description: '- required' - example: 'evolution' + description: "- required" + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} @@ -1116,17 +1426,17 @@ paths: in: query schema: type: string - description: '- required - The unique identifier of the group.' - example: '120363046555718472@g.us' + description: "- required - The unique identifier of the group." + example: "120363046555718472@g.us" - name: instanceName in: path schema: type: string required: true - description: '- required' - example: 'evolution' + description: "- required" + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} @@ -1142,17 +1452,17 @@ paths: in: query schema: type: string - description: '- required - The unique identifier of the group.' - example: '120363046555718472@g.us' + description: "- required - The unique identifier of the group." + example: "120363046555718472@g.us" - name: instanceName in: path schema: type: string required: true - description: '- required' - example: 'evolution' + description: "- required" + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} @@ -1170,23 +1480,23 @@ paths: properties: action: type: string - enum: ['add', 'remove', 'promote', 'demote'] - description: '- required - The action to be taken on the participant.' + enum: ["add", "remove", "promote", "demote"] + description: "- required - The action to be taken on the participant." participants: type: array items: type: string - description: '- required - List of participant phone numbers to be updated.' + description: "- required - List of participant phone numbers to be updated." parameters: - name: instanceName in: path schema: type: string required: true - description: '- required' - example: 'evolution' + description: "- required" + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} @@ -1201,10 +1511,10 @@ paths: schema: type: string required: true - description: '- required' - example: 'evolution' + description: "- required" + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} @@ -1223,9 +1533,9 @@ paths: properties: oldToken: type: string - description: '- required - The expired JWT token.' + description: "- required - The expired JWT token." responses: - '200': + "200": description: Successful response content: application/json: {} @@ -1244,21 +1554,21 @@ paths: properties: enabled: type: boolean - description: 'Indicates whether the webhook is active.' + description: "Indicates whether the webhook is active." url: type: string format: uri - description: 'The endpoint URL where the webhook data will be sent.' + description: "The endpoint URL where the webhook data will be sent." parameters: - name: instanceName in: path schema: type: string required: true - description: '- required' - example: 'evolution' + description: "- required" + example: "evolution" responses: - '200': + "200": description: Successful response content: application/json: {} @@ -1273,10 +1583,10 @@ paths: schema: type: string required: true - description: '- required' - example: 'evolution' + description: "- required" + example: "evolution" responses: - '200': + "200": description: Successful response content: - application/json: {} \ No newline at end of file + application/json: {} diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 567a587e..7eb9296a 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -2384,7 +2384,6 @@ export class WAStartupService { mediaMessage.fileName = arrayMatch[1]; this.logger.verbose('File name: ' + mediaMessage.fileName); } - let mimetype: string; if (mediaMessage.mediatype === 'image' && !mediaMessage.fileName) { mediaMessage.fileName = 'image.png'; @@ -2394,6 +2393,8 @@ export class WAStartupService { mediaMessage.fileName = 'video.mp4'; } + let mimetype: string; + if (isURL(mediaMessage.media)) { mimetype = getMIMEType(mediaMessage.media); } else { From e26ae30f6f4cbc97ce642f9104572c47e84c3657 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 5 Oct 2023 15:57:53 -0300 Subject: [PATCH 10/32] feat: webhook base64 option --- src/dev-env.yml | 1 - src/whatsapp/services/whatsapp.service.ts | 8 +++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/dev-env.yml b/src/dev-env.yml index cadfe105..7af78d40 100644 --- a/src/dev-env.yml +++ b/src/dev-env.yml @@ -97,7 +97,6 @@ WEBHOOK: WEBHOOK_BY_EVENTS: false # Automatically maps webhook paths # Set the events you want to hear - WEBHOOK_BASE64: false EVENTS: APPLICATION_STARTUP: false QRCODE_UPDATED: true diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index e4c25938..56e0bc64 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -279,7 +279,6 @@ export class WAStartupService { this.localWebhook.webhook_base64 = data?.webhook_base64; this.logger.verbose(`Webhook by webhook_base64: ${this.localWebhook.webhook_base64}`); - this.logger.verbose('Webhook loaded'); } @@ -1533,8 +1532,11 @@ export class WAStartupService { } let messageRaw: MessageRaw; - const globalWebhook = this.configService.get('WEBHOOK').GLOBAL; - if (this.localWebhook.webhook_base64 === true && received?.message.documentMessage || received?.message.imageMessage ) { + + if ( + (this.localWebhook.webhook_base64 === true && received?.message.documentMessage) || + received?.message.imageMessage + ) { const buffer = await downloadMediaMessage( { key: received.key, message: received?.message }, 'buffer', From 966b287026e7489b672fa60bd7c6f49105e934c3 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 5 Oct 2023 16:01:47 -0300 Subject: [PATCH 11/32] feat: webhook base64 option --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 43ef7281..f0c1427d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Feature * Swagger documentation +* Added base 64 sending option via webhook ### Fixed @@ -13,6 +14,7 @@ * Adjustment to start typebot, added startSession parameter * Chatwoot now receives messages sent via api and typebot * Fixed problem with starting with an input in typebot +* Added check to ensure variables are not empty before executing foreach in start typebot # 1.5.2 (2023-09-28 17:56) From d5eeb6871497d27a8819edf20207be9539eabe21 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 5 Oct 2023 17:05:41 -0300 Subject: [PATCH 12/32] feat: webhook base64 option --- src/whatsapp/dto/webhook.dto.ts | 1 + src/whatsapp/services/webhook.service.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/whatsapp/dto/webhook.dto.ts b/src/whatsapp/dto/webhook.dto.ts index 5203884d..87a21883 100644 --- a/src/whatsapp/dto/webhook.dto.ts +++ b/src/whatsapp/dto/webhook.dto.ts @@ -3,4 +3,5 @@ export class WebhookDto { url?: string; events?: string[]; webhook_by_events?: boolean; + webhook_base64?: boolean; } diff --git a/src/whatsapp/services/webhook.service.ts b/src/whatsapp/services/webhook.service.ts index 7dbb9d36..810ce96d 100644 --- a/src/whatsapp/services/webhook.service.ts +++ b/src/whatsapp/services/webhook.service.ts @@ -26,7 +26,7 @@ export class WebhookService { return result; } catch (error) { - return { enabled: false, url: '', events: [], webhook_by_events: false, webhook_base64 : false }; + return { enabled: false, url: '', events: [], webhook_by_events: false, webhook_base64: false }; } } } From 857031ff5a62ca575fb9997e4e52ea25130ede23 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 6 Oct 2023 18:05:37 -0300 Subject: [PATCH 13/32] adjusts in swagger --- src/docs/swagger.yaml | 321 ++++++++++++++++++++++----- src/whatsapp/models/typebot.model.ts | 2 +- 2 files changed, 269 insertions(+), 54 deletions(-) diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml index a6170263..07d69ac8 100644 --- a/src/docs/swagger.yaml +++ b/src/docs/swagger.yaml @@ -1368,6 +1368,181 @@ paths: description: Successful response content: application/json: {} + /group/updateGroupSubject/{instanceName}: + put: + tags: + - Group Controller + summary: Update the group's display picture. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + subject: + type: string + description: "- required - The new name of the group." + parameters: + - name: groupJid + in: query + schema: + type: string + description: "- required - The unique identifier of the group." + example: "120363046555718472@g.us" + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + /group/updateGroupDescription/{instanceName}: + put: + tags: + - Group Controller + summary: Update the group's display picture. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + description: + type: string + description: "- required - The new description of the group." + parameters: + - name: groupJid + in: query + schema: + type: string + description: "- required - The unique identifier of the group." + example: "120363046555718472@g.us" + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + /group/inviteCode/{instanceName}: + get: + tags: + - Group Controller + summary: Update the group's display picture. + parameters: + - name: groupJid + in: query + schema: + type: string + description: "- required - The unique identifier of the group." + example: "120363046555718472@g.us" + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + /group/revokeInviteCode/{instanceName}: + put: + tags: + - Group Controller + summary: Update the group's display picture. + parameters: + - name: groupJid + in: query + schema: + type: string + description: "- required - The unique identifier of the group." + example: "120363046555718472@g.us" + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + /group/sendInvite/{instanceName}: + post: + tags: + - Group Controller + summary: Update the group's display picture. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + groupJid: + type: string + description: "The unique identifier of the group." + description: + type: string + description: "The new description of the group." + numbers: + type: array + description: "List of participant phone numbers to be invited." + items: + type: string + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + /group/inviteInfo/{instanceName}: + get: + tags: + - Group Controller + summary: Retrieve details about a specific group. + parameters: + - name: inviteCode + in: query + schema: + type: string + description: "- required - The invite code of the group." + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} /group/findGroupInfos/{instanceName}: get: tags: @@ -1392,6 +1567,29 @@ paths: description: Successful response content: application/json: {} + /group/fetchAllGroups/{instanceName}: + get: + tags: + - Group Controller + summary: Retrieve details about a specific group. + parameters: + - name: getParticipants + in: query + schema: + type: boolean + description: "- required - Indicates whether to retrieve the participants of the group." + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} /group/participants/{instanceName}: get: tags: @@ -1416,56 +1614,6 @@ paths: description: Successful response content: application/json: {} - /group/inviteCode/{instanceName}: - get: - tags: - - Group Controller - summary: Retrieve the group's invite link. - parameters: - - name: groupJid - in: query - schema: - type: string - description: "- required - The unique identifier of the group." - example: "120363046555718472@g.us" - - name: instanceName - in: path - schema: - type: string - required: true - description: "- required" - example: "evolution" - responses: - "200": - description: Successful response - content: - application/json: {} - /group/revokeInviteCode/{instanceName}: - put: - tags: - - Group Controller - summary: Invalidate the existing group invite link. - requestBody: - content: {} - parameters: - - name: groupJid - in: query - schema: - type: string - description: "- required - The unique identifier of the group." - example: "120363046555718472@g.us" - - name: instanceName - in: path - schema: - type: string - required: true - description: "- required" - example: "evolution" - responses: - "200": - description: Successful response - content: - application/json: {} /group/updateParticipant/{instanceName}: put: tags: @@ -1500,6 +1648,63 @@ paths: description: Successful response content: application/json: {} + /group/updateSetting/{instanceName}: + put: + tags: + - Group Controller + summary: Update the status or role of a participant in the group. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + action: + type: string + enum: ["announcement", "not_announcement", "locked", "unlocked"] + description: "- required - The action to be taken on the participant." + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + /group/toggleEphemeral/{instanceName}: + put: + tags: + - Group Controller + summary: Update the status or role of a participant in the group. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + expiration: + type: number + description: "- required - The action to be taken on the participant." + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} /group/leaveGroup/{instanceName}: delete: tags: @@ -1552,13 +1757,23 @@ paths: schema: type: object properties: - enabled: - type: boolean - description: "Indicates whether the webhook is active." url: type: string format: uri description: "The endpoint URL where the webhook data will be sent." + webhook_by_events: + type: boolean + description: "Indicates whether to send the webhook data by events." + webhook_base64: + type: boolean + description: "Indicates whether to send the webhook data in Base64 format." + events: + type: array + enum: [ "APPLICATION_STARTUP", "QRCODE_UPDATED", "MESSAGES_SET", "MESSAGES_UPSERT", "MESSAGES_UPDATE", "MESSAGES_DELETE", "SEND_MESSAGE", "CONTACTS_SET", "CONTACTS_UPSERT", "CONTACTS_UPDATE", "PRESENCE_UPDATE", "CHATS_SET", "CHATS_UPSERT", "CHATS_UPDATE", "CHATS_DELETE", "GROUPS_UPSERT", "GROUP_UPDATE", "GROUP_PARTICIPANTS_UPDATE", "CONNECTION_UPDATE", "CALL", "NEW_JWT_TOKEN" ] + items: + type: string + description: "List of events to be sent to the webhook." + parameters: - name: instanceName in: path diff --git a/src/whatsapp/models/typebot.model.ts b/src/whatsapp/models/typebot.model.ts index c9232bd8..c8ae7105 100644 --- a/src/whatsapp/models/typebot.model.ts +++ b/src/whatsapp/models/typebot.model.ts @@ -48,7 +48,7 @@ const typebotSchema = new Schema({ prefilledVariables: { remoteJid: { type: String, required: false }, pushName: { type: String, required: false }, - additionalData: { type: Schema.Types.Mixed, required: false } + additionalData: { type: Schema.Types.Mixed, required: false }, }, }, ], From eb814e181abbf3522e03cc2dc0327d2439e15bab Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 6 Oct 2023 18:45:26 -0300 Subject: [PATCH 14/32] adjusts in swagger --- src/docs/swagger.yaml | 796 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 793 insertions(+), 3 deletions(-) diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml index 07d69ac8..c58ff582 100644 --- a/src/docs/swagger.yaml +++ b/src/docs/swagger.yaml @@ -1662,7 +1662,8 @@ paths: properties: action: type: string - enum: ["announcement", "not_announcement", "locked", "unlocked"] + enum: + ["announcement", "not_announcement", "locked", "unlocked"] description: "- required - The action to be taken on the participant." parameters: - name: instanceName @@ -1769,11 +1770,33 @@ paths: description: "Indicates whether to send the webhook data in Base64 format." events: type: array - enum: [ "APPLICATION_STARTUP", "QRCODE_UPDATED", "MESSAGES_SET", "MESSAGES_UPSERT", "MESSAGES_UPDATE", "MESSAGES_DELETE", "SEND_MESSAGE", "CONTACTS_SET", "CONTACTS_UPSERT", "CONTACTS_UPDATE", "PRESENCE_UPDATE", "CHATS_SET", "CHATS_UPSERT", "CHATS_UPDATE", "CHATS_DELETE", "GROUPS_UPSERT", "GROUP_UPDATE", "GROUP_PARTICIPANTS_UPDATE", "CONNECTION_UPDATE", "CALL", "NEW_JWT_TOKEN" ] + enum: + [ + "APPLICATION_STARTUP", + "QRCODE_UPDATED", + "MESSAGES_SET", + "MESSAGES_UPSERT", + "MESSAGES_UPDATE", + "MESSAGES_DELETE", + "SEND_MESSAGE", + "CONTACTS_SET", + "CONTACTS_UPSERT", + "CONTACTS_UPDATE", + "PRESENCE_UPDATE", + "CHATS_SET", + "CHATS_UPSERT", + "CHATS_UPDATE", + "CHATS_DELETE", + "GROUPS_UPSERT", + "GROUP_UPDATE", + "GROUP_PARTICIPANTS_UPDATE", + "CONNECTION_UPDATE", + "CALL", + "NEW_JWT_TOKEN", + ] items: type: string description: "List of events to be sent to the webhook." - parameters: - name: instanceName in: path @@ -1805,3 +1828,770 @@ paths: description: Successful response content: application/json: {} + + /websocket/set/{instanceName}: + post: + tags: + - Websocket + summary: Set up or modify the Websocket for an instance. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + enabled: + type: boolean + description: "Indicates whether to enable the websocket." + events: + type: array + enum: + [ + "APPLICATION_STARTUP", + "QRCODE_UPDATED", + "MESSAGES_SET", + "MESSAGES_UPSERT", + "MESSAGES_UPDATE", + "MESSAGES_DELETE", + "SEND_MESSAGE", + "CONTACTS_SET", + "CONTACTS_UPSERT", + "CONTACTS_UPDATE", + "PRESENCE_UPDATE", + "CHATS_SET", + "CHATS_UPSERT", + "CHATS_UPDATE", + "CHATS_DELETE", + "GROUPS_UPSERT", + "GROUP_UPDATE", + "GROUP_PARTICIPANTS_UPDATE", + "CONNECTION_UPDATE", + "CALL", + "NEW_JWT_TOKEN", + ] + items: + type: string + description: "List of events to be sent to the websocket." + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + /websocket/find/{instanceName}: + get: + tags: + - Websocket + summary: Retrieve the websocket settings for a specific instance. + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + + /rabbitmq/set/{instanceName}: + post: + tags: + - RabbitMQ + summary: Set up or modify the RabbitMQ for an instance. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + enabled: + type: boolean + description: "Indicates whether to enable the RabbitMQ." + events: + type: array + enum: + [ + "APPLICATION_STARTUP", + "QRCODE_UPDATED", + "MESSAGES_SET", + "MESSAGES_UPSERT", + "MESSAGES_UPDATE", + "MESSAGES_DELETE", + "SEND_MESSAGE", + "CONTACTS_SET", + "CONTACTS_UPSERT", + "CONTACTS_UPDATE", + "PRESENCE_UPDATE", + "CHATS_SET", + "CHATS_UPSERT", + "CHATS_UPDATE", + "CHATS_DELETE", + "GROUPS_UPSERT", + "GROUP_UPDATE", + "GROUP_PARTICIPANTS_UPDATE", + "CONNECTION_UPDATE", + "CALL", + "NEW_JWT_TOKEN", + ] + items: + type: string + description: "List of events to be sent to the RabbitMQ." + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + /rabbitmq/find/{instanceName}: + get: + tags: + - RabbitMQ + summary: Retrieve the RabbitMQ settings for a specific instance. + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + + /settings/set/{instanceName}: + post: + tags: + - Settings + summary: Set up or modify the Settings for an instance. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + reject_call: + type: boolean + description: "Indicates whether to reject incoming calls." + msg_call: + type: string + description: "Message to be sent when rejecting a call." + groups_ignore: + type: boolean + description: "Indicates whether to ignore group messages." + always_online: + type: boolean + description: "Indicates whether to keep the instance always online." + read_messages: + type: boolean + description: "Indicates whether to mark messages as read." + read_status: + type: boolean + description: "Indicates whether to mark status messages as read." + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + /settings/find/{instanceName}: + get: + tags: + - Settings + summary: Retrieve the Settings for a specific instance. + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + + /chatwoot/set/{instanceName}: + post: + tags: + - Chatwoot + summary: Set up or modify the Chatwoot for an instance. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + enabled: + type: boolean + description: "Indicates whether to enable the Chatwoot integration." + account_id: + type: string + description: "The Chatwoot account ID." + token: + type: string + description: "The Chatwoot token." + url: + type: string + description: "The Chatwoot URL." + sign_msg: + type: boolean + description: "Indicates whether to sign messages." + reopen_conversation: + type: boolean + description: "Indicates whether to reopen conversations." + conversation_pending: + type: boolean + description: "Indicates whether to mark conversations as pending." + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + /chatwoot/find/{instanceName}: + get: + tags: + - Chatwoot + summary: Retrieve the Chatwoot for a specific instance. + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + + /typebot/set/{instanceName}: + post: + tags: + - Typebot + summary: Set up or modify the Typebot for an instance. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + enabled: + type: boolean + description: "Indicates whether to enable the Typebot integration." + url: + type: string + description: "The Chatwoot URL." + typebot: + type: string + description: "The Typebot Name." + expire: + type: number + description: "The Typebot Expire." + keyword_finish: + type: string + description: "The Typebot Keyword Finish." + delay_message: + type: number + description: "The Typebot Delay Message." + unknown_message: + type: string + description: "The Typebot Unknown Message." + listening_from_me: + type: boolean + description: "Indicates whether to listening from me." + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + /typebot/start/{instanceName}: + post: + tags: + - Typebot + summary: Start the Typebot for an instance. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + url: + type: string + description: "The Typebot URL." + typebot: + type: string + description: "The Typebot Name." + remoteJid: + type: string + description: "The Typebot RemoteJid." + startSession: + type: boolean + description: "Indicates whether to start session." + variables: + type: array + description: "List of variables." + items: + type: object + properties: + name: + type: string + description: "The variable name." + value: + type: string + description: "The variable value." + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + /typebot/find/{instanceName}: + get: + tags: + - Typebot + summary: Retrieve the Typebot for a specific instance. + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + /typebot/changeStatus/{instanceName}: + post: + tags: + - Typebot + summary: Change the status of the Typebot for an instance. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + remoteJid: + type: string + description: "The Typebot RemoteJid." + status: + type: string + description: "The Typebot Status." + enum: ["opened", "paused", "closed"] + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + + /proxy/set/{instanceName}: + post: + tags: + - Proxy + summary: Set up or modify the Proxy for an instance. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + enabled: + type: boolean + description: "Indicates whether to enable the Proxy integration." + proxy: + type: string + description: "The Proxy URI." + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + /proxy/find/{instanceName}: + get: + tags: + - Proxy + summary: Retrieve the Proxy for a specific instance. + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + + /chamaai/set/{instanceName}: + post: + tags: + - Chama AI + summary: Set up or modify the Chama AI for an instance. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + enabled: + type: boolean + description: "Indicates whether to enable the Chamai AI integration." + url: + type: string + description: "The Chamai AI URL." + token: + type: string + description: "The Chamai AI Token." + waNumber: + type: string + description: "The Chamai AI WhatsApp Number." + answerByAudio: + type: boolean + description: "Indicates whether to answer by audio." + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + /chamaai/find/{instanceName}: + get: + tags: + - Chama AI + summary: Retrieve the Chama AI for a specific instance. + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + + /chat/fetchBusinessProfile/{instanceName}: + post: + tags: + - Profile Settings + summary: Fetch the business profile of a specific contact. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + number: + type: string + description: "- required - The phone number of the contact." + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + /chat/fetchProfile/{instanceName}: + post: + tags: + - Profile Settings + summary: Fetch the profile of a specific contact. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + number: + type: string + description: "- required - The phone number of the contact." + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + /chat/updateProfileName/{instanceName}: + post: + tags: + - Profile Settings + summary: Update the name of a specific contact. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + name: + type: string + description: "- required - The new name of the contact." + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + /chat/updateProfileStatus/{instanceName}: + post: + tags: + - Profile Settings + summary: Update the status of a specific contact. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + status: + type: string + description: "- required - The new status of the contact." + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + /chat/updateProfilePicture/{instanceName}: + put: + tags: + - Profile Settings + summary: Update the profile picture of a specific contact. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + picture: + type: string + description: "- required - The new profile picture of the contact." + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + /chat/removeProfilePicture/{instanceName}: + delete: + tags: + - Profile Settings + summary: Remove the profile picture of a specific contact. + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + /chat/fetchPrivacySettings/{instanceName}: + get: + tags: + - Profile Settings + summary: Fetch the privacy settings of a specific contact. + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} + /chat/updatePrivacySettings/{instanceName}: + put: + tags: + - Profile Settings + summary: Update the privacy settings of a specific contact. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + privacySettings: + type: object + description: "- required - The new privacy settings of the contact." + properties: + readreceipts: + type: string + enum: ["all", "none"] + description: "- required - The new read receipts privacy setting of the contact." + profile: + type: string + enum: ["all", "contacts", "contact_blacklist", "none"] + description: "- required - The new profile privacy setting of the contact." + status: + type: string + enum: ["all", "contacts", "contact_blacklist", "none"] + description: "- required - The new status privacy setting of the contact." + online: + type: string + enum: ["all", "match_last_seen"] + description: "- required - The new online privacy setting of the contact." + last: + type: string + enum: ["all", "contacts", "contact_blacklist", "none"] + description: "- required - The new last seen privacy setting of the contact." + groupadd: + type: string + enum: ["all", "contacts", "contact_blacklist", "none"] + description: "- required - The new group add privacy setting of the contact." + parameters: + - name: instanceName + in: path + schema: + type: string + required: true + description: "- required" + example: "evolution" + responses: + "200": + description: Successful response + content: + application/json: {} From 047359e8dcff65bd691c6850091729b9432f9213 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 6 Oct 2023 18:55:36 -0300 Subject: [PATCH 15/32] version: 1.5.3 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f0c1427d..c443cfe7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 1.5.3 (develop) +# 1.5.3 (2023-10-06 18:55) ### Feature From 62c74deac3118b7afd6ea0c85e39f0345839a3ca Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 9 Oct 2023 18:00:14 -0300 Subject: [PATCH 16/32] fix: Solved problem with duplicate messages in chatwoot --- CHANGELOG.md | 7 ++ Dockerfile | 2 +- package.json | 2 +- src/docs/swagger.yaml | 2 +- src/whatsapp/controllers/views.controller.ts | 12 +- src/whatsapp/services/chatwoot.service.ts | 6 +- src/whatsapp/services/whatsapp.service.ts | 25 +++-- views/manager-wip.hbs | 110 +++++++++++++++++++ views/manager.hbs | 2 +- 9 files changed, 151 insertions(+), 17 deletions(-) create mode 100644 views/manager-wip.hbs diff --git a/CHANGELOG.md b/CHANGELOG.md index c443cfe7..d4e1b87f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# 1.5.4 (develop) + +### Fixed + +* Baileys logger typing issue resolved +* Solved problem with duplicate messages in chatwoot + # 1.5.3 (2023-10-06 18:55) ### Feature diff --git a/Dockerfile b/Dockerfile index e5c218cc..dee414d6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM node:20.7.0-alpine -LABEL version="1.5.3" description="Api to control whatsapp features through http requests." +LABEL version="1.5.4" description="Api to control whatsapp features through http requests." LABEL maintainer="Davidson Gomes" git="https://github.com/DavidsonGomes" LABEL contact="contato@agenciadgcode.com" diff --git a/package.json b/package.json index 16c7466d..e00f1e39 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.5.3", + "version": "1.5.4", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": { diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml index c58ff582..5f9235ac 100644 --- a/src/docs/swagger.yaml +++ b/src/docs/swagger.yaml @@ -25,7 +25,7 @@ info: [![Run in Postman](https://run.pstmn.io/button.svg)](https://god.gw.postman.com/run-collection/26869335-5546d063-156b-4529-915f-909dd628c090?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D26869335-5546d063-156b-4529-915f-909dd628c090%26entityType%3Dcollection%26workspaceId%3D339a4ee7-378b-45c9-b5b8-fd2c0a9c2442) - version: 1.5.2 + version: 1.5.4 contact: name: DavidsonGomes email: contato@agenciadgcode.com diff --git a/src/whatsapp/controllers/views.controller.ts b/src/whatsapp/controllers/views.controller.ts index e775b960..7e15dfe7 100644 --- a/src/whatsapp/controllers/views.controller.ts +++ b/src/whatsapp/controllers/views.controller.ts @@ -1,15 +1,21 @@ import { Request, Response } from 'express'; -import { ConfigService } from '../../config/env.config'; +import { Auth, ConfigService, HttpServer } from '../../config/env.config'; import { HttpStatus } from '../routers/index.router'; import { WAMonitoringService } from '../services/monitor.service'; export class ViewsController { - constructor(private readonly waMonit: WAMonitoringService, private readonly configService: ConfigService) {} + constructor(private readonly waMonitor: WAMonitoringService, private readonly configService: ConfigService) {} public async manager(request: Request, response: Response) { try { - return response.status(HttpStatus.OK).render('manager'); + const token = this.configService.get('AUTHENTICATION').API_KEY.KEY; + const port = this.configService.get('SERVER').PORT; + + const instances = await this.waMonitor.instanceInfo(); + + console.log('INSTANCES: ', instances); + return response.status(HttpStatus.OK).render('manager', { token, port, instances }); } catch (error) { console.log('ERROR: ', error); } diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 6c145ea2..b19fa31f 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -914,7 +914,7 @@ export class ChatwootService { }, }; - await waInstance?.audioWhatsapp(data); + await waInstance?.audioWhatsapp(data, true); this.logger.verbose('audio sent'); return; @@ -939,7 +939,7 @@ export class ChatwootService { data.mediaMessage.caption = caption; } - await waInstance?.mediaMessage(data); + await waInstance?.mediaMessage(data, true); this.logger.verbose('media sent'); return; @@ -1074,7 +1074,7 @@ export class ChatwootService { }, }; - await waInstance?.textMessage(data); + await waInstance?.textMessage(data, true); } } } diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 56e0bc64..fdd028c0 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -33,6 +33,7 @@ import makeWASocket, { WAMessageUpdate, WASocket, } from '@whiskeysockets/baileys'; +import MAIN_LOGGER from '@whiskeysockets/baileys/lib/Utils/logger'; import axios from 'axios'; import { exec, execSync } from 'child_process'; import { arrayUnique, isBase64, isURL } from 'class-validator'; @@ -131,6 +132,8 @@ import { ChatwootService } from './chatwoot.service'; //import { SocksProxyAgent } from './socks-proxy-agent'; import { TypebotService } from './typebot.service'; +const logger = MAIN_LOGGER.child({}); + export class WAStartupService { constructor( private readonly configService: ConfigService, @@ -1542,7 +1545,7 @@ export class WAStartupService { 'buffer', {}, { - logger: P({ level: 'error' }), + logger: logger, reuploadRequest: this.client.updateMediaMessage, }, ); @@ -2061,7 +2064,12 @@ export class WAStartupService { } } - private async sendMessageWithTyping(number: string, message: T, options?: Options) { + private async sendMessageWithTyping( + number: string, + message: T, + options?: Options, + isChatwoot = false, + ) { this.logger.verbose('Sending message with typing'); this.logger.verbose(`Check if number "${number}" is WhatsApp`); @@ -2219,7 +2227,7 @@ export class WAStartupService { this.logger.verbose('Sending data to webhook in event SEND_MESSAGE'); await this.sendDataWebhook(Events.SEND_MESSAGE, messageRaw); - if (this.localChatwoot.enabled) { + if (this.localChatwoot.enabled && !isChatwoot) { this.chatwootService.eventWhatsapp(Events.SEND_MESSAGE, { instanceName: this.instance.name }, messageRaw); } @@ -2244,7 +2252,7 @@ export class WAStartupService { } // Send Message Controller - public async textMessage(data: SendTextDto) { + public async textMessage(data: SendTextDto, isChatwoot = false) { this.logger.verbose('Sending text message'); return await this.sendMessageWithTyping( data.number, @@ -2252,6 +2260,7 @@ export class WAStartupService { conversation: data.textMessage.text, }, data?.options, + isChatwoot, ); } @@ -2528,11 +2537,11 @@ export class WAStartupService { return result; } - public async mediaMessage(data: SendMediaDto) { + public async mediaMessage(data: SendMediaDto, isChatwoot = false) { this.logger.verbose('Sending media message'); const generate = await this.prepareMediaMessage(data.mediaMessage); - return await this.sendMessageWithTyping(data.number, { ...generate.message }, data?.options); + return await this.sendMessageWithTyping(data.number, { ...generate.message }, data?.options, isChatwoot); } public async processAudio(audio: string, number: string) { @@ -2589,7 +2598,7 @@ export class WAStartupService { }); } - public async audioWhatsapp(data: SendAudioDto) { + public async audioWhatsapp(data: SendAudioDto, isChatwoot = false) { this.logger.verbose('Sending audio whatsapp'); if (!data.options?.encoding && data.options?.encoding !== false) { @@ -2608,6 +2617,7 @@ export class WAStartupService { mimetype: 'audio/mp4', }, { presence: 'recording', delay: data?.options?.delay }, + isChatwoot, ); fs.unlinkSync(convert); @@ -2629,6 +2639,7 @@ export class WAStartupService { mimetype: 'audio/ogg; codecs=opus', }, { presence: 'recording', delay: data?.options?.delay }, + isChatwoot, ); } diff --git a/views/manager-wip.hbs b/views/manager-wip.hbs new file mode 100644 index 00000000..59b0cd0f --- /dev/null +++ b/views/manager-wip.hbs @@ -0,0 +1,110 @@ + + + + + + + + + + + Instance Manager + + + +
+ + + + + + + + + + + + + + + + {{#each instances}} + + + + + + + {{/each}} + +
Nome da InstânciaStatusAPI KeyAções
{{this.instance.instanceName}}{{this.instance.status}}{{this.instance.apikey}} + + +
+
+ + + + + + + + + + + + \ No newline at end of file diff --git a/views/manager.hbs b/views/manager.hbs index 5414bdf1..57d5fca4 100644 --- a/views/manager.hbs +++ b/views/manager.hbs @@ -11,7 +11,7 @@ - + From 957033a7bbab46dca5daafd364118eb8d248a4d4 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 9 Oct 2023 19:57:26 -0300 Subject: [PATCH 17/32] ajustes --- src/whatsapp/services/whatsapp.service.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index fdd028c0..e49c96dd 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -33,7 +33,6 @@ import makeWASocket, { WAMessageUpdate, WASocket, } from '@whiskeysockets/baileys'; -import MAIN_LOGGER from '@whiskeysockets/baileys/lib/Utils/logger'; import axios from 'axios'; import { exec, execSync } from 'child_process'; import { arrayUnique, isBase64, isURL } from 'class-validator'; @@ -132,8 +131,6 @@ import { ChatwootService } from './chatwoot.service'; //import { SocksProxyAgent } from './socks-proxy-agent'; import { TypebotService } from './typebot.service'; -const logger = MAIN_LOGGER.child({}); - export class WAStartupService { constructor( private readonly configService: ConfigService, @@ -1545,7 +1542,7 @@ export class WAStartupService { 'buffer', {}, { - logger: logger, + logger: P({ level: 'error' }) as any, reuploadRequest: this.client.updateMediaMessage, }, ); From 51ec4821f323c6730a0ebf7a3e74c0fc6c19377b Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 9 Oct 2023 20:14:50 -0300 Subject: [PATCH 18/32] fix: adjusts logger --- 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 e49c96dd..17e8d230 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -2947,7 +2947,7 @@ export class WAStartupService { 'buffer', {}, { - logger: P({ level: 'error' }), + logger: P({ level: 'error' }) as any, reuploadRequest: this.client.updateMediaMessage, }, ); From 8588ef1d8a320c8c0ce4aa1a4a3788111ef51a0e Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 9 Oct 2023 20:15:53 -0300 Subject: [PATCH 19/32] fix: adjusts logger --- 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 17e8d230..a693bc25 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1273,7 +1273,7 @@ export class WAStartupService { ...options, auth: { creds: this.instance.authState.state.creds, - keys: makeCacheableSignalKeyStore(this.instance.authState.state.keys, P({ level: 'error' })), + keys: makeCacheableSignalKeyStore(this.instance.authState.state.keys, P({ level: 'error' }) as any), }, logger: P({ level: this.logBaileys }), printQRInTerminal: false, From f32a34190d9808c08d7dbb177d559b0650bdddac Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 9 Oct 2023 20:17:01 -0300 Subject: [PATCH 20/32] fix: adjusts logger --- 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 a693bc25..c4d25c88 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1193,7 +1193,7 @@ export class WAStartupService { ...options, auth: { creds: this.instance.authState.state.creds, - keys: makeCacheableSignalKeyStore(this.instance.authState.state.keys, P({ level: 'error' })), + keys: makeCacheableSignalKeyStore(this.instance.authState.state.keys, P({ level: 'error' }) as any), }, logger: P({ level: this.logBaileys }), printQRInTerminal: false, From 303effebbc4b2cc4ec671c8bbc11ebb6100ac9a8 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Mon, 9 Oct 2023 20:43:30 -0300 Subject: [PATCH 21/32] version: 1.5.4 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4e1b87f..98783e84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 1.5.4 (develop) +# 1.5.4 (2023-10-09 20:43) ### Fixed From a82b206fe62114009dd6ce31b56f2451de183105 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 10 Oct 2023 10:00:11 -0300 Subject: [PATCH 22/32] test: messages.upsert --- src/whatsapp/services/whatsapp.service.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index c4d25c88..7493adc3 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1512,11 +1512,11 @@ export class WAStartupService { const received = messages[0]; if ( - type !== 'notify' || - !received?.message || - received.message?.protocolMessage || - received.message.senderKeyDistributionMessage || - received.message?.pollUpdateMessage + type !== 'notify' + // !received?.message || + // received.message?.protocolMessage || + // received.message.senderKeyDistributionMessage || + // received.message?.pollUpdateMessage ) { this.logger.verbose('message rejected'); return; From d8d7debfee2d8de3113797ec9de6375852a57cac Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 11 Oct 2023 17:27:49 -0300 Subject: [PATCH 23/32] fix: lid messages --- package.json | 2 +- src/whatsapp/services/whatsapp.service.ts | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index e00f1e39..17a90ebc 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "@figuro/chatwoot-sdk": "^1.1.16", "@hapi/boom": "^10.0.1", "@sentry/node": "^7.59.2", - "@whiskeysockets/baileys": "^6.5.0", + "@whiskeysockets/baileys": "github:WhiskeySockets/Baileys#fix-lids", "amqplib": "^0.10.3", "axios": "^1.3.5", "class-validator": "^0.13.2", diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 7493adc3..40ce46a4 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1512,11 +1512,11 @@ export class WAStartupService { const received = messages[0]; if ( - type !== 'notify' - // !received?.message || - // received.message?.protocolMessage || - // received.message.senderKeyDistributionMessage || - // received.message?.pollUpdateMessage + type !== 'notify' || + !received?.message || + received.message?.protocolMessage || + received.message.senderKeyDistributionMessage || + received.message?.pollUpdateMessage ) { this.logger.verbose('message rejected'); return; @@ -1934,8 +1934,8 @@ 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')) { - this.logger.verbose('Number already contains @g.us or @s.whatsapp.net'); + if (number.includes('@g.us') || number.includes('@s.whatsapp.net') || number.includes('@lid')) { + this.logger.verbose('Number already contains @g.us or @s.whatsapp.net or @lid'); return number; } From e157a2a36b48aadde891e4879287b8bfeed4ea8c Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 18 Oct 2023 18:09:01 -0300 Subject: [PATCH 24/32] fix: adjusts in proxy --- src/whatsapp/services/monitor.service.ts | 4 ++-- src/whatsapp/services/whatsapp.service.ts | 27 +++++++++++++++-------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/whatsapp/services/monitor.service.ts b/src/whatsapp/services/monitor.service.ts index 1decd13c..40147bf8 100644 --- a/src/whatsapp/services/monitor.service.ts +++ b/src/whatsapp/services/monitor.service.ts @@ -117,7 +117,7 @@ export class WAMonitoringService { if (this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) { instanceData.instance['serverUrl'] = this.configService.get('SERVER').URL; - instanceData.instance['apikey'] = (await this.repository.auth.find(key)).apikey; + instanceData.instance['apikey'] = (await this.repository.auth.find(key))?.apikey; instanceData.instance['chatwoot'] = chatwoot; } @@ -136,7 +136,7 @@ export class WAMonitoringService { if (this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) { instanceData.instance['serverUrl'] = this.configService.get('SERVER').URL; - instanceData.instance['apikey'] = (await this.repository.auth.find(key)).apikey; + instanceData.instance['apikey'] = (await this.repository.auth.find(key))?.apikey; instanceData.instance['chatwoot'] = chatwoot; } diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 40ce46a4..86ac3176 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -128,9 +128,7 @@ import { Events, MessageSubtype, TypeMediaMessage, wa } from '../types/wa.types' import { waMonitor } from '../whatsapp.module'; import { ChamaaiService } from './chamaai.service'; import { ChatwootService } from './chatwoot.service'; -//import { SocksProxyAgent } from './socks-proxy-agent'; import { TypebotService } from './typebot.service'; - export class WAStartupService { constructor( private readonly configService: ConfigService, @@ -584,7 +582,7 @@ export class WAStartupService { Object.assign(this.localProxy, data); this.logger.verbose('Proxy set'); - this.client?.ws?.close(); + this.reloadConnection(); } public async findProxy() { @@ -1183,10 +1181,22 @@ export class WAStartupService { if (this.localProxy.enabled) { this.logger.verbose('Proxy enabled'); - options = { - agent: new ProxyAgent(this.localProxy.proxy as any), - fetchAgent: new ProxyAgent(this.localProxy.proxy as any), - }; + + if (this.localProxy.proxy.includes('proxyscrape')) { + const response = await axios.get(this.localProxy.proxy); + const text = response.data; + const proxyUrls = text.split('\r\n'); + const rand = Math.floor(Math.random() * Math.floor(proxyUrls.length)); + const proxyUrl = 'http://' + proxyUrls[rand]; + console.log(proxyUrl); + options = { + agent: new ProxyAgent(proxyUrl as any), + }; + } else { + options = { + agent: new ProxyAgent(this.localProxy.proxy as any), + }; + } } const socketConfig: UserFacingSocketConfig = { @@ -1546,7 +1556,6 @@ export class WAStartupService { reuploadRequest: this.client.updateMediaMessage, }, ); - console.log(buffer); messageRaw = { key: received.key, pushName: received.pushName, @@ -3086,7 +3095,7 @@ export class WAStartupService { await this.client.updateGroupsAddPrivacy(settings.privacySettings.groupadd); this.logger.verbose('Groups add privacy updated'); - this.client?.ws?.close(); + this.reloadConnection(); return { update: 'success', From daadc6cb684b7a087c726671968acda01c1d4ffa Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 18 Oct 2023 18:09:26 -0300 Subject: [PATCH 25/32] fix: adjusts in proxy --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98783e84..add0b1f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.5.5 (develop) + +### Fixed + +* Adjusts in proxy + # 1.5.4 (2023-10-09 20:43) ### Fixed From cd6cb8182ec1d40a294bf66a79a3d5c4c41ff1d7 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 24 Oct 2023 12:05:58 -0300 Subject: [PATCH 26/32] fix: start session --- src/whatsapp/services/typebot.service.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/whatsapp/services/typebot.service.ts b/src/whatsapp/services/typebot.service.ts index c329a169..e7669ab9 100644 --- a/src/whatsapp/services/typebot.service.ts +++ b/src/whatsapp/services/typebot.service.ts @@ -121,6 +121,12 @@ export class TypebotService { } if (startSession) { + const session = sessions.find((session) => session.remoteJid === remoteJid); + + if (session) { + sessions.splice(sessions.indexOf(session), 1); + } + const response = await this.createNewSession(instance, { url: url, typebot: typebot, From cc9df1dabb8aef78af0e095124b6f489f03a1dc0 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 24 Oct 2023 12:06:20 -0300 Subject: [PATCH 27/32] fix: start session --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index add0b1f1..114178d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Fixed * Adjusts in proxy +* Adjusts in start session for Typebot # 1.5.4 (2023-10-09 20:43) From d8629e53f1a0eb039ba987a9c463c7bd835c4585 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 24 Oct 2023 13:16:35 -0300 Subject: [PATCH 28/32] fix: start session --- src/whatsapp/services/typebot.service.ts | 59 +++++++++++++++++------- 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/src/whatsapp/services/typebot.service.ts b/src/whatsapp/services/typebot.service.ts index e7669ab9..30f1cb53 100644 --- a/src/whatsapp/services/typebot.service.ts +++ b/src/whatsapp/services/typebot.service.ts @@ -47,7 +47,7 @@ export class TypebotService { findData.sessions.splice(findData.sessions.indexOf(session), 1); const typebotData = { - enabled: true, + enabled: findData.enabled, url: findData.url, typebot: findData.typebot, expire: findData.expire, @@ -71,7 +71,7 @@ export class TypebotService { } const typebotData = { - enabled: true, + enabled: findData.enabled, url: findData.url, typebot: findData.typebot, expire: findData.expire, @@ -102,7 +102,6 @@ export class TypebotService { const startSession = data.startSession; const variables = data.variables; const findTypebot = await this.find(instance); - const sessions = (findTypebot.sessions as Session[]) ?? []; const expire = findTypebot.expire; const keyword_finish = findTypebot.keyword_finish; const delay_message = findTypebot.delay_message; @@ -121,13 +120,10 @@ export class TypebotService { } if (startSession) { - const session = sessions.find((session) => session.remoteJid === remoteJid); - - if (session) { - sessions.splice(sessions.indexOf(session), 1); - } + const newSessions = await this.clearSessions(instance, remoteJid); const response = await this.createNewSession(instance, { + enabled: findTypebot.enabled, url: url, typebot: typebot, remoteJid: remoteJid, @@ -136,7 +132,7 @@ export class TypebotService { delay_message: delay_message, unknown_message: unknown_message, listening_from_me: listening_from_me, - sessions: sessions, + sessions: newSessions, prefilledVariables: prefilledVariables, }); @@ -263,7 +259,7 @@ export class TypebotService { }); const typebotData = { - enabled: true, + enabled: data.enabled, url: data.url, typebot: data.typebot, expire: data.expire, @@ -280,6 +276,37 @@ export class TypebotService { return request.data; } + public async clearSessions(instance: InstanceDto, remoteJid: string) { + const findTypebot = await this.find(instance); + const sessions = (findTypebot.sessions as Session[]) ?? []; + + const sessionWithRemoteJid = sessions.filter((session) => session.remoteJid === remoteJid); + + if (sessionWithRemoteJid.length > 0) { + sessionWithRemoteJid.forEach((session) => { + sessions.splice(sessions.indexOf(session), 1); + }); + + const typebotData = { + enabled: findTypebot.enabled, + url: findTypebot.url, + typebot: findTypebot.typebot, + expire: findTypebot.expire, + keyword_finish: findTypebot.keyword_finish, + delay_message: findTypebot.delay_message, + unknown_message: findTypebot.unknown_message, + listening_from_me: findTypebot.listening_from_me, + sessions, + }; + + this.create(instance, typebotData); + + return sessions; + } + + return sessions; + } + public async sendWAMessage( instance: InstanceDto, remoteJid: string, @@ -450,9 +477,10 @@ export class TypebotService { const diffInMinutes = Math.floor(diff / 1000 / 60); if (diffInMinutes > expire) { - sessions.splice(sessions.indexOf(session), 1); + const newSessions = await this.clearSessions(instance, remoteJid); const data = await this.createNewSession(instance, { + enabled: findTypebot.enabled, url: url, typebot: typebot, expire: expire, @@ -460,7 +488,7 @@ export class TypebotService { delay_message: delay_message, unknown_message: unknown_message, listening_from_me: listening_from_me, - sessions: sessions, + sessions: newSessions, remoteJid: remoteJid, pushName: msg.pushName, }); @@ -487,7 +515,7 @@ export class TypebotService { } if (keyword_finish && content.toLowerCase() === keyword_finish.toLowerCase()) { - sessions.splice(sessions.indexOf(session), 1); + const newSessions = await this.clearSessions(instance, remoteJid); const typebotData = { enabled: true, @@ -498,7 +526,7 @@ export class TypebotService { delay_message: delay_message, unknown_message: unknown_message, listening_from_me: listening_from_me, - sessions, + sessions: newSessions, }; this.create(instance, typebotData); @@ -513,7 +541,6 @@ export class TypebotService { const request = await axios.post(url + '/api/v1/sendMessage', reqData); - console.log('request', request); await this.sendWAMessage( instance, remoteJid, @@ -533,6 +560,7 @@ export class TypebotService { if (!session) { const data = await this.createNewSession(instance, { + enabled: findTypebot.enabled, url: url, typebot: typebot, expire: expire, @@ -593,7 +621,6 @@ export class TypebotService { const request = await axios.post(url + '/api/v1/sendMessage', reqData); - console.log('request', request); await this.sendWAMessage( instance, remoteJid, From 50e1efe5d7ac6051dcea9074f8a002bb1b60f45d Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 25 Oct 2023 07:00:58 -0300 Subject: [PATCH 29/32] fix: start session --- 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 86ac3176..9aab7d29 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1601,7 +1601,7 @@ export class WAStartupService { ); } - if (this.localTypebot.enabled) { + if (this.localTypebot.enabled || this.localTypebot.sessions?.length > 0) { if (!(this.localTypebot.listening_from_me === false && messageRaw.key.fromMe === true)) { await this.typebotService.sendTypebot( { instanceName: this.instance.name }, From bc70ec8b073854adafcda744c21337a7e1a18058 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 25 Oct 2023 08:19:44 -0300 Subject: [PATCH 30/32] fix: start session --- src/whatsapp/services/typebot.service.ts | 8 ++++---- src/whatsapp/services/whatsapp.service.ts | 6 +++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/whatsapp/services/typebot.service.ts b/src/whatsapp/services/typebot.service.ts index 30f1cb53..f29de04f 100644 --- a/src/whatsapp/services/typebot.service.ts +++ b/src/whatsapp/services/typebot.service.ts @@ -518,7 +518,7 @@ export class TypebotService { const newSessions = await this.clearSessions(instance, remoteJid); const typebotData = { - enabled: true, + enabled: findTypebot.enabled, url: url, typebot: typebot, expire: expire, @@ -598,7 +598,7 @@ export class TypebotService { sessions.splice(sessions.indexOf(session), 1); const typebotData = { - enabled: true, + enabled: findTypebot.enabled, url: url, typebot: typebot, expire: expire, @@ -639,7 +639,7 @@ export class TypebotService { }); const typebotData = { - enabled: true, + enabled: findTypebot.enabled, url: url, typebot: typebot, expire: expire, @@ -674,7 +674,7 @@ export class TypebotService { sessions.splice(sessions.indexOf(session), 1); const typebotData = { - enabled: true, + enabled: findTypebot.enabled, url: url, typebot: typebot, expire: expire, diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 9aab7d29..c922cd63 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1601,7 +1601,11 @@ export class WAStartupService { ); } - if (this.localTypebot.enabled || this.localTypebot.sessions?.length > 0) { + const typebotSessionRemoteJid = this.localTypebot.sessions?.find( + (session) => session.remoteJid === received.key.remoteJid, + ); + + if (this.localTypebot.enabled || typebotSessionRemoteJid) { if (!(this.localTypebot.listening_from_me === false && messageRaw.key.fromMe === true)) { await this.typebotService.sendTypebot( { instanceName: this.instance.name }, From 783c00a1d9cff2b12dda87b6952dba33e887560b Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 25 Oct 2023 10:29:24 -0300 Subject: [PATCH 31/32] fix: Added mimetype field when sending media --- CHANGELOG.md | 1 + Dockerfile | 2 +- package.json | 2 +- src/docs/swagger.yaml | 2 +- src/whatsapp/dto/sendMessage.dto.ts | 1 + src/whatsapp/services/whatsapp.service.ts | 11 +++++++---- 6 files changed, 12 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 114178d0..47b359e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Adjusts in proxy * Adjusts in start session for Typebot +* Added mimetype field when sending media # 1.5.4 (2023-10-09 20:43) diff --git a/Dockerfile b/Dockerfile index dee414d6..f60ed48d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM node:20.7.0-alpine -LABEL version="1.5.4" description="Api to control whatsapp features through http requests." +LABEL version="1.5.5" description="Api to control whatsapp features through http requests." LABEL maintainer="Davidson Gomes" git="https://github.com/DavidsonGomes" LABEL contact="contato@agenciadgcode.com" diff --git a/package.json b/package.json index 17a90ebc..7997c3fa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.5.4", + "version": "1.5.5", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": { diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml index 5f9235ac..589ba8dc 100644 --- a/src/docs/swagger.yaml +++ b/src/docs/swagger.yaml @@ -25,7 +25,7 @@ info: [![Run in Postman](https://run.pstmn.io/button.svg)](https://god.gw.postman.com/run-collection/26869335-5546d063-156b-4529-915f-909dd628c090?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D26869335-5546d063-156b-4529-915f-909dd628c090%26entityType%3Dcollection%26workspaceId%3D339a4ee7-378b-45c9-b5b8-fd2c0a9c2442) - version: 1.5.4 + version: 1.5.5 contact: name: DavidsonGomes email: contato@agenciadgcode.com diff --git a/src/whatsapp/dto/sendMessage.dto.ts b/src/whatsapp/dto/sendMessage.dto.ts index c2ddb3a2..e0d6d8f9 100644 --- a/src/whatsapp/dto/sendMessage.dto.ts +++ b/src/whatsapp/dto/sendMessage.dto.ts @@ -61,6 +61,7 @@ export class SendPollDto extends Metadata { export type MediaType = 'image' | 'document' | 'video' | 'audio'; export class MediaMessage { mediatype: MediaType; + mimetype?: string; caption?: string; // for document fileName?: string; diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index c922cd63..6f630b63 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1188,7 +1188,6 @@ export class WAStartupService { const proxyUrls = text.split('\r\n'); const rand = Math.floor(Math.random() * Math.floor(proxyUrls.length)); const proxyUrl = 'http://' + proxyUrls[rand]; - console.log(proxyUrl); options = { agent: new ProxyAgent(proxyUrl as any), }; @@ -2447,10 +2446,14 @@ export class WAStartupService { let mimetype: string; - if (isURL(mediaMessage.media)) { - mimetype = getMIMEType(mediaMessage.media); + if (mediaMessage.mimetype) { + mimetype = mediaMessage.mimetype; } else { - mimetype = getMIMEType(mediaMessage.fileName); + if (isURL(mediaMessage.media)) { + mimetype = getMIMEType(mediaMessage.media); + } else { + mimetype = getMIMEType(mediaMessage.fileName); + } } this.logger.verbose('Mimetype: ' + mimetype); From d0a5ae1da4d6b05bc2864a377b64d656bb01df46 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 26 Oct 2023 18:01:17 -0300 Subject: [PATCH 32/32] fix: Removed senderKeyDistributionMessage --- src/whatsapp/services/whatsapp.service.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 6f630b63..3321605e 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1520,11 +1520,12 @@ export class WAStartupService { this.logger.verbose('Event received: messages.upsert'); const received = messages[0]; + console.log(received, type); if ( type !== 'notify' || !received?.message || received.message?.protocolMessage || - received.message.senderKeyDistributionMessage || + // received.message.senderKeyDistributionMessage || received.message?.pollUpdateMessage ) { this.logger.verbose('message rejected');