fix(whatsapp): prevent merged lid conversations from returning
This commit is contained in:
+19
-4
@@ -33,6 +33,7 @@ import { isTimestampOlderThan, webhookEventClaimDecision } from './reliability.j
|
||||
import {
|
||||
canonicalWhatsAppJid,
|
||||
isWeakWhatsAppDisplayName,
|
||||
resolvedWhatsAppJid,
|
||||
reusableWhatsAppConversations,
|
||||
whatsappConversationActivityAt,
|
||||
whatsappCustomerStableId,
|
||||
@@ -3231,7 +3232,9 @@ async function upsertWhatsAppMessage(tenantId, channel, rawMessage, options = {}
|
||||
if (!rawJid || !rawMessage.id) return null
|
||||
const aliasCacheKey = `${channel.gatewayAccountId}:${rawJid}`
|
||||
const cachedJid = whatsappCanonicalJidCache.get(aliasCacheKey)
|
||||
const preliminaryJid = cachedJid || rawJid
|
||||
const rawCanonicalJid = canonicalWhatsAppJid(rawJid)
|
||||
const hasCanonicalAlias = Boolean(cachedJid && cachedJid !== rawCanonicalJid)
|
||||
const preliminaryJid = hasCanonicalAlias ? cachedJid : rawCanonicalJid
|
||||
const rawConversationId = `${channel.id}:${rawJid}`
|
||||
const preliminaryConversationId = `${channel.id}:${preliminaryJid}`
|
||||
const preliminaryCustomer = await resolveWhatsAppCustomer(
|
||||
@@ -3242,7 +3245,7 @@ async function upsertWhatsAppMessage(tenantId, channel, rawMessage, options = {}
|
||||
)
|
||||
const needsIdentity = Boolean(
|
||||
options.identity
|
||||
|| (rawJid.endsWith('@lid') && !cachedJid)
|
||||
|| (rawJid.endsWith('@lid') && !hasCanonicalAlias)
|
||||
|| !preliminaryCustomer
|
||||
|| isWeakWhatsAppDisplayName(preliminaryCustomer?.name, rawJid),
|
||||
)
|
||||
@@ -3256,8 +3259,15 @@ async function upsertWhatsAppMessage(tenantId, channel, rawMessage, options = {}
|
||||
avatarUrl: preliminaryCustomer.avatarUrl,
|
||||
chatType: preliminaryCustomer.whatsappChatType,
|
||||
})
|
||||
const jid = cachedJid || canonicalWhatsAppJid(rawJid, identity || {})
|
||||
whatsappCanonicalJidCache.set(aliasCacheKey, jid)
|
||||
const jid = resolvedWhatsAppJid(rawJid, identity || {}, cachedJid)
|
||||
// A LID is a temporary alias, not a stable customer identity. Never cache an
|
||||
// unresolved LID as canonical; otherwise a later sync can recreate a merged
|
||||
// duplicate conversation even after the gateway learns its phone JID.
|
||||
if (jid !== rawCanonicalJid || !rawJid.endsWith('@lid')) {
|
||||
whatsappCanonicalJidCache.set(aliasCacheKey, jid)
|
||||
} else {
|
||||
whatsappCanonicalJidCache.delete(aliasCacheKey)
|
||||
}
|
||||
const conversationId = `${channel.id}:${jid}`
|
||||
if (
|
||||
await getResource(tenantId, 'conversation-tombstones', conversationId)
|
||||
@@ -3478,6 +3488,11 @@ async function mergeLegacyWhatsAppConversations(tenantId, channel, jid, aliasJid
|
||||
await deleteResource(tenantId, `messages:${source.id}`, message.id)
|
||||
}
|
||||
await deleteResource(tenantId, 'conversations', source.id)
|
||||
broadcast(tenantId, {
|
||||
type: 'conversation.deleted',
|
||||
conversationId: source.id,
|
||||
mergedIntoConversationId: targetId,
|
||||
})
|
||||
}
|
||||
await patchResource(tenantId, 'conversations', targetId, {
|
||||
customerId,
|
||||
|
||||
@@ -13,6 +13,15 @@ export function canonicalWhatsAppJid(jid, identity = {}) {
|
||||
return phone ? `${phone}@s.whatsapp.net` : raw
|
||||
}
|
||||
|
||||
export function resolvedWhatsAppJid(jid, identity = {}, cachedJid = '') {
|
||||
const fallback = canonicalWhatsAppJid(jid)
|
||||
const resolved = canonicalWhatsAppJid(jid, identity)
|
||||
if (resolved && resolved !== fallback) return resolved
|
||||
|
||||
const cached = canonicalWhatsAppJid(cachedJid)
|
||||
return cached && cached !== fallback ? cached : fallback
|
||||
}
|
||||
|
||||
export function whatsappCustomerStableId(jid) {
|
||||
const normalized = canonicalWhatsAppJid(jid)
|
||||
const hash = crypto.createHash('sha256').update(normalized).digest('hex').slice(0, 24)
|
||||
|
||||
Reference in New Issue
Block a user