[core] ChatWoot - Facebook Ads Message Template

closes #1461

(cherry picked from bergpinheiro/waha@5863590208)

Thanks @bergpinheiro
Co-authored-by: bergpinheiro <berg.pinheiro2009@gmail.com>
This commit is contained in:
devlikepro committed 2025-10-12 18:45:48 +07:00
1 parent b420548dd9
commit bbe3859085
21 files changed
+369

No files matched your search

@@ -18,6 +18,7 @@ import { WAHAWebhookMessageAny } from '@waha/structures/webhooks.dto';
import { Job } from 'bullmq';
import { PinoLogger } from 'nestjs-pino';
import {
FacebookAdMessage,
LocationMessage,
MessageToChatWootConverter,
ShareContactMessage,
@@ -69,6 +70,13 @@ class MessageAnyHandler extends MessageBaseHandler<WAMessage> {
let msg: ChatWootMessagePartial;
const protoMessage = resolveProtoMessage(payload);
// Check for Facebook Ad first - but let it use the normal flow later
converter = new FacebookAdMessage(this.l, this.logger);
msg = await converter.convert(payload, protoMessage);
if (msg) {
return msg;
}
converter = new TextMessage(this.l, this.logger, this.waha);
msg = await converter.convert(payload, null);
if (msg) {
+15
View File
@@ -236,3 +236,18 @@ whatsapp.to.chatwoot.message.unsupported: |-
📱 يرجى فتح **WhatsApp** لعرضه.
التفاصيل: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **إعلان فيسبوك**
**العنوان:** {{{adData.title}}}
**الوصف:**
{{{adData.body}}}
**رابط الإعلان:** [عرض على فيسبوك]({{{adData.sourceUrl}}})
**معرّف الإعلان:** {{{adData.sourceId}}}
---
💬 **رسالة العميل:**
{{{payload.body}}}
+15
View File
@@ -236,3 +236,18 @@ whatsapp.to.chatwoot.message.unsupported: |-
📱 এটি দেখতে অনুগ্রহ করে **WhatsApp** খুলুন।
বিস্তারিত: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **ফেসবুক বিজ্ঞাপন**
**শিরোনাম:** {{{adData.title}}}
**বর্ণনা:**
{{{adData.body}}}
**বিজ্ঞাপনের লিংক:** [ফেসবুকে দেখুন]({{{adData.sourceUrl}}})
**বিজ্ঞাপনের আইডি:** {{{adData.sourceId}}}
---
💬 **গ্রাহকের বার্তা:**
{{{payload.body}}}
+15
View File
@@ -239,3 +239,18 @@ whatsapp.to.chatwoot.message.unsupported: |-
📱 Bitte öffne **WhatsApp**, um ihn anzusehen.
Details: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **FACEBOOK-ANZEIGE**
**Titel:** {{{adData.title}}}
**Beschreibung:**
{{{adData.body}}}
**Anzeigenlink:** [Auf Facebook ansehen]({{{adData.sourceUrl}}})
**Anzeigen-ID:** {{{adData.sourceId}}}
---
💬 **Kundennachricht:**
{{{payload.body}}}
+15
View File
@@ -116,6 +116,21 @@ whatsapp.to.chatwoot.message.unsupported: |-
Details: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **FACEBOOK AD**
**Title:** {{{adData.title}}}
**Description:**
{{{adData.body}}}
**Ad Link:** [View on Facebook]({{{adData.sourceUrl}}})
**Ad ID:** {{{adData.sourceId}}}
---
💬 **CUSTOMER MESSAGE:**
{{{payload.body}}}
app.connected.message: |-
🔗 **CONNECTED: WhatsApp Session to ChatWoot Inbox**
+15
View File
@@ -239,3 +239,18 @@ whatsapp.to.chatwoot.message.unsupported: |-
📱 Por favor, abre **WhatsApp** para verlo.
Detalles: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **ANUNCIO DE FACEBOOK**
**Título:** {{{adData.title}}}
**Descripción:**
{{{adData.body}}}
**Enlace del anuncio:** [Ver en Facebook]({{{adData.sourceUrl}}})
**ID del anuncio:** {{{adData.sourceId}}}
---
💬 **Mensaje del cliente:**
{{{payload.body}}}
+15
View File
@@ -236,3 +236,18 @@ whatsapp.to.chatwoot.message.unsupported: |-
📱 لطفاً برای مشاهده آن **WhatsApp** را باز کنید.
جزئیات: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **آگهی فیس‌بوک**
**عنوان:** {{{adData.title}}}
**توضیحات:**
{{{adData.body}}}
**لینک آگهی:** [مشاهده در فیس‌بوک]({{{adData.sourceUrl}}})
**شناسه آگهی:** {{{adData.sourceId}}}
---
💬 **پیام مشتری:**
{{{payload.body}}}
+15
View File
@@ -236,3 +236,18 @@ whatsapp.to.chatwoot.message.unsupported: |-
📱 Veuillez ouvrir **WhatsApp** pour l’afficher.
Détails: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **PUBLICITÉ FACEBOOK**
**Titre:** {{{adData.title}}}
**Description:**
{{{adData.body}}}
**Lien de l'annonce :** [Voir sur Facebook]({{{adData.sourceUrl}}})
**ID de l'annonce :** {{{adData.sourceId}}}
---
💬 **Message du client :**
{{{payload.body}}}
+15
View File
@@ -236,3 +236,18 @@ whatsapp.to.chatwoot.message.unsupported: |-
📱 אנא פתח/י את **WhatsApp** כדי לצפות בזה.
פרטים: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **מודעת פייסבוק**
**כותרת:** {{{adData.title}}}
**תיאור:**
{{{adData.body}}}
**קישור למודעה:** [לצפייה בפייסבוק]({{{adData.sourceUrl}}})
**מזהה המודעה:** {{{adData.sourceId}}}
---
💬 **הודעת הלקוח:**
{{{payload.body}}}
+15
View File
@@ -236,3 +236,18 @@ whatsapp.to.chatwoot.message.unsupported: |-
📱 इसे देखने के लिए कृपया **WhatsApp** खोलें।
विवरण: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **फेसबुक विज्ञापन**
**शीर्षक:** {{{adData.title}}}
**विवरण:**
{{{adData.body}}}
**विज्ञापन लिंक:** [फेसबुक पर देखें]({{{adData.sourceUrl}}})
**विज्ञापन आईडी:** {{{adData.sourceId}}}
---
💬 **ग्राहक संदेश:**
{{{payload.body}}}
+15
View File
@@ -236,3 +236,18 @@ whatsapp.to.chatwoot.message.unsupported: |-
📱 Silakan buka **WhatsApp** untuk melihatnya.
Detail: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **IKLAN FACEBOOK**
**Judul:** {{{adData.title}}}
**Deskripsi:**
{{{adData.body}}}
**Tautan Iklan:** [Lihat di Facebook]({{{adData.sourceUrl}}})
**ID Iklan:** {{{adData.sourceId}}}
---
💬 **Pesan Pelanggan:**
{{{payload.body}}}
+15
View File
@@ -236,3 +236,18 @@ whatsapp.to.chatwoot.message.unsupported: |-
📱 ਇਸਨੂੰ ਦੇਖਣ ਲਈ ਕਿਰਪਾ ਕਰਕੇ **WhatsApp** ਖੋਲ੍ਹੋ।
ਵੇਰਵੇ: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **ਫੇਸਬੁੱਕ ਵਿਗਿਆਪਨ**
**ਸਿਰਲੇਖ:** {{{adData.title}}}
**ਵੇਰਵਾ:**
{{{adData.body}}}
**ਵਿਗਿਆਪਨ ਲਿੰਕ:** [ਫੇਸਬੁੱਕ 'ਤੇ ਵੇਖੋ]({{{adData.sourceUrl}}})
**ਵਿਗਿਆਪਨ ਆਈਡੀ:** {{{adData.sourceId}}}
---
💬 **ਗਾਹਕ ਦਾ ਸੁਨੇਹਾ:**
{{{payload.body}}}
+15
View File
@@ -239,3 +239,18 @@ whatsapp.to.chatwoot.message.unsupported: |-
📱 Por favor, abra o **WhatsApp** para visualizá-la.
Detalhes: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **ANÚNCIO DO FACEBOOK**
**Título:** {{{adData.title}}}
**Descrição:**
{{{adData.body}}}
**Link do Anúncio:** [Ver no Facebook]({{{adData.sourceUrl}}})
**ID do Anúncio:** {{{adData.sourceId}}}
---
💬 **MENSAGEM DO CLIENTE:**
{{{payload.body}}}
+15
View File
@@ -236,3 +236,18 @@ whatsapp.to.chatwoot.message.unsupported: |-
📱 Пожалуйста, откройте **WhatsApp**, чтобы просмотреть.
Подробности: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **РЕКЛАМА FACEBOOK**
**Заголовок:** {{{adData.title}}}
**Описание:**
{{{adData.body}}}
**Ссылка на объявление:** [Посмотреть в Facebook]({{{adData.sourceUrl}}})
**Идентификатор объявления:** {{{adData.sourceId}}}
---
💬 **Сообщение клиента:**
{{{payload.body}}}
+15
View File
@@ -236,3 +236,18 @@ whatsapp.to.chatwoot.message.unsupported: |-
📱 Görüntülemek için lütfen **WhatsApp’ı** açın.
Ayrıntılar: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **FACEBOOK İLANI**
**Başlık:** {{{adData.title}}}
**Açıklama:**
{{{adData.body}}}
**İlan Bağlantısı:** [Facebook’ta Görüntüle]({{{adData.sourceUrl}}})
**İlan Kimliği:** {{{adData.sourceId}}}
---
💬 **Müşteri Mesajı:**
{{{payload.body}}}
+15
View File
@@ -236,3 +236,18 @@ whatsapp.to.chatwoot.message.unsupported: |-
📱 Будь ласка, відкрийте **WhatsApp**, щоб переглянути.
Подробиці: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **РЕКЛАМА FACEBOOK**
**Заголовок:** {{{adData.title}}}
**Опис:**
{{{adData.body}}}
**Посилання на рекламу:** [Переглянути у Facebook]({{{adData.sourceUrl}}})
**Ідентифікатор реклами:** {{{adData.sourceId}}}
---
💬 **Повідомлення клієнта:**
{{{payload.body}}}
+15
View File
@@ -236,3 +236,18 @@ whatsapp.to.chatwoot.message.unsupported: |-
📱 اسے دیکھنے کے لیے براہ کرم **WhatsApp** کھولیں۔
تفصیلات: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **فیس بک اشتہار**
**عنوان:** {{{adData.title}}}
**تفصیل:**
{{{adData.body}}}
**اشتہار کا لنک:** [فیس بک پر دیکھیں]({{{adData.sourceUrl}}})
**اشتہار کا شناختی نمبر:** {{{adData.sourceId}}}
---
💬 **گاہک کا پیغام:**
{{{payload.body}}}
+15
View File
@@ -238,3 +238,18 @@ whatsapp.to.chatwoot.message.unsupported: |-
📱 请打开 **WhatsApp** 查看。
详情: [{{{details.text}}}]({{{details.url}}})
whatsapp.to.chatwoot.message.facebook.ad: |-
📢 **Facebook 广告**
**标题:** {{{adData.title}}}
**描述:**
{{{adData.body}}}
**广告链接:** [在 Facebook 查看]({{{adData.sourceUrl}}})
**广告 ID:** {{{adData.sourceId}}}
---
💬 **客户消息:**
{{{payload.body}}}
+14
View File
@@ -52,6 +52,7 @@ export enum TKey {
WA_TO_CW_MESSAGE_CONTACTS = 'whatsapp.to.chatwoot.message.contacts',
WA_TO_CW_MESSAGE_LOCATION = 'whatsapp.to.chatwoot.message.location',
WA_TO_CW_MESSAGE_UNSUPPORTED = 'whatsapp.to.chatwoot.message.unsupported',
WA_TO_CW_MESSAGE_FACEBOOK_AD = 'whatsapp.to.chatwoot.message.facebook.ad',
//
// App Inbox
@@ -99,6 +100,15 @@ interface Link {
url: string;
}
export interface FacebookAdTemplateData {
title: string;
body: string;
thumbnailUrl: string;
originalImageUrl: string;
sourceUrl: string;
sourceId: string;
}
export type TemplatePayloads = {
[TKey.LOCALE_NAME]: void;
[TKey.APP_INBOX_CONTACT_NAME]: void;
@@ -132,6 +142,10 @@ export type TemplatePayloads = {
[TKey.WA_TO_CW_MESSAGE_CONTACTS]: { contacts: SimpleVCardInfo[] };
[TKey.WA_TO_CW_MESSAGE_LOCATION]: { payload: any; message: proto.Message };
[TKey.WA_TO_CW_MESSAGE_UNSUPPORTED]: { details: Link };
[TKey.WA_TO_CW_MESSAGE_FACEBOOK_AD]: {
payload: WAMessage;
adData: FacebookAdTemplateData;
};
[TKey.JOB_SCHEDULED_ERROR_HEADER]: void;
[TKey.JOB_REPORT_ERROR]: {
header: string;
@@ -0,0 +1,91 @@
import { ILogger } from '@waha/apps/app_sdk/ILogger';
import { SendAttachment } from '@waha/apps/chatwoot/client/types';
import { ChatWootMessagePartial } from '@waha/apps/chatwoot/consumers/waha/base';
import { Locale } from '@waha/apps/chatwoot/i18n/locale';
import {
FacebookAdTemplateData,
TKey,
} from '@waha/apps/chatwoot/i18n/templates';
import { MessageToChatWootConverter } from '@waha/apps/chatwoot/messages/to/chatwoot';
import { WhatsappToMarkdown } from '@waha/apps/chatwoot/messages/to/chatwoot/utils/markdown';
import { WAMessage } from '@waha/structures/responses.dto';
import type { proto } from '@adiwajshing/baileys';
import * as lodash from 'lodash';
import { fetchBuffer } from '@waha/core/abc/session.abc';
export class FacebookAdMessage implements MessageToChatWootConverter {
constructor(
private readonly locale: Locale,
private readonly logger: ILogger,
) {}
async convert(
payload: WAMessage,
protoMessage: proto.Message | null,
): Promise<ChatWootMessagePartial | null> {
const adData = this.extractAdData(protoMessage);
if (!adData) {
return null;
}
const content = this.locale.key(TKey.WA_TO_CW_MESSAGE_FACEBOOK_AD).render({
payload,
adData,
});
const attachments = await this.getAttachments(adData);
return {
content: WhatsappToMarkdown(content),
attachments,
private: undefined,
};
}
private extractAdData(protoMessage: proto.Message): FacebookAdTemplateData {
if (
lodash.isEmpty(
protoMessage?.extendedTextMessage?.contextInfo?.externalAdReply,
)
) {
return null;
}
const adReply =
protoMessage?.extendedTextMessage?.contextInfo?.externalAdReply;
return {
title: adReply.title ?? '',
body: adReply.body ?? '',
thumbnailUrl: adReply.thumbnailUrl ?? '',
originalImageUrl: adReply.originalImageUrl ?? '',
sourceUrl: adReply.sourceUrl ?? '',
sourceId: adReply.sourceId ?? '',
};
}
private async getAttachments(
adData: FacebookAdTemplateData,
): Promise<SendAttachment[]> {
const imageUrl = adData.originalImageUrl || adData.thumbnailUrl;
if (!imageUrl) {
return [];
}
try {
this.logger.info(`Downloading Facebook Ad image from '${imageUrl}'...`);
const buffer = await fetchBuffer(imageUrl);
const attachment: SendAttachment = {
content: buffer.toString('base64'),
filename: 'facebook-ad-image.jpg',
encoding: 'base64',
};
this.logger.info(
`Downloaded Facebook Ad image from '${imageUrl}' as '${attachment.filename}'`,
);
return [attachment];
} catch (error) {
const reason = error instanceof Error ? error.message : `${error}`;
this.logger.error(
`Failed to download Facebook Ad image from '${imageUrl}': ${reason}`,
);
return [];
}
}
}
@@ -8,6 +8,7 @@ export { LocationMessage } from './LocationMessage';
export { ShareContactMessage } from './ShareContactMessage';
export { UnsupportedMessage } from './UnsupportedMessage';
export { MessageEdited } from './MessageEdited';
export { FacebookAdMessage } from './FacebookAdMessage';
export type Awaitable<T> = T | Promise<T>;