diff --git a/src/apps/chatwoot/consumers/waha/base.ts b/src/apps/chatwoot/consumers/waha/base.ts index a666d5c1..d46e488d 100644 --- a/src/apps/chatwoot/consumers/waha/base.ts +++ b/src/apps/chatwoot/consumers/waha/base.ts @@ -320,6 +320,7 @@ export abstract class MessageBaseHandler< this.session, EngineHelper.ChatID(payload as any), this.l, + EngineHelper.PhoneNumber(payload as any), ); const conversation = await this.repo.ConversationByContact(contactInfo); this.info.onConversationId(conversation.conversationId); diff --git a/src/apps/chatwoot/contacts/WhatsAppContactInfo.ts b/src/apps/chatwoot/contacts/WhatsAppContactInfo.ts index 273184d4..2a72bb2a 100644 --- a/src/apps/chatwoot/contacts/WhatsAppContactInfo.ts +++ b/src/apps/chatwoot/contacts/WhatsAppContactInfo.ts @@ -89,9 +89,21 @@ class JidContactInfo extends ChatContactInfo { * LID contact info */ class LidContactInfo extends ChatContactInfo { + constructor( + session: WAHASessionAPI, + chatId: string, + locale: Locale, + private pn: string | null = null, + ) { + super(session, chatId, locale); + } + @CacheAsync() async jid() { - const pn = await this.session.findPNByLid(this.chatId); + let pn = this.pn; + if (!pn) { + pn = await this.session.findPNByLid(this.chatId); + } if (!pn) { return null; } @@ -261,6 +273,7 @@ export function WhatsAppContactInfo( session: WAHASessionAPI, chatId: string, locale: Locale, + pn: string | null = null, ): ContactInfo { if (isJidGroup(chatId)) { return new GroupContactInfo(session, chatId, locale); @@ -271,7 +284,7 @@ export function WhatsAppContactInfo( } else if (isJidBroadcast(chatId)) { return new BroadcastContactInfo(session, chatId, locale); } else if (isLidUser(chatId)) { - return new LidContactInfo(session, normalizeJid(chatId), locale); + return new LidContactInfo(session, normalizeJid(chatId), locale, pn); } else if (isPnUser(chatId)) { return new JidContactInfo(session, chatId, locale); } else { diff --git a/src/apps/chatwoot/waha/engines.ts b/src/apps/chatwoot/waha/engines.ts index 8aabd1bd..e7b5e8d8 100644 --- a/src/apps/chatwoot/waha/engines.ts +++ b/src/apps/chatwoot/waha/engines.ts @@ -5,7 +5,12 @@ import { WAHAEngine } from '@waha/structures/enums.dto'; import { getEngineName } from '@waha/version'; import { Message as MessageInstance } from 'whatsapp-web.js/src/structures'; import { Jid } from '@waha/core/engines/const'; -import { isLidUser, isPnUser, toCusFormat } from '@waha/core/utils/jids'; +import { + isLidUser, + isPnUser, + jidsFromKey, + toCusFormat, +} from '@waha/core/utils/jids'; import { parseMessageIdSerialized } from '@waha/core/utils/ids'; import { WAMessage } from '@waha/structures/responses.dto'; import { CallData } from '@waha/structures/calls.dto'; @@ -22,6 +27,12 @@ export interface QuotedMedia { interface IEngineHelper { ChatID(message: WAMessage | any): string; + /** + * Phone number chat id (@c.us) of the DM contact extracted from the message payload + * (alt jid fields), when the engine provides it. Null otherwise. + */ + PhoneNumber(message: WAMessage | any): string | null; + CallChatID(call: CallData | any): string; IsReplyToStatus( @@ -49,6 +60,15 @@ class NOWEBHelper implements IEngineHelper { return message.from; } + PhoneNumber(message: WAMessage | any): string | null { + const key = message._data?.key; + if (!key) { + return null; + } + const jids = jidsFromKey(key); + return pnChatIdOrNull(jids?.pn); + } + CallChatID(call: CallData): string { return call.from; } @@ -100,6 +120,21 @@ class GOWSHelper implements IEngineHelper { return message.from; } + PhoneNumber(message: WAMessage | any): string | null { + const info = message._data?.Info; + if (!info) { + return null; + } + // SenderAlt / RecipientAlt carry the phone number for @lid-addressed chats + let pn: string | null; + if (info.IsFromMe) { + pn = info.RecipientAlt || null; + } else { + pn = info.SenderAlt || null; + } + return pnChatIdOrNull(pn); + } + CallChatID(call: CallData): string { return call._data?.CallCreator || call.from; } @@ -156,6 +191,11 @@ class WEBJSHelper implements IEngineHelper { return message._data?.id?.remote || message.from; } + PhoneNumber(message: WAMessage | any): string | null { + void message; + return null; + } + CallChatID(call: CallData): string { return call.from; } @@ -222,6 +262,11 @@ class WPPHelper implements IEngineHelper { return toCusFormat(parseMessageIdSerialized(message.id as any).remoteJid); } + PhoneNumber(message: WAMessage | any): string | null { + void message; + return null; + } + CallChatID(call: CallData): string { return call.from; } @@ -367,6 +412,17 @@ function extractBrowserQuotedMedia(replyData: any): QuotedMedia | null { }; } +function pnChatIdOrNull(pn: string | null | undefined): string | null { + if (!pn) { + return null; + } + const chatId = toCusFormat(pn); + if (isPnUser(chatId)) { + return chatId; + } + return null; +} + function preferPnChats(chats: string[]): string[] { const unique = lodash.uniq(chats ?? []); const hasPn = unique.some(isPnUser);