From ee0f0f0be0457119e33d98aa055cb93ddbe3731b Mon Sep 17 00:00:00 2001 From: Gabriel Pastori <58153955+gabrielpastori1@users.noreply.github.com> Date: Wed, 6 Dec 2023 00:31:35 -0300 Subject: [PATCH] add send presence router --- src/validate/validate.schema.ts | 10 ++++++ .../controllers/sendMessage.controller.ts | 6 ++++ src/whatsapp/dto/sendMessage.dto.ts | 9 +++++ src/whatsapp/routers/sendMessage.router.ts | 18 ++++++++++ src/whatsapp/services/whatsapp.service.ts | 33 +++++++++++++++++++ 5 files changed, 76 insertions(+) diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 9781e18c..4fad3269 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -149,6 +149,16 @@ export const textMessageSchema: JSONSchema7 = { required: ['textMessage', 'number'], }; +export const presenceSchema: JSONSchema7 = { + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + options: { ...optionsSchema, required: ['presence', 'delay'] }, + }, + required: ['options', 'number'], +}; + export const pollMessageSchema: JSONSchema7 = { $id: v4(), type: 'object', diff --git a/src/whatsapp/controllers/sendMessage.controller.ts b/src/whatsapp/controllers/sendMessage.controller.ts index 20e38ae5..a6b844dc 100644 --- a/src/whatsapp/controllers/sendMessage.controller.ts +++ b/src/whatsapp/controllers/sendMessage.controller.ts @@ -11,6 +11,7 @@ import { SendLocationDto, SendMediaDto, SendPollDto, + SendPresenceDto, SendReactionDto, SendStatusDto, SendStickerDto, @@ -23,6 +24,11 @@ const logger = new Logger('MessageRouter'); export class SendMessageController { constructor(private readonly waMonitor: WAMonitoringService) {} + public async sendPresence({ instanceName }: InstanceDto, data: SendPresenceDto) { + logger.verbose('requested sendPresence from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].sendPresence(data); + } + public async sendText({ instanceName }: InstanceDto, data: SendTextDto) { logger.verbose('requested sendText from ' + instanceName + ' instance'); return await this.waMonitor.waInstances[instanceName].textMessage(data); diff --git a/src/whatsapp/dto/sendMessage.dto.ts b/src/whatsapp/dto/sendMessage.dto.ts index e0d6d8f9..8cc4dd1e 100644 --- a/src/whatsapp/dto/sendMessage.dto.ts +++ b/src/whatsapp/dto/sendMessage.dto.ts @@ -46,9 +46,18 @@ class PollMessage { values: string[]; messageSecret?: Uint8Array; } +export class SendPresenceDto extends Metadata { + options: { + presence: WAPresence; + delay: number; + }; +} export class SendTextDto extends Metadata { textMessage: TextMessage; } +export class SendPresence extends Metadata { + textMessage: TextMessage; +} export class SendStatusDto extends Metadata { statusMessage: StatusMessage; diff --git a/src/whatsapp/routers/sendMessage.router.ts b/src/whatsapp/routers/sendMessage.router.ts index d87db44d..02047249 100644 --- a/src/whatsapp/routers/sendMessage.router.ts +++ b/src/whatsapp/routers/sendMessage.router.ts @@ -9,6 +9,7 @@ import { locationMessageSchema, mediaMessageSchema, pollMessageSchema, + presenceSchema, reactionMessageSchema, statusMessageSchema, stickerMessageSchema, @@ -23,6 +24,7 @@ import { SendLocationDto, SendMediaDto, SendPollDto, + SendPresenceDto, SendReactionDto, SendStatusDto, SendStickerDto, @@ -37,6 +39,22 @@ export class MessageRouter extends RouterBroker { constructor(...guards: RequestHandler[]) { super(); this.router + .post(this.routerPath('sendPresence'), ...guards, async (req, res) => { + logger.verbose('request received in sendText'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: presenceSchema, + ClassRef: SendPresenceDto, + execute: (instance, data) => sendMessageController.sendPresence(instance, data), + }); + + return res.status(HttpStatus.CREATED).json(response); + }) .post(this.routerPath('sendText'), ...guards, async (req, res) => { logger.verbose('request received in sendText'); logger.verbose('request body: '); diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 5c3edc44..83df4b74 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -109,6 +109,7 @@ import { SendLocationDto, SendMediaDto, SendPollDto, + SendPresenceDto, SendReactionDto, SendStatusDto, SendStickerDto, @@ -2387,6 +2388,38 @@ export class WAStartupService { return this.stateConnection; } + public async sendPresence(data: SendPresenceDto) { + try { + const { number } = data; + + this.logger.verbose(`Check if number "${number}" is WhatsApp`); + const isWA = (await this.whatsappNumber({ numbers: [number] }))?.shift(); + + this.logger.verbose(`Exists: "${isWA.exists}" | jid: ${isWA.jid}`); + if (!isWA.exists && !isJidGroup(isWA.jid) && !isWA.jid.includes('@broadcast')) { + throw new BadRequestException(isWA); + } + + const sender = isWA.jid; + + this.logger.verbose('Sending presence'); + await this.client.presenceSubscribe(sender); + this.logger.verbose('Subscribing to presence'); + + await this.client.sendPresenceUpdate(data.options?.presence ?? 'composing', sender); + this.logger.verbose('Sending presence update: ' + data.options?.presence ?? 'composing'); + + await delay(data.options.delay); + this.logger.verbose('Set delay: ' + data.options.delay); + + await this.client.sendPresenceUpdate('paused', sender); + this.logger.verbose('Sending presence update: paused'); + } catch (error) { + this.logger.error(error); + throw new BadRequestException(error.toString()); + } + } + // Send Message Controller public async textMessage(data: SendTextDto, isChatwoot = false) { this.logger.verbose('Sending text message');