Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -1666,6 +1666,10 @@ export class ChatwootService {
return result;
}

private isInteractiveButtonMessage(messageType: string, message: any) {
return messageType === 'interactiveMessage' && message.interactiveMessage?.nativeFlowMessage?.buttons?.length > 0;
}

private getAdsMessage(msg: any) {
interface AdsMessage {
title: string;
Expand Down Expand Up @@ -1984,8 +1988,9 @@ export class ChatwootService {
const adsMessage = this.getAdsMessage(body);

const reactionMessage = this.getReactionMessage(body.message);
const isInteractiveButtonMessage = this.isInteractiveButtonMessage(body.messageType, body.message);

if (!bodyMessage && !isMedia && !reactionMessage) {
if (!bodyMessage && !isMedia && !reactionMessage && !isInteractiveButtonMessage) {
this.logger.warn('no body message found');
return;
}
Expand Down Expand Up @@ -2118,6 +2123,50 @@ export class ChatwootService {
return;
}

if (isInteractiveButtonMessage) {
const buttons = body.message.interactiveMessage.nativeFlowMessage.buttons;
this.logger.info('is Interactive Button Message: ' + JSON.stringify(buttons));

for (const button of buttons) {
const buttonParams = JSON.parse(button.buttonParamsJson);
const paymentSettings = buttonParams.payment_settings;

if (button.name === 'payment_info' && paymentSettings[0].type === 'pix_static_code') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Accessing paymentSettings[0] assumes paymentSettings is a non-empty array.

Add a check to ensure paymentSettings exists and is not empty before accessing paymentSettings[0].

const pixSettings = paymentSettings[0].pix_static_code;
const pixKeyType = (() => {
switch (pixSettings.key_type) {
case 'EVP':
return 'Chave AleatΓ³ria';
case 'EMAIL':
return 'E-mail';
case 'PHONE':
return 'Telefone';
default:
return pixSettings.key_type;
}
})();
const pixKey = pixSettings.key_type === 'PHONE' ? pixSettings.key.replace('+55', '') : pixSettings.key;
const content = `*${pixSettings.merchant_name}*\nChave PIX: ${pixKey} (${pixKeyType})`;
Comment on lines +2148 to +2149
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Replacing '+55' may not handle all phone formats.

This approach may fail if the phone key does not start with '+55'. Please ensure the phone format is validated or normalized before performing the replacement.

Suggested change
const pixKey = pixSettings.key_type === 'PHONE' ? pixSettings.key.replace('+55', '') : pixSettings.key;
const content = `*${pixSettings.merchant_name}*\nChave PIX: ${pixKey} (${pixKeyType})`;
const normalizePhoneKey = (key: string) => {
// Remove all non-digit characters
const digits = key.replace(/\D/g, '');
// If it starts with 55 and has 13 digits, remove the country code
if (digits.length === 13 && digits.startsWith('55')) {
return digits.slice(2);
}
// If it already has 11 digits (standard BR phone), return as is
if (digits.length === 11) {
return digits;
}
// Otherwise, return the original key for manual review
return key;
};
const pixKey = pixSettings.key_type === 'PHONE' ? normalizePhoneKey(pixSettings.key) : pixSettings.key;
const content = `*${pixSettings.merchant_name}*\nChave PIX: ${pixKey} (${pixKeyType})`;


const send = await this.createMessage(
instance,
getConversation,
content,
messageType,
false,
[],
body,
'WAID:' + body.key.id,
quotedMsg,
);
if (!send) this.logger.warn('message not sent');
Comment on lines +2151 to +2162
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): The return value of createMessage is checked only for falsy values.

If createMessage throws an error, it will bypass the warning. Wrap the call in try/catch to ensure errors are properly handled.

Suggested change
const send = await this.createMessage(
instance,
getConversation,
content,
messageType,
false,
[],
body,
'WAID:' + body.key.id,
quotedMsg,
);
if (!send) this.logger.warn('message not sent');
let send;
try {
send = await this.createMessage(
instance,
getConversation,
content,
messageType,
false,
[],
body,
'WAID:' + body.key.id,
quotedMsg,
);
if (!send) this.logger.warn('message not sent');
} catch (error) {
this.logger.warn('message not sent due to error', error);
}

} else {
this.logger.warn('Interactive Button Message not mapped');
}
}
return;
}

const isAdsMessage = (adsMessage && adsMessage.title) || adsMessage.body || adsMessage.thumbnailUrl;
if (isAdsMessage) {
const imgBuffer = await axios.get(adsMessage.thumbnailUrl, { responseType: 'arraybuffer' });
Expand Down
Loading