diff --git a/.env.example b/.env.example index 02eca612..1a320aa1 100644 --- a/.env.example +++ b/.env.example @@ -62,6 +62,7 @@ RABBITMQ_EVENTS_MESSAGES_EDITED=false RABBITMQ_EVENTS_MESSAGES_UPDATE=false RABBITMQ_EVENTS_MESSAGES_DELETE=false RABBITMQ_EVENTS_SEND_MESSAGE=false +RABBITMQ_EVENTS_SEND_MESSAGE_UPDATE=false RABBITMQ_EVENTS_CONTACTS_SET=false RABBITMQ_EVENTS_CONTACTS_UPSERT=false RABBITMQ_EVENTS_CONTACTS_UPDATE=false @@ -108,6 +109,7 @@ PUSHER_EVENTS_MESSAGES_EDITED=true PUSHER_EVENTS_MESSAGES_UPDATE=true PUSHER_EVENTS_MESSAGES_DELETE=true PUSHER_EVENTS_SEND_MESSAGE=true +PUSHER_EVENTS_SEND_MESSAGE_UPDATE=true PUSHER_EVENTS_CONTACTS_SET=true PUSHER_EVENTS_CONTACTS_UPSERT=true PUSHER_EVENTS_CONTACTS_UPDATE=true @@ -149,6 +151,7 @@ WEBHOOK_EVENTS_MESSAGES_EDITED=true WEBHOOK_EVENTS_MESSAGES_UPDATE=true WEBHOOK_EVENTS_MESSAGES_DELETE=true WEBHOOK_EVENTS_SEND_MESSAGE=true +WEBHOOK_EVENTS_SEND_MESSAGE_UPDATE=true WEBHOOK_EVENTS_CONTACTS_SET=true WEBHOOK_EVENTS_CONTACTS_UPSERT=true WEBHOOK_EVENTS_CONTACTS_UPDATE=true diff --git a/Docker/swarm/evolution_api_v2.yaml b/Docker/swarm/evolution_api_v2.yaml index 867251a5..6bf9629e 100644 --- a/Docker/swarm/evolution_api_v2.yaml +++ b/Docker/swarm/evolution_api_v2.yaml @@ -34,6 +34,7 @@ services: - RABBITMQ_EVENTS_MESSAGES_UPDATE=false - RABBITMQ_EVENTS_MESSAGES_DELETE=false - RABBITMQ_EVENTS_SEND_MESSAGE=false + - RABBITMQ_EVENTS_SEND_MESSAGE_UPDATE=false - RABBITMQ_EVENTS_CONTACTS_SET=false - RABBITMQ_EVENTS_CONTACTS_UPSERT=false - RABBITMQ_EVENTS_CONTACTS_UPDATE=false @@ -71,6 +72,7 @@ services: - WEBHOOK_EVENTS_MESSAGES_UPDATE=true - WEBHOOK_EVENTS_MESSAGES_DELETE=true - WEBHOOK_EVENTS_SEND_MESSAGE=true + - WEBHOOK_EVENTS_SEND_MESSAGE_UPDATE=true - WEBHOOK_EVENTS_CONTACTS_SET=true - WEBHOOK_EVENTS_CONTACTS_UPSERT=true - WEBHOOK_EVENTS_CONTACTS_UPDATE=true diff --git a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts index bafefa18..542e2f72 100644 --- a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts +++ b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts @@ -1135,37 +1135,39 @@ export class BaileysStartupService extends ChannelStartupService { const editedMessage = received?.message?.protocolMessage || received?.message?.editedMessage?.message?.protocolMessage; - if (received.message?.protocolMessage?.editedMessage || received.message?.editedMessage?.message) { - if (editedMessage) { - if (this.configService.get('CHATWOOT').ENABLED && this.localChatwoot?.enabled) - this.chatwootService.eventWhatsapp( - 'messages.edit', - { instanceName: this.instance.name, instanceId: this.instance.id }, - editedMessage, - ); + if (received.message?.protocolMessage?.editedMessage && editedMessage) { + if (this.configService.get('CHATWOOT').ENABLED && this.localChatwoot?.enabled) + this.chatwootService.eventWhatsapp( + 'messages.edit', + { instanceName: this.instance.name, instanceId: this.instance.id }, + editedMessage, + ); - await this.sendDataWebhook(Events.MESSAGES_EDITED, editedMessage); - const oldMessage = await this.getMessage(editedMessage.key, true); - if ((oldMessage as any)?.id) { - await this.prismaRepository.message.update({ - where: { id: (oldMessage as any).id }, - data: { - message: editedMessage.editedMessage as any, - messageTimestamp: (editedMessage.timestampMs as Long.Long).toNumber(), - status: 'EDITED', - }, - }); - await this.prismaRepository.messageUpdate.create({ - data: { - fromMe: editedMessage.key.fromMe, - keyId: editedMessage.key.id, - remoteJid: editedMessage.key.remoteJid, - status: 'EDITED', - instanceId: this.instanceId, - messageId: (oldMessage as any).id, - }, - }); - } + await this.sendDataWebhook(Events.MESSAGES_EDITED, editedMessage); + const oldMessage = await this.getMessage(editedMessage.key, true); + if ((oldMessage as any)?.id) { + const editedMessageTimestamp = Long.isLong(editedMessage?.timestampMs) + ? editedMessage.timestampMs?.toNumber() + : (editedMessage.timestampMs as number); + + await this.prismaRepository.message.update({ + where: { id: (oldMessage as any).id }, + data: { + message: editedMessage.editedMessage as any, + messageTimestamp: editedMessageTimestamp, + status: 'EDITED', + }, + }); + await this.prismaRepository.messageUpdate.create({ + data: { + fromMe: editedMessage.key.fromMe, + keyId: editedMessage.key.id, + remoteJid: editedMessage.key.remoteJid, + status: 'EDITED', + instanceId: this.instanceId, + messageId: (oldMessage as any).id, + }, + }); } } @@ -3972,71 +3974,71 @@ export class BaileysStartupService extends ChannelStartupService { throw new BadRequestException('Message is older than 15 minutes'); } - const response = await this.client.sendMessage(jid, { + const messageSent = await this.client.sendMessage(jid, { ...(options as any), edit: data.key, }); - if (response) { - const messageId = response.message?.protocolMessage?.key?.id; - if (messageId) { - let message = await this.prismaRepository.message.findFirst({ - where: { - key: { - path: ['id'], - equals: messageId, + if (messageSent) { + const editedMessage = + messageSent?.message?.protocolMessage || messageSent?.message?.editedMessage?.message?.protocolMessage; + + if (editedMessage) { + this.sendDataWebhook(Events.SEND_MESSAGE_UPDATE, editedMessage); + if (this.configService.get('CHATWOOT').ENABLED && this.localChatwoot?.enabled) + this.chatwootService.eventWhatsapp( + 'send.message.update', + { instanceName: this.instance.name, instanceId: this.instance.id }, + editedMessage, + ); + + const messageId = messageSent.message?.protocolMessage?.key?.id; + if (messageId) { + let message = await this.prismaRepository.message.findFirst({ + where: { + key: { + path: ['id'], + equals: messageId, + }, }, - }, - }); - if (!message) throw new NotFoundException('Message not found'); + }); + if (!message) throw new NotFoundException('Message not found'); - if (!(message.key.valueOf() as any).fromMe) { - new BadRequestException('You cannot edit others messages'); - } - if ((message.key.valueOf() as any)?.deleted) { - new BadRequestException('You cannot edit deleted messages'); - } - if (oldMessage.messageType === 'conversation' || oldMessage.messageType === 'extendedTextMessage') { - oldMessage.message.conversation = data.text; - } else { - oldMessage.message[oldMessage.messageType].caption = data.text; - } - message = await this.prismaRepository.message.update({ - where: { id: message.id }, - data: { - message: oldMessage.message, + if (!(message.key.valueOf() as any).fromMe) { + new BadRequestException('You cannot edit others messages'); + } + if ((message.key.valueOf() as any)?.deleted) { + new BadRequestException('You cannot edit deleted messages'); + } + if (oldMessage.messageType === 'conversation' || oldMessage.messageType === 'extendedTextMessage') { + oldMessage.message.conversation = data.text; + } else { + oldMessage.message[oldMessage.messageType].caption = data.text; + } + message = await this.prismaRepository.message.update({ + where: { id: message.id }, + data: { + message: oldMessage.message, + status: 'EDITED', + messageTimestamp: Math.floor(Date.now() / 1000), // Convert to int32 by dividing by 1000 to get seconds + }, + }); + const messageUpdate: any = { + messageId: message.id, + keyId: messageId, + remoteJid: messageSent.key.remoteJid, + fromMe: messageSent.key.fromMe, + participant: messageSent.key?.remoteJid, status: 'EDITED', - messageTimestamp: Math.floor(Date.now() / 1000), // Convert to int32 by dividing by 1000 to get seconds - }, - }); - const messageUpdate: any = { - messageId: message.id, - keyId: messageId, - remoteJid: response.key.remoteJid, - fromMe: response.key.fromMe, - participant: response.key?.remoteJid, - status: 'EDITED', - instanceId: this.instanceId, - }; - await this.prismaRepository.messageUpdate.create({ - data: messageUpdate, - }); - - this.sendDataWebhook(Events.MESSAGES_EDITED, { - id: message.id, - instanceId: message.instanceId, - key: message.key, - messageType: message.messageType, - status: 'EDITED', - source: message.source, - messageTimestamp: message.messageTimestamp, - pushName: message.pushName, - participant: message.participant, - message: message.message, - }); + instanceId: this.instanceId, + }; + await this.prismaRepository.messageUpdate.create({ + data: messageUpdate, + }); + } } } - return response; + return messageSent; } catch (error) { this.logger.error(error); throw error; diff --git a/src/api/integrations/chatbot/chatwoot/services/chatwoot.service.ts b/src/api/integrations/chatbot/chatwoot/services/chatwoot.service.ts index 23eb1c5c..ed3f1899 100644 --- a/src/api/integrations/chatbot/chatwoot/services/chatwoot.service.ts +++ b/src/api/integrations/chatbot/chatwoot/services/chatwoot.service.ts @@ -2199,7 +2199,7 @@ export class ChatwootService { } } - if (event === 'messages.edit') { + if (event === 'messages.edit' || event === 'send.message.update') { const editedText = `${ body?.editedMessage?.conversation || body?.editedMessage?.extendedTextMessage?.text }\n\n_\`${i18next.t('cw.message.edited')}.\`_`; diff --git a/src/api/integrations/event/event.controller.ts b/src/api/integrations/event/event.controller.ts index 72c02132..7df3de92 100644 --- a/src/api/integrations/event/event.controller.ts +++ b/src/api/integrations/event/event.controller.ts @@ -132,6 +132,7 @@ export class EventController { 'MESSAGES_UPDATE', 'MESSAGES_DELETE', 'SEND_MESSAGE', + 'SEND_MESSAGE_UPDATE', 'CONTACTS_SET', 'CONTACTS_UPSERT', 'CONTACTS_UPDATE', diff --git a/src/api/types/wa.types.ts b/src/api/types/wa.types.ts index 0aad0696..2bb3dc1e 100644 --- a/src/api/types/wa.types.ts +++ b/src/api/types/wa.types.ts @@ -15,6 +15,7 @@ export enum Events { MESSAGES_UPDATE = 'messages.update', MESSAGES_DELETE = 'messages.delete', SEND_MESSAGE = 'send.message', + SEND_MESSAGE_UPDATE = 'send.message.update', CONTACTS_SET = 'contacts.set', CONTACTS_UPSERT = 'contacts.upsert', CONTACTS_UPDATE = 'contacts.update', diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 9eff0738..908bdc2a 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -72,6 +72,7 @@ export type EventsRabbitmq = { MESSAGES_UPDATE: boolean; MESSAGES_DELETE: boolean; SEND_MESSAGE: boolean; + SEND_MESSAGE_UPDATE: boolean; CONTACTS_SET: boolean; CONTACTS_UPDATE: boolean; CONTACTS_UPSERT: boolean; @@ -140,6 +141,7 @@ export type EventsWebhook = { MESSAGES_UPDATE: boolean; MESSAGES_DELETE: boolean; SEND_MESSAGE: boolean; + SEND_MESSAGE_UPDATE: boolean; CONTACTS_SET: boolean; CONTACTS_UPDATE: boolean; CONTACTS_UPSERT: boolean; @@ -172,6 +174,7 @@ export type EventsPusher = { MESSAGES_UPDATE: boolean; MESSAGES_DELETE: boolean; SEND_MESSAGE: boolean; + SEND_MESSAGE_UPDATE: boolean; CONTACTS_SET: boolean; CONTACTS_UPDATE: boolean; CONTACTS_UPSERT: boolean; @@ -380,6 +383,7 @@ export class ConfigService { MESSAGES_UPDATE: process.env?.RABBITMQ_EVENTS_MESSAGES_UPDATE === 'true', MESSAGES_DELETE: process.env?.RABBITMQ_EVENTS_MESSAGES_DELETE === 'true', SEND_MESSAGE: process.env?.RABBITMQ_EVENTS_SEND_MESSAGE === 'true', + SEND_MESSAGE_UPDATE: process.env?.RABBITMQ_EVENTS_SEND_MESSAGE_UPDATE === 'true', CONTACTS_SET: process.env?.RABBITMQ_EVENTS_CONTACTS_SET === 'true', CONTACTS_UPDATE: process.env?.RABBITMQ_EVENTS_CONTACTS_UPDATE === 'true', CONTACTS_UPSERT: process.env?.RABBITMQ_EVENTS_CONTACTS_UPSERT === 'true', @@ -416,6 +420,7 @@ export class ConfigService { MESSAGES_UPDATE: process.env?.NATS_EVENTS_MESSAGES_UPDATE === 'true', MESSAGES_DELETE: process.env?.NATS_EVENTS_MESSAGES_DELETE === 'true', SEND_MESSAGE: process.env?.NATS_EVENTS_SEND_MESSAGE === 'true', + SEND_MESSAGE_UPDATE: process.env?.NATS_EVENTS_SEND_MESSAGE_UPDATE === 'true', CONTACTS_SET: process.env?.NATS_EVENTS_CONTACTS_SET === 'true', CONTACTS_UPDATE: process.env?.NATS_EVENTS_CONTACTS_UPDATE === 'true', CONTACTS_UPSERT: process.env?.NATS_EVENTS_CONTACTS_UPSERT === 'true', @@ -467,6 +472,7 @@ export class ConfigService { MESSAGES_UPDATE: process.env?.PUSHER_EVENTS_MESSAGES_UPDATE === 'true', MESSAGES_DELETE: process.env?.PUSHER_EVENTS_MESSAGES_DELETE === 'true', SEND_MESSAGE: process.env?.PUSHER_EVENTS_SEND_MESSAGE === 'true', + SEND_MESSAGE_UPDATE: process.env?.PUSHER_EVENTS_SEND_MESSAGE_UPDATE === 'true', CONTACTS_SET: process.env?.PUSHER_EVENTS_CONTACTS_SET === 'true', CONTACTS_UPDATE: process.env?.PUSHER_EVENTS_CONTACTS_UPDATE === 'true', CONTACTS_UPSERT: process.env?.PUSHER_EVENTS_CONTACTS_UPSERT === 'true', @@ -523,6 +529,7 @@ export class ConfigService { MESSAGES_UPDATE: process.env?.WEBHOOK_EVENTS_MESSAGES_UPDATE === 'true', MESSAGES_DELETE: process.env?.WEBHOOK_EVENTS_MESSAGES_DELETE === 'true', SEND_MESSAGE: process.env?.WEBHOOK_EVENTS_SEND_MESSAGE === 'true', + SEND_MESSAGE_UPDATE: process.env?.WEBHOOK_EVENTS_SEND_MESSAGE_UPDATE === 'true', CONTACTS_SET: process.env?.WEBHOOK_EVENTS_CONTACTS_SET === 'true', CONTACTS_UPDATE: process.env?.WEBHOOK_EVENTS_CONTACTS_UPDATE === 'true', CONTACTS_UPSERT: process.env?.WEBHOOK_EVENTS_CONTACTS_UPSERT === 'true', diff --git a/src/validate/instance.schema.ts b/src/validate/instance.schema.ts index 11a708f0..a0553b66 100644 --- a/src/validate/instance.schema.ts +++ b/src/validate/instance.schema.ts @@ -68,6 +68,7 @@ export const instanceSchema: JSONSchema7 = { 'MESSAGES_UPDATE', 'MESSAGES_DELETE', 'SEND_MESSAGE', + 'SEND_MESSAGE_UPDATE', 'CONTACTS_SET', 'CONTACTS_UPSERT', 'CONTACTS_UPDATE', @@ -104,6 +105,7 @@ export const instanceSchema: JSONSchema7 = { 'MESSAGES_UPDATE', 'MESSAGES_DELETE', 'SEND_MESSAGE', + 'SEND_MESSAGE_UPDATE', 'CONTACTS_SET', 'CONTACTS_UPSERT', 'CONTACTS_UPDATE', @@ -140,6 +142,7 @@ export const instanceSchema: JSONSchema7 = { 'MESSAGES_UPDATE', 'MESSAGES_DELETE', 'SEND_MESSAGE', + 'SEND_MESSAGE_UPDATE', 'CONTACTS_SET', 'CONTACTS_UPSERT', 'CONTACTS_UPDATE', @@ -176,6 +179,7 @@ export const instanceSchema: JSONSchema7 = { 'MESSAGES_UPDATE', 'MESSAGES_DELETE', 'SEND_MESSAGE', + 'SEND_MESSAGE_UPDATE', 'CONTACTS_SET', 'CONTACTS_UPSERT', 'CONTACTS_UPDATE',