Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 63 additions & 31 deletions src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3311,30 +3311,34 @@ export class BaileysStartupService extends ChannelStartupService {
]);

public async buttonMessage(data: SendButtonsDto) {
if (data.buttons.length === 0) {
if (!data.buttons || data.buttons.length === 0) {
throw new BadRequestException('At least one button is required');
}

const hasReplyButtons = data.buttons.some((btn) => btn.type === 'reply');

const hasPixButton = data.buttons.some((btn) => btn.type === 'pix');
const hasCTAButtons = data.buttons.some((btn) => btn.type === 'url' || btn.type === 'call' || btn.type === 'copy');

const hasOtherButtons = data.buttons.some((btn) => btn.type !== 'reply' && btn.type !== 'pix');
/* =========================
* REGRAS DE VALIDAÇÃO
* ========================= */

// Reply
if (hasReplyButtons) {
if (data.buttons.length > 3) {
throw new BadRequestException('Maximum of 3 reply buttons allowed');
}
if (hasOtherButtons) {
throw new BadRequestException('Reply buttons cannot be mixed with other button types');
if (hasCTAButtons || hasPixButton) {
throw new BadRequestException('Reply buttons cannot be mixed with CTA or PIX buttons');
}
}

// PIX
if (hasPixButton) {
if (data.buttons.length > 1) {
throw new BadRequestException('Only one PIX button is allowed');
}
if (hasOtherButtons) {
if (hasReplyButtons || hasCTAButtons) {
throw new BadRequestException('PIX button cannot be mixed with other button types');
}

Expand All @@ -3343,8 +3347,16 @@ export class BaileysStartupService extends ChannelStartupService {
message: {
interactiveMessage: {
nativeFlowMessage: {
buttons: [{ name: this.mapType.get('pix'), buttonParamsJson: this.toJSONString(data.buttons[0]) }],
messageParamsJson: JSON.stringify({ from: 'api', templateId: v4() }),
buttons: [
{
name: this.mapType.get('pix'),
buttonParamsJson: this.toJSONString(data.buttons[0]),
},
],
messageParamsJson: JSON.stringify({
from: 'api',
templateId: v4(),
}),
},
},
},
Expand All @@ -3360,43 +3372,63 @@ export class BaileysStartupService extends ChannelStartupService {
});
}

const generate = await (async () => {
if (data?.thumbnailUrl) {
return await this.prepareMediaMessage({ mediatype: 'image', media: data.thumbnailUrl });
// CTA (url / call / copy)
if (hasCTAButtons) {
if (data.buttons.length > 2) {
throw new BadRequestException('Maximum of 2 CTA buttons allowed');
}
if (hasReplyButtons) {
throw new BadRequestException('CTA buttons cannot be mixed with reply buttons');
}
})();
}

const buttons = data.buttons.map((value) => {
return { name: this.mapType.get(value.type), buttonParamsJson: this.toJSONString(value) };
});
/* =========================
* HEADER (opcional)
* ========================= */

const generatedMedia = data?.thumbnailUrl
? await this.prepareMediaMessage({ mediatype: 'image', media: data.thumbnailUrl })
: null;

/* =========================
* BOTΓ•ES
* ========================= */

const buttons = data.buttons.map((btn) => ({
name: this.mapType.get(btn.type),
buttonParamsJson: this.toJSONString(btn),
}));

/* =========================
* MENSAGEM FINAL
* ========================= */

const message: proto.IMessage = {
viewOnceMessage: {
message: {
interactiveMessage: {
body: {
text: (() => {
let t = '*' + data.title + '*';
let text = `*${data.title}*`;
if (data?.description) {
t += '\n\n';
t += data.description;
t += '\n';
text += `\n\n${data.description}`;
}
return t;
return text;
})(),
},
footer: { text: data?.footer },
header: (() => {
if (generate?.message?.imageMessage) {
return {
hasMediaAttachment: !!generate.message.imageMessage,
imageMessage: generate.message.imageMessage,
};
}
})(),
footer: data?.footer ? { text: data.footer } : undefined,
header: generatedMedia?.message?.imageMessage
? {
hasMediaAttachment: true,
imageMessage: generatedMedia.message.imageMessage,
}
: undefined,
nativeFlowMessage: {
buttons: buttons,
messageParamsJson: JSON.stringify({ from: 'api', templateId: v4() }),
buttons,
messageParamsJson: JSON.stringify({
from: 'api',
templateId: v4(),
}),
},
},
},
Expand Down