From 55e86987e97d3ab2a546c773fad9712a2894efbb Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 22 Jan 2026 17:13:07 +0000 Subject: [PATCH] feat(history): add userReceipt fallback for LID-PN mapping extraction Add extractPnFromMessages() function to extract phone numbers from userReceipt fields when pnJid is missing in LID conversations. This is a cherry-pick of the functionality from upstream PR #2282 (commit f829b6d7a) integrated with our existing LID-PN extraction logic. Closes: WhiskeySockets/Baileys#2282 --- src/Utils/history.ts | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/Utils/history.ts b/src/Utils/history.ts index b55562ee..7754395e 100644 --- a/src/Utils/history.ts +++ b/src/Utils/history.ts @@ -206,6 +206,36 @@ export function extractLidPnFromMessage( return undefined } +/** + * Extracts phone number (PN) from message userReceipt fields. + * + * This is a fallback mechanism for LID chats that don't have a pnJid property. + * It looks at outgoing messages (fromMe: true) and extracts the recipient's + * phone number from the userReceipt.userJid field. + * + * @param messages - Array of history sync messages from a conversation + * @returns The extracted phone number JID, or undefined if not found + * + * @see https://github.com/WhiskeySockets/Baileys/pull/2282 + */ +const extractPnFromMessages = (messages: proto.IHistorySyncMsg[]): string | undefined => { + for (const msgItem of messages) { + const message = msgItem.message + // Only extract from outgoing messages (fromMe: true) in 1:1 chats + // because userReceipt.userJid is the recipient's JID + if (!message?.key?.fromMe || !message.userReceipt?.length) { + continue + } + + const userJid = message.userReceipt[0]?.userJid + if (userJid && (isPnUser(userJid) || isHostedPnUser(userJid))) { + return userJid + } + } + + return undefined +} + /** * Processes a history sync message and extracts chats, contacts, messages, * and LID-PN mappings. @@ -276,6 +306,16 @@ export const processHistoryMessage = (item: proto.IHistorySync) => { ) if (conversationMapping) { addLidPnMapping(conversationMapping) + } else if ((isLidUser(chatId) || isHostedLidUser(chatId)) && !chat.pnJid) { + // Source 2b: Fallback - extract PN from userReceipt in messages when pnJid is missing + // This handles edge cases where the conversation is LID but pnJid wasn't provided + const pnFromReceipt = extractPnFromMessages(chat.messages || []) + if (pnFromReceipt) { + addLidPnMapping({ + lid: jidNormalizedUser(chatId), + pn: jidNormalizedUser(pnFromReceipt) + }) + } } contacts.push({