Skip to content

Commit

Permalink
feat: typebot send list
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidsonGomes committed Oct 29, 2024
1 parent 52216ec commit c55312d
Showing 1 changed file with 170 additions and 10 deletions.
180 changes: 170 additions & 10 deletions src/api/integrations/chatbot/typebot/services/typebot.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,51 @@ export class TypebotService {

formattedText = formattedText.replace(/\n$/, '');

if (formattedText.includes('[buttons]')) {
if (formattedText.includes('[list]')) {
const listJson = {
number: remoteJid.split('@')[0],
title: '',
description: '',
buttonText: '',
footerText: '',
sections: [],
};

const titleMatch = formattedText.match(/\[title\]([\s\S]*?)(?=\[description\])/);
const descriptionMatch = formattedText.match(/\[description\]([\s\S]*?)(?=\[buttonText\])/);
const buttonTextMatch = formattedText.match(/\[buttonText\]([\s\S]*?)(?=\[footerText\])/);
const footerTextMatch = formattedText.match(/\[footerText\]([\s\S]*?)(?=\[menu\])/);

if (titleMatch) listJson.title = titleMatch[1].trim();
if (descriptionMatch) listJson.description = descriptionMatch[1].trim();
if (buttonTextMatch) listJson.buttonText = buttonTextMatch[1].trim();
if (footerTextMatch) listJson.footerText = footerTextMatch[1].trim();

const menuContent = formattedText.match(/\[menu\]([\s\S]*?)\[\/menu\]/)?.[1];
if (menuContent) {
const sections = menuContent.match(/\[section\]([\s\S]*?)(?=\[section\]|\[\/section\])/g);
if (sections) {
sections.forEach((section) => {
const sectionTitle = section.match(/title: (.*?)(?:\n|$)/)?.[1]?.trim();
const rows = section.match(/\[row\]([\s\S]*?)(?=\[row\]|\[\/section\]|\[\/menu\])/g);

const sectionData = {
title: sectionTitle,
rows:
rows?.map((row) => ({
title: row.match(/title: (.*?)(?:\n|$)/)?.[1]?.trim(),
description: row.match(/description: (.*?)(?:\n|$)/)?.[1]?.trim(),
rowId: row.match(/rowId: (.*?)(?:\n|$)/)?.[1]?.trim(),
})) || [],
};

listJson.sections.push(sectionData);
});
}
}

await instance.listMessage(listJson);
} else if (formattedText.includes('[buttons]')) {
const buttonJson = {
number: remoteJid.split('@')[0],
thumbnailUrl: undefined,
Expand Down Expand Up @@ -302,9 +346,9 @@ export class TypebotService {
},
false,
);

sendTelemetry('/message/sendText');
}

sendTelemetry('/message/sendText');
}

if (message.type === 'image') {
Expand Down Expand Up @@ -371,14 +415,130 @@ export class TypebotService {

formattedText = formattedText.replace(/\n$/, '');

await instance.textMessage(
{
if (formattedText.includes('[list]')) {
const listJson = {
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
text: formattedText,
},
false,
);
title: '',
description: '',
buttonText: '',
footerText: '',
sections: [],
};

const titleMatch = formattedText.match(/\[title\]([\s\S]*?)(?=\[description\])/);
const descriptionMatch = formattedText.match(/\[description\]([\s\S]*?)(?=\[buttonText\])/);
const buttonTextMatch = formattedText.match(/\[buttonText\]([\s\S]*?)(?=\[footerText\])/);
const footerTextMatch = formattedText.match(/\[footerText\]([\s\S]*?)(?=\[menu\])/);

if (titleMatch) listJson.title = titleMatch[1].trim();
if (descriptionMatch) listJson.description = descriptionMatch[1].trim();
if (buttonTextMatch) listJson.buttonText = buttonTextMatch[1].trim();
if (footerTextMatch) listJson.footerText = footerTextMatch[1].trim();

const menuContent = formattedText.match(/\[menu\]([\s\S]*?)\[\/menu\]/)?.[1];
if (menuContent) {
const sections = menuContent.match(/\[section\]([\s\S]*?)(?=\[section\]|\[\/section\])/g);
if (sections) {
sections.forEach((section) => {
const sectionTitle = section.match(/title: (.*?)(?:\n|$)/)?.[1]?.trim();
const rows = section.match(/\[row\]([\s\S]*?)(?=\[row\]|\[\/section\]|\[\/menu\])/g);

const sectionData = {
title: sectionTitle,
rows:
rows?.map((row) => ({
title: row.match(/title: (.*?)(?:\n|$)/)?.[1]?.trim(),
description: row.match(/description: (.*?)(?:\n|$)/)?.[1]?.trim(),
rowId: row.match(/rowId: (.*?)(?:\n|$)/)?.[1]?.trim(),
})) || [],
};

listJson.sections.push(sectionData);
});
}
}

await instance.listMessage(listJson);
} else if (formattedText.includes('[buttons]')) {
const buttonJson = {
number: remoteJid.split('@')[0],
thumbnailUrl: undefined,
title: '',
description: '',
footer: '',
buttons: [],
};

const thumbnailUrlMatch = formattedText.match(/\[thumbnailUrl\]([\s\S]*?)(?=\[title\])/);
const titleMatch = formattedText.match(/\[title\]([\s\S]*?)(?=\[description\])/);
const descriptionMatch = formattedText.match(/\[description\]([\s\S]*?)(?=\[footer\])/);
const footerMatch = formattedText.match(/\[footer\]([\s\S]*?)(?=\[(?:reply|pix|copy|call|url))/);

if (titleMatch) buttonJson.title = titleMatch[1].trim();
if (thumbnailUrlMatch) buttonJson.thumbnailUrl = thumbnailUrlMatch[1].trim();
if (descriptionMatch) buttonJson.description = descriptionMatch[1].trim();
if (footerMatch) buttonJson.footer = footerMatch[1].trim();

const buttonTypes = {
reply: /\[reply\]([\s\S]*?)(?=\[(?:reply|pix|copy|call|url)|$)/g,
pix: /\[pix\]([\s\S]*?)(?=\[(?:reply|pix|copy|call|url)|$)/g,
copy: /\[copy\]([\s\S]*?)(?=\[(?:reply|pix|copy|call|url)|$)/g,
call: /\[call\]([\s\S]*?)(?=\[(?:reply|pix|copy|call|url)|$)/g,
url: /\[url\]([\s\S]*?)(?=\[(?:reply|pix|copy|call|url)|$)/g,
};

for (const [type, pattern] of Object.entries(buttonTypes)) {
let match;
while ((match = pattern.exec(formattedText)) !== null) {
const content = match[1].trim();
const button: any = { type };

switch (type) {
case 'pix':
button.currency = content.match(/currency: (.*?)(?:\n|$)/)?.[1]?.trim();
button.name = content.match(/name: (.*?)(?:\n|$)/)?.[1]?.trim();
button.keyType = content.match(/keyType: (.*?)(?:\n|$)/)?.[1]?.trim();
button.key = content.match(/key: (.*?)(?:\n|$)/)?.[1]?.trim();
break;

case 'reply':
button.displayText = content.match(/displayText: (.*?)(?:\n|$)/)?.[1]?.trim();
button.id = content.match(/id: (.*?)(?:\n|$)/)?.[1]?.trim();
break;

case 'copy':
button.displayText = content.match(/displayText: (.*?)(?:\n|$)/)?.[1]?.trim();
button.copyCode = content.match(/copyCode: (.*?)(?:\n|$)/)?.[1]?.trim();
break;

case 'call':
button.displayText = content.match(/displayText: (.*?)(?:\n|$)/)?.[1]?.trim();
button.phoneNumber = content.match(/phone: (.*?)(?:\n|$)/)?.[1]?.trim();
break;

case 'url':
button.displayText = content.match(/displayText: (.*?)(?:\n|$)/)?.[1]?.trim();
button.url = content.match(/url: (.*?)(?:\n|$)/)?.[1]?.trim();
break;
}

if (Object.keys(button).length > 1) {
buttonJson.buttons.push(button);
}
}
}

await instance.buttonMessage(buttonJson);
} else {
await instance.textMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
text: formattedText,
},
false,
);
}

sendTelemetry('/message/sendText');
}
Expand Down

0 comments on commit c55312d

Please sign in to comment.