From 69c10596442980d8d93ec84cbfb0b345e172fd59 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Thu, 6 Jul 2023 13:55:14 -0300 Subject: [PATCH] feat: Route to send status broadcast --- CHANGELOG.md | 6 ++++ package.json | 2 +- src/validate/validate.schema.ts | 28 ++++++++++++++++ .../controllers/sendMessage.controller.ts | 5 +++ src/whatsapp/dto/sendMessage.dto.ts | 11 +++++++ src/whatsapp/routers/sendMessage.router.ts | 12 +++++++ src/whatsapp/services/whatsapp.service.ts | 33 +++++++++++++++++-- 7 files changed, 94 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7061bc15..06c8e4e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.1.4 (homolog) + +### Features + +* Route to send status broadcast + # 1.1.3 (2023-07-06 11:43) ### Features diff --git a/package.json b/package.json index 0e73166f..5c50a877 100644 --- a/package.json +++ b/package.json @@ -40,10 +40,10 @@ }, "homepage": "https://github.com/DavidsonGomes/evolution-api#readme", "dependencies": { + "@whiskeysockets/baileys": "github:EvolutionAPI/Baileys", "@adiwajshing/keyed-db": "^0.2.4", "@ffmpeg-installer/ffmpeg": "^1.1.0", "@hapi/boom": "^10.0.1", - "@whiskeysockets/baileys": "^6.3.0", "axios": "^1.3.5", "class-validator": "^0.13.2", "compression": "^1.7.4", diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 66388634..9a8fae2d 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -189,6 +189,34 @@ export const pollMessageSchema: JSONSchema7 = { required: ['pollMessage', 'number'], }; +export const statusMessageSchema: JSONSchema7 = { + $id: v4(), + type: 'object', + properties: { + statusMessage: { + type: 'object', + properties: { + text: { type: 'string' }, + backgroundColor: { type: 'string' }, + font: { type: 'integer', minimum: 0, maximum: 5 }, + statusJidList: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + pattern: '^\\d+', + description: '"statusJidList" must be an array of numeric strings', + }, + }, + }, + required: ['text', 'backgroundColor', 'font', 'statusJidList'], + ...isNotEmpty('text', 'backgroundColor', 'font', 'statusJidList'), + }, + }, + required: ['statusMessage'], +}; + export const mediaMessageSchema: JSONSchema7 = { $id: v4(), type: 'object', diff --git a/src/whatsapp/controllers/sendMessage.controller.ts b/src/whatsapp/controllers/sendMessage.controller.ts index b985d5e7..8e70c26c 100644 --- a/src/whatsapp/controllers/sendMessage.controller.ts +++ b/src/whatsapp/controllers/sendMessage.controller.ts @@ -11,6 +11,7 @@ import { SendMediaDto, SendPollDto, SendReactionDto, + SendStatusDto, SendStickerDto, SendTextDto, } from '../dto/sendMessage.dto'; @@ -80,6 +81,10 @@ export class SendMessageController { return await this.waMonitor.waInstances[instanceName].pollMessage(data); } + public async sendStatus({ instanceName }: InstanceDto, data: SendStatusDto) { + return await this.waMonitor.waInstances[instanceName].statusMessage(data); + } + public async sendLinkPreview({ instanceName }: InstanceDto, data: SendLinkPreviewDto) { return await this.waMonitor.waInstances[instanceName].linkPreview(data); } diff --git a/src/whatsapp/dto/sendMessage.dto.ts b/src/whatsapp/dto/sendMessage.dto.ts index 0d3f7183..1b9708fa 100644 --- a/src/whatsapp/dto/sendMessage.dto.ts +++ b/src/whatsapp/dto/sendMessage.dto.ts @@ -32,6 +32,13 @@ class linkPreviewMessage { text: string; } +class StatusMessage { + text: string; + backgroundColor: string; + font: number; + statusJidList: string[]; +} + class PollMessage { name: string; selectableCount: number; @@ -46,6 +53,10 @@ export class SendLinkPreviewDto extends Metadata { linkPreview: linkPreviewMessage; } +export class SendStatusDto extends Metadata { + statusMessage: StatusMessage; +} + export class SendPollDto extends Metadata { pollMessage: PollMessage; } diff --git a/src/whatsapp/routers/sendMessage.router.ts b/src/whatsapp/routers/sendMessage.router.ts index b2400f7f..92b01557 100644 --- a/src/whatsapp/routers/sendMessage.router.ts +++ b/src/whatsapp/routers/sendMessage.router.ts @@ -9,6 +9,7 @@ import { mediaMessageSchema, pollMessageSchema, reactionMessageSchema, + statusMessageSchema, stickerMessageSchema, textMessageSchema, } from '../../validate/validate.schema'; @@ -22,6 +23,7 @@ import { SendMediaDto, SendPollDto, SendReactionDto, + SendStatusDto, SendStickerDto, SendTextDto, } from '../dto/sendMessage.dto'; @@ -124,6 +126,16 @@ export class MessageRouter extends RouterBroker { return res.status(HttpStatus.CREATED).json(response); }) + .post(this.routerPath('sendStatus'), ...guards, async (req, res) => { + const response = await this.dataValidate({ + request: req, + schema: statusMessageSchema, + ClassRef: SendStatusDto, + execute: (instance, data) => sendMessageController.sendStatus(instance, data), + }); + + return res.status(HttpStatus.CREATED).json(response); + }) .post(this.routerPath('sendLinkPreview'), ...guards, async (req, res) => { const response = await this.dataValidate({ request: req, diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 4f30f72c..4ad8ce39 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -77,6 +77,7 @@ import { SendPollDto, SendLinkPreviewDto, SendStickerDto, + SendStatusDto, } from '../dto/sendMessage.dto'; import { arrayUnique, isBase64, isURL } from 'class-validator'; import { @@ -1098,6 +1099,11 @@ export class WAStartupService { return number; } + if (number.includes('@broadcast')) { + this.logger.verbose('Number already contains @broadcast'); + return number; + } + const formattedBRNumber = this.formatBRNumber(number); if (formattedBRNumber !== number) { this.logger.verbose( @@ -1152,7 +1158,7 @@ export class WAStartupService { const jid = this.createJid(number); const isWA = (await this.whatsappNumber({ numbers: [jid] }))[0]; - if (!isWA.exists && !isJidGroup(isWA.jid)) { + if (!isWA.exists && !isJidGroup(isWA.jid) && !isWA.jid.includes('@broadcast')) { throw new BadRequestException(isWA); } @@ -1229,7 +1235,8 @@ export class WAStartupService { !message['audio'] && !message['poll'] && !message['linkPreview'] && - !message['sticker'] + !message['sticker'] && + !message['status'] ) { if (!message['audio']) { this.logger.verbose('Sending message'); @@ -1258,6 +1265,21 @@ export class WAStartupService { ); } + if (message['status']) { + this.logger.verbose('Sending message'); + return await this.client.sendMessage( + sender, + { + text: message['status'].text, + } as unknown as AnyMessageContent, + { + backgroundColor: message['status'].backgroundColor, + font: message['status'].font, + statusJidList: message['status'].statusJidList, + } as unknown as MiscMessageGenerationOptions, + ); + } + this.logger.verbose('Sending message'); return await this.client.sendMessage( sender, @@ -1335,6 +1357,13 @@ export class WAStartupService { ); } + public async statusMessage(data: SendStatusDto) { + this.logger.verbose('Sending status message'); + return await this.sendMessageWithTyping('status@broadcast', { + status: data.statusMessage, + }); + } + private async prepareMediaMessage(mediaMessage: MediaMessage) { try { this.logger.verbose('Preparing media message');