Skip to content

Commit d15c434

Browse files
author
root
committed
fix(baileys): interactive buttons via deviceSentMessage + CTA limits
1 parent cd800f2 commit d15c434

File tree

1 file changed

+81
-74
lines changed

1 file changed

+81
-74
lines changed

src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts

Lines changed: 81 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -3311,91 +3311,46 @@ export class BaileysStartupService extends ChannelStartupService {
33113311
]);
33123312

33133313
public async buttonMessage(data: SendButtonsDto) {
3314-
if (data.buttons.length === 0) {
3315-
throw new BadRequestException('At least one button is required');
3316-
}
3317-
3318-
const hasReplyButtons = data.buttons.some((btn) => btn.type === 'reply');
3319-
3320-
const hasPixButton = data.buttons.some((btn) => btn.type === 'pix');
3314+
if (data.buttons.length === 0) {
3315+
throw new BadRequestException('At least one button is required');
3316+
}
33213317

3322-
const hasOtherButtons = data.buttons.some((btn) => btn.type !== 'reply' && btn.type !== 'pix');
3318+
const hasReplyButtons = data.buttons.some((btn) => btn.type === 'reply');
3319+
const hasPixButton = data.buttons.some((btn) => btn.type === 'pix');
3320+
const hasOtherButtons = data.buttons.some((btn) => btn.type !== 'reply' && btn.type !== 'pix');
33233321

3324-
if (hasReplyButtons) {
3325-
if (data.buttons.length > 3) {
3326-
throw new BadRequestException('Maximum of 3 reply buttons allowed');
3327-
}
3328-
if (hasOtherButtons) {
3329-
throw new BadRequestException('Reply buttons cannot be mixed with other button types');
3330-
}
3322+
// Reply rules
3323+
if (hasReplyButtons) {
3324+
if (data.buttons.length > 3) {
3325+
throw new BadRequestException('Maximum of 3 reply buttons allowed');
33313326
}
3332-
3333-
if (hasPixButton) {
3334-
if (data.buttons.length > 1) {
3335-
throw new BadRequestException('Only one PIX button is allowed');
3336-
}
3337-
if (hasOtherButtons) {
3338-
throw new BadRequestException('PIX button cannot be mixed with other button types');
3339-
}
3340-
3341-
const message: proto.IMessage = {
3342-
viewOnceMessage: {
3343-
message: {
3344-
interactiveMessage: {
3345-
nativeFlowMessage: {
3346-
buttons: [{ name: this.mapType.get('pix'), buttonParamsJson: this.toJSONString(data.buttons[0]) }],
3347-
messageParamsJson: JSON.stringify({ from: 'api', templateId: v4() }),
3348-
},
3349-
},
3350-
},
3351-
},
3352-
};
3353-
3354-
return await this.sendMessageWithTyping(data.number, message, {
3355-
delay: data?.delay,
3356-
presence: 'composing',
3357-
quoted: data?.quoted,
3358-
mentionsEveryOne: data?.mentionsEveryOne,
3359-
mentioned: data?.mentioned,
3360-
});
3327+
if (hasOtherButtons) {
3328+
throw new BadRequestException('Reply buttons cannot be mixed with other button types');
33613329
}
3330+
}
33623331

3363-
const generate = await (async () => {
3364-
if (data?.thumbnailUrl) {
3365-
return await this.prepareMediaMessage({ mediatype: 'image', media: data.thumbnailUrl });
3366-
}
3367-
})();
3332+
// CTA rules (url/call/copy) - WhatsApp limits to 2 CTAs
3333+
if (hasOtherButtons && !hasReplyButtons && !hasPixButton) {
3334+
if (data.buttons.length > 2) {
3335+
throw new BadRequestException('Maximum of 2 CTA buttons allowed (url/call/copy)');
3336+
}
3337+
}
33683338

3369-
const buttons = data.buttons.map((value) => {
3370-
return { name: this.mapType.get(value.type), buttonParamsJson: this.toJSONString(value) };
3371-
});
3339+
// PIX rules
3340+
if (hasPixButton) {
3341+
if (data.buttons.length > 1) {
3342+
throw new BadRequestException('Only one PIX button is allowed');
3343+
}
3344+
if (hasOtherButtons) {
3345+
throw new BadRequestException('PIX button cannot be mixed with other button types');
3346+
}
33723347

33733348
const message: proto.IMessage = {
3374-
viewOnceMessage: {
3349+
deviceSentMessage: {
33753350
message: {
33763351
interactiveMessage: {
3377-
body: {
3378-
text: (() => {
3379-
let t = '*' + data.title + '*';
3380-
if (data?.description) {
3381-
t += '\n\n';
3382-
t += data.description;
3383-
t += '\n';
3384-
}
3385-
return t;
3386-
})(),
3387-
},
3388-
footer: { text: data?.footer },
3389-
header: (() => {
3390-
if (generate?.message?.imageMessage) {
3391-
return {
3392-
hasMediaAttachment: !!generate.message.imageMessage,
3393-
imageMessage: generate.message.imageMessage,
3394-
};
3395-
}
3396-
})(),
33973352
nativeFlowMessage: {
3398-
buttons: buttons,
3353+
buttons: [{ name: this.mapType.get('pix'), buttonParamsJson: this.toJSONString(data.buttons[0]) }],
33993354
messageParamsJson: JSON.stringify({ from: 'api', templateId: v4() }),
34003355
},
34013356
},
@@ -3412,6 +3367,58 @@ export class BaileysStartupService extends ChannelStartupService {
34123367
});
34133368
}
34143369

3370+
const generate = await (async () => {
3371+
if (data?.thumbnailUrl) {
3372+
return await this.prepareMediaMessage({ mediatype: 'image', media: data.thumbnailUrl });
3373+
}
3374+
})();
3375+
3376+
const buttons = data.buttons.map((value) => {
3377+
return { name: this.mapType.get(value.type), buttonParamsJson: this.toJSONString(value) };
3378+
});
3379+
3380+
const message: proto.IMessage = {
3381+
deviceSentMessage: {
3382+
message: {
3383+
interactiveMessage: {
3384+
body: {
3385+
text: (() => {
3386+
let t = '*' + data.title + '*';
3387+
if (data?.description) {
3388+
t += '\n\n';
3389+
t += data.description;
3390+
t += '\n';
3391+
}
3392+
return t;
3393+
})(),
3394+
},
3395+
footer: { text: data?.footer },
3396+
header: (() => {
3397+
if (generate?.message?.imageMessage) {
3398+
return {
3399+
hasMediaAttachment: !!generate.message.imageMessage,
3400+
imageMessage: generate.message.imageMessage,
3401+
};
3402+
}
3403+
})(),
3404+
nativeFlowMessage: {
3405+
buttons,
3406+
messageParamsJson: JSON.stringify({ from: 'api', templateId: v4() }),
3407+
},
3408+
},
3409+
},
3410+
},
3411+
};
3412+
3413+
return await this.sendMessageWithTyping(data.number, message, {
3414+
delay: data?.delay,
3415+
presence: 'composing',
3416+
quoted: data?.quoted,
3417+
mentionsEveryOne: data?.mentionsEveryOne,
3418+
mentioned: data?.mentioned,
3419+
});
3420+
}
3421+
34153422
public async locationMessage(data: SendLocationDto) {
34163423
return await this.sendMessageWithTyping(
34173424
data.number,

0 commit comments

Comments
 (0)