feat: send ptv message

This commit is contained in:
Davidson Gomes 2024-10-28 18:02:17 -03:00
parent 0fdc47e8f0
commit a4e7baa41c
6 changed files with 106 additions and 14 deletions

View File

@ -20,6 +20,7 @@
* Add indexes to improve performance in Evolution
* Add logical or permanent message deletion based on env config
* Add support for fetching multiple instances by key
* Update instance.controller.ts to filter by instanceName
# 2.1.2 (2024-10-06 10:09)

View File

@ -7,6 +7,7 @@ import {
SendLocationDto,
SendMediaDto,
SendPollDto,
SendPtvDto,
SendReactionDto,
SendStatusDto,
SendStickerDto,
@ -39,6 +40,13 @@ export class SendMessageController {
throw new BadRequestException('Owned media must be a url or base64');
}
public async sendPtv({ instanceName }: InstanceDto, data: SendPtvDto, file?: any) {
if (file || isURL(data?.video) || isBase64(data?.video)) {
return await this.waMonitor.waInstances[instanceName].ptvMessage(data, file);
}
throw new BadRequestException('Owned media must be a url or base64');
}
public async sendSticker({ instanceName }: InstanceDto, data: SendStickerDto, file?: any) {
if (file || isURL(data.sticker) || isBase64(data.sticker)) {
return await this.waMonitor.waInstances[instanceName].mediaSticker(data, file);

View File

@ -70,7 +70,7 @@ export class SendPollDto extends Metadata {
messageSecret?: Uint8Array;
}
export type MediaType = 'image' | 'document' | 'video' | 'audio';
export type MediaType = 'image' | 'document' | 'video' | 'audio' | 'ptv';
export class SendMediaDto extends Metadata {
mediatype: MediaType;
@ -82,6 +82,10 @@ export class SendMediaDto extends Metadata {
media: string;
}
export class SendPtvDto extends Metadata {
video: string;
}
export class SendStickerDto extends Metadata {
sticker: string;
}

View File

@ -42,6 +42,7 @@ import {
SendLocationDto,
SendMediaDto,
SendPollDto,
SendPtvDto,
SendReactionDto,
SendStatusDto,
SendStickerDto,
@ -309,7 +310,7 @@ export class BaileysStartupService extends ChannelStartupService {
qrcodeTerminal.generate(qr, { small: true }, (qrcode) =>
this.logger.log(
`\n{ instance: ${this.instance.name} pairingCode: ${this.instance.qrcode.pairingCode}, qrcodeCount: ${this.instance.qrcode.count} }\n` +
qrcode,
qrcode,
),
);
@ -913,18 +914,18 @@ export class BaileysStartupService extends ChannelStartupService {
const messagesRepository = new Set(
chatwootImport.getRepositoryMessagesCache(instance) ??
(
await this.prismaRepository.message.findMany({
select: { key: true },
where: { instanceId: this.instanceId },
})
).map((message) => {
const key = message.key as {
id: string;
};
(
await this.prismaRepository.message.findMany({
select: { key: true },
where: { instanceId: this.instanceId },
})
).map((message) => {
const key = message.key as {
id: string;
};
return key.id;
}),
return key.id;
}),
);
if (chatwootImport.getRepositoryMessagesCache(instance) === null) {
@ -2052,6 +2053,7 @@ export class BaileysStartupService extends ChannelStartupService {
messageSent?.message?.imageMessage ||
messageSent?.message?.videoMessage ||
messageSent?.message?.stickerMessage ||
messageSent?.message?.ptvMessage ||
messageSent?.message?.documentMessage ||
messageSent?.message?.documentWithCaptionMessage ||
messageSent?.message?.audioMessage;
@ -2397,9 +2399,11 @@ export class BaileysStartupService extends ChannelStartupService {
private async prepareMediaMessage(mediaMessage: MediaMessage) {
try {
const type = mediaMessage.mediatype === 'ptv' ? 'video' : mediaMessage.mediatype;
const prepareMedia = await prepareWAMessageMedia(
{
[mediaMessage.mediatype]: isURL(mediaMessage.media)
[type]: isURL(mediaMessage.media)
? { url: mediaMessage.media }
: Buffer.from(mediaMessage.media, 'base64'),
} as any,
@ -2453,6 +2457,10 @@ export class BaileysStartupService extends ChannelStartupService {
}
}
if (mediaMessage.mediatype === 'ptv') {
prepareMedia[mediaType] = prepareMedia[type + 'Message'];
}
prepareMedia[mediaType].caption = mediaMessage?.caption;
prepareMedia[mediaType].mimetype = mimetype;
prepareMedia[mediaType].fileName = mediaMessage.fileName;
@ -2564,6 +2572,37 @@ export class BaileysStartupService extends ChannelStartupService {
return mediaSent;
}
public async ptvMessage(data: SendPtvDto, file?: any, isIntegration = false) {
const mediaData: SendMediaDto = {
number: data.number,
media: data.video,
mediatype: 'ptv',
delay: data?.delay,
quoted: data?.quoted,
mentionsEveryOne: data?.mentionsEveryOne,
mentioned: data?.mentioned,
};
if (file) mediaData.media = file.buffer.toString('base64');
const generate = await this.prepareMediaMessage(mediaData);
const mediaSent = await this.sendMessageWithTyping(
data.number,
{ ...generate.message },
{
delay: data?.delay,
presence: 'composing',
quoted: data?.quoted,
mentionsEveryOne: data?.mentionsEveryOne,
mentioned: data?.mentioned,
},
isIntegration,
);
return mediaSent;
}
public async processAudioMp4(audio: string) {
let inputStream: PassThrough;

View File

@ -7,6 +7,7 @@ import {
SendLocationDto,
SendMediaDto,
SendPollDto,
SendPtvDto,
SendReactionDto,
SendStatusDto,
SendStickerDto,
@ -22,6 +23,7 @@ import {
locationMessageSchema,
mediaMessageSchema,
pollMessageSchema,
ptvMessageSchema,
reactionMessageSchema,
statusMessageSchema,
stickerMessageSchema,
@ -71,6 +73,18 @@ export class MessageRouter extends RouterBroker {
return res.status(HttpStatus.CREATED).json(response);
})
.post(this.routerPath('sendPtv'), ...guards, upload.single('file'), async (req, res) => {
const bodyData = req.body;
const response = await this.dataValidate<SendPtvDto>({
request: req,
schema: ptvMessageSchema,
ClassRef: SendPtvDto,
execute: (instance) => sendMessageController.sendPtv(instance, bodyData, req.file as any),
});
return res.status(HttpStatus.CREATED).json(response);
})
.post(this.routerPath('sendWhatsAppAudio'), ...guards, upload.single('file'), async (req, res) => {
const bodyData = req.body;

View File

@ -122,6 +122,32 @@ export const mediaMessageSchema: JSONSchema7 = {
required: ['number', 'mediatype'],
};
export const ptvMessageSchema: JSONSchema7 = {
$id: v4(),
type: 'object',
properties: {
number: { ...numberDefinition },
video: { type: 'string' },
delay: {
type: 'integer',
description: 'Enter a value in milliseconds',
},
quoted: { ...quotedOptionsSchema },
everyOne: { type: 'boolean', enum: [true, false] },
mentioned: {
type: 'array',
minItems: 1,
uniqueItems: true,
items: {
type: 'string',
pattern: '^\\d+',
description: '"mentioned" must be an array of numeric strings',
},
},
},
required: ['number'],
};
export const audioMessageSchema: JSONSchema7 = {
$id: v4(),
type: 'object',