diff --git a/omni_chat/src/worker.ts b/omni_chat/src/worker.ts index 6769914..795e232 100644 --- a/omni_chat/src/worker.ts +++ b/omni_chat/src/worker.ts @@ -212,19 +212,12 @@ function buildContactProfile( normalized: OmniInboundEnvelopeV1["payloadNormalized"], externalContactId: string, ): ContactProfile { - const firstName = - asString(normalized.contactFirstName) ?? - asString(normalized.fromFirstName) ?? - asString(normalized.chatFirstName); - const lastName = - asString(normalized.contactLastName) ?? - asString(normalized.fromLastName) ?? - asString(normalized.chatLastName); - const username = - asString(normalized.contactUsername) ?? - asString(normalized.fromUsername) ?? - asString(normalized.chatUsername); - const title = asString(normalized.contactTitle) ?? asString(normalized.chatTitle); + // Use only normalized contact-* fields (counterparty), avoid sender/chat fallbacks + // to prevent accidental renames to the business owner name on OUT events. + const firstName = asString(normalized.contactFirstName); + const lastName = asString(normalized.contactLastName); + const username = asString(normalized.contactUsername); + const title = asString(normalized.contactTitle); const fullName = [firstName, lastName].filter(Boolean).join(" "); const displayName = diff --git a/omni_inbound/src/telegram.ts b/omni_inbound/src/telegram.ts index 834c8b1..4b8b0d3 100644 --- a/omni_inbound/src/telegram.ts +++ b/omni_inbound/src/telegram.ts @@ -60,6 +60,12 @@ function normalizeNumber(value: unknown) { return null; } +function normalizeId(value: unknown) { + if (value == null) return null; + const text = String(value).trim(); + return text || null; +} + type TelegramMediaInfo = { kind: "voice" | "audio" | "video_note" | null; fileId: string | null; @@ -159,8 +165,26 @@ export function parseTelegramBusinessUpdate(raw: unknown): OmniInboundEnvelopeV1 const chat = asObject(message.chat); const from = asObject(message.from); const direction = detectDirection(message, chat, from); - const contactSource = direction === "OUT" && Object.keys(chat).length > 0 ? chat : from; - const fallbackContactSource = direction === "OUT" ? from : chat; + const ownerChatId = normalizeId(businessConnection.user_chat_id); + const chatId = normalizeId(chat.id); + const fromId = normalizeId(from.id); + + let contactSource: JsonObject | null = null; + if (ownerChatId) { + // Prefer the counterparty id/source (different from connected owner chat id). + if (chatId && chatId !== ownerChatId) contactSource = chat; + if (fromId && fromId !== ownerChatId) { + if (!contactSource || direction === "IN") { + contactSource = from; + } + } + } + + if (!contactSource) { + contactSource = direction === "OUT" && Object.keys(chat).length > 0 ? chat : from; + } + + const fallbackContactSource = contactSource === chat ? from : chat; const threadExternalId = chat.id != null @@ -170,11 +194,9 @@ export function parseTelegramBusinessUpdate(raw: unknown): OmniInboundEnvelopeV1 : null; const contactExternalId = - contactSource.id != null - ? String(contactSource.id) - : fallbackContactSource.id != null - ? String(fallbackContactSource.id) - : null; + normalizeId(contactSource?.id) ?? + normalizeId(fallbackContactSource?.id) ?? + null; const media = pickTelegramMedia(message); const text =