Merge pull request #2382 from webmastersites/fix/interactive-devicesent

Fix/interactive devicesent
This commit is contained in:
Davidson Gomes
2026-02-24 12:15:25 -03:00
committed by GitHub
@@ -3595,30 +3595,34 @@ export class BaileysStartupService extends ChannelStartupService {
]); ]);
public async buttonMessage(data: SendButtonsDto) { 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'); throw new BadRequestException('At least one button is required');
} }
const hasReplyButtons = data.buttons.some((btn) => btn.type === 'reply'); const hasReplyButtons = data.buttons.some((btn) => btn.type === 'reply');
const hasPixButton = data.buttons.some((btn) => btn.type === 'pix'); 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 (hasReplyButtons) {
if (data.buttons.length > 3) { if (data.buttons.length > 3) {
throw new BadRequestException('Maximum of 3 reply buttons allowed'); throw new BadRequestException('Maximum of 3 reply buttons allowed');
} }
if (hasOtherButtons) { if (hasCTAButtons || hasPixButton) {
throw new BadRequestException('Reply buttons cannot be mixed with other button types'); throw new BadRequestException('Reply buttons cannot be mixed with CTA or PIX buttons');
} }
} }
// PIX
if (hasPixButton) { if (hasPixButton) {
if (data.buttons.length > 1) { if (data.buttons.length > 1) {
throw new BadRequestException('Only one PIX button is allowed'); 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'); throw new BadRequestException('PIX button cannot be mixed with other button types');
} }
@@ -3627,8 +3631,16 @@ export class BaileysStartupService extends ChannelStartupService {
message: { message: {
interactiveMessage: { interactiveMessage: {
nativeFlowMessage: { nativeFlowMessage: {
buttons: [{ name: this.mapType.get('pix'), buttonParamsJson: this.toJSONString(data.buttons[0]) }], buttons: [
messageParamsJson: JSON.stringify({ from: 'api', templateId: v4() }), {
name: this.mapType.get('pix'),
buttonParamsJson: this.toJSONString(data.buttons[0]),
},
],
messageParamsJson: JSON.stringify({
from: 'api',
templateId: v4(),
}),
}, },
}, },
}, },
@@ -3644,15 +3656,36 @@ export class BaileysStartupService extends ChannelStartupService {
}); });
} }
const generate = await (async () => { // CTA (url / call / copy)
if (data?.thumbnailUrl) { if (hasCTAButtons) {
return await this.prepareMediaMessage({ mediatype: 'image', media: data.thumbnailUrl }); 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 = { const message: proto.IMessage = {
viewOnceMessage: { viewOnceMessage: {
@@ -3660,27 +3693,26 @@ export class BaileysStartupService extends ChannelStartupService {
interactiveMessage: { interactiveMessage: {
body: { body: {
text: (() => { text: (() => {
let t = '*' + data.title + '*'; let text = `*${data.title}*`;
if (data?.description) { if (data?.description) {
t += '\n\n'; text += `\n\n${data.description}`;
t += data.description;
t += '\n';
} }
return t; return text;
})(), })(),
}, },
footer: { text: data?.footer }, footer: data?.footer ? { text: data.footer } : undefined,
header: (() => { header: generatedMedia?.message?.imageMessage
if (generate?.message?.imageMessage) { ? {
return { hasMediaAttachment: true,
hasMediaAttachment: !!generate.message.imageMessage, imageMessage: generatedMedia.message.imageMessage,
imageMessage: generate.message.imageMessage,
};
} }
})(), : undefined,
nativeFlowMessage: { nativeFlowMessage: {
buttons: buttons, buttons,
messageParamsJson: JSON.stringify({ from: 'api', templateId: v4() }), messageParamsJson: JSON.stringify({
from: 'api',
templateId: v4(),
}),
}, },
}, },
}, },