diff --git a/package.json b/package.json index 04167b86..b5ab7022 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "@sentry/node": "^8.28.0", "amqplib": "^0.10.3", "axios": "^1.6.5", - "baileys": "6.7.8", + "baileys": "github:fmedeiros95/Baileys", "class-validator": "^0.14.1", "compression": "^1.7.4", "cors": "^2.8.5", diff --git a/src/api/controllers/sendMessage.controller.ts b/src/api/controllers/sendMessage.controller.ts index 0d6ea33e..201d359c 100644 --- a/src/api/controllers/sendMessage.controller.ts +++ b/src/api/controllers/sendMessage.controller.ts @@ -1,5 +1,6 @@ import { InstanceDto } from '@api/dto/instance.dto'; import { + OfferCallDto, SendAudioDto, SendButtonDto, SendContactDto, @@ -83,4 +84,8 @@ export class SendMessageController { public async sendStatus({ instanceName }: InstanceDto, data: SendStatusDto, file?: any) { return await this.waMonitor.waInstances[instanceName].statusMessage(data, file); } + + public async offerCall({ instanceName }: InstanceDto, data: OfferCallDto) { + return await this.waMonitor.waInstances[instanceName].offerCall(data); + } } diff --git a/src/api/dto/sendMessage.dto.ts b/src/api/dto/sendMessage.dto.ts index 8d3ba1a0..3dcabbe4 100644 --- a/src/api/dto/sendMessage.dto.ts +++ b/src/api/dto/sendMessage.dto.ts @@ -46,6 +46,11 @@ export class Metadata { encoding?: boolean; } +export class OfferCallDto extends Metadata { + isVideo?: boolean; + callDuration?: number; +} + export class SendTextDto extends Metadata { text: string; } diff --git a/src/api/integrations/channel/evolution/evolution.channel.service.ts b/src/api/integrations/channel/evolution/evolution.channel.service.ts index 28d73d7f..c3f3f4d6 100644 --- a/src/api/integrations/channel/evolution/evolution.channel.service.ts +++ b/src/api/integrations/channel/evolution/evolution.channel.service.ts @@ -555,6 +555,9 @@ export class EvolutionStartupService extends ChannelStartupService { public async fetchProfile() { throw new BadRequestException('Method not available on Evolution Channel'); } + public async offerCall() { + throw new BadRequestException('Method not available on WhatsApp Business API'); + } public async sendPresence() { throw new BadRequestException('Method not available on Evolution Channel'); } diff --git a/src/api/integrations/channel/meta/whatsapp.business.service.ts b/src/api/integrations/channel/meta/whatsapp.business.service.ts index f3bccdfd..f7eef675 100644 --- a/src/api/integrations/channel/meta/whatsapp.business.service.ts +++ b/src/api/integrations/channel/meta/whatsapp.business.service.ts @@ -1359,6 +1359,9 @@ export class BusinessStartupService extends ChannelStartupService { public async fetchProfile() { throw new BadRequestException('Method not available on WhatsApp Business API'); } + public async offerCall() { + throw new BadRequestException('Method not available on WhatsApp Business API'); + } public async sendPresence() { throw new BadRequestException('Method not available on WhatsApp Business API'); } diff --git a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts index 79167858..e95cee27 100644 --- a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts +++ b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts @@ -32,6 +32,7 @@ import { HandleLabelDto, LabelDto } from '@api/dto/label.dto'; import { ContactMessage, MediaMessage, + OfferCallDto, Options, SendAudioDto, SendContactDto, @@ -1670,6 +1671,25 @@ export class BaileysStartupService extends ChannelStartupService { } } + public async offerCall({ number, callDuration }: OfferCallDto) { + const jid = this.createJid(number); + + try { + const call = await this.client.offerCall(jid); + if (callDuration) { + setTimeout(async () => { + console.log('Terminating call'); + const aaa = await this.client.terminateCall(call.id, call.to); + console.log(aaa); + }, callDuration * 1000); + } + + return call; + } catch (error) { + return error; + } + } + private async sendMessage( sender: string, message: any, diff --git a/src/api/routes/sendMessage.router.ts b/src/api/routes/sendMessage.router.ts index 06f70ad7..249e3c04 100644 --- a/src/api/routes/sendMessage.router.ts +++ b/src/api/routes/sendMessage.router.ts @@ -1,5 +1,6 @@ import { RouterBroker } from '@api/abstract/abstract.router'; import { + OfferCallDto, SendAudioDto, SendButtonDto, SendContactDto, @@ -21,6 +22,7 @@ import { listMessageSchema, locationMessageSchema, mediaMessageSchema, + offerCallSchema, pollMessageSchema, reactionMessageSchema, statusMessageSchema, @@ -166,6 +168,16 @@ export class MessageRouter extends RouterBroker { execute: (instance, data) => sendMessageController.sendButtons(instance, data), }); + return res.status(HttpStatus.CREATED).json(response); + }) + .post(this.routerPath('offerCall'), ...guards, async (req, res) => { + const response = await this.dataValidate({ + request: req, + schema: offerCallSchema, + ClassRef: OfferCallDto, + execute: (instance, data) => sendMessageController.offerCall(instance, data), + }); + return res.status(HttpStatus.CREATED).json(response); }); } diff --git a/src/validate/message.schema.ts b/src/validate/message.schema.ts index 6ec1ab04..4e8651cc 100644 --- a/src/validate/message.schema.ts +++ b/src/validate/message.schema.ts @@ -54,6 +54,17 @@ const quotedOptionsSchema: JSONSchema7 = { }, }; +export const offerCallSchema: JSONSchema7 = { + $id: v4(), + type: 'object', + properties: { + number: { ...numberDefinition }, + isVideo: { type: 'boolean', enum: [true, false] }, + callDuration: { type: 'integer', minimum: 1, maximum: 15 }, + }, + required: ['number', 'callDuration'], +}; + export const textMessageSchema: JSONSchema7 = { $id: v4(), type: 'object',