Fix Telegram direction mapping and contact hydration
This commit is contained in:
@@ -45,6 +45,29 @@ function cropText(value: unknown) {
|
||||
return value.slice(0, MAX_TEXT_LENGTH);
|
||||
}
|
||||
|
||||
function normalizeString(value: unknown) {
|
||||
if (typeof value !== "string") return null;
|
||||
const normalized = value.trim();
|
||||
return normalized || null;
|
||||
}
|
||||
|
||||
function detectDirection(message: JsonObject, chat: JsonObject, from: JsonObject): "IN" | "OUT" {
|
||||
if (typeof message.outgoing === "boolean") return message.outgoing ? "OUT" : "IN";
|
||||
if (typeof message.is_outgoing === "boolean") return message.is_outgoing ? "OUT" : "IN";
|
||||
if (typeof message.out === "boolean") return message.out ? "OUT" : "IN";
|
||||
|
||||
const chatType = normalizeString(chat.type);
|
||||
if (chatType === "private" && from.is_bot === true) return "OUT";
|
||||
|
||||
const chatId = chat.id != null ? String(chat.id) : null;
|
||||
const fromId = from.id != null ? String(from.id) : null;
|
||||
if (chatType === "private" && chatId && fromId && chatId !== fromId) {
|
||||
return "OUT";
|
||||
}
|
||||
|
||||
return "IN";
|
||||
}
|
||||
|
||||
function requireString(value: unknown, fallback: string) {
|
||||
const v = String(value ?? "").trim();
|
||||
return v || fallback;
|
||||
@@ -72,6 +95,9 @@ 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 threadExternalId =
|
||||
chat.id != null
|
||||
@@ -80,7 +106,12 @@ export function parseTelegramBusinessUpdate(raw: unknown): OmniInboundEnvelopeV1
|
||||
? String(businessConnection.user_chat_id)
|
||||
: null;
|
||||
|
||||
const contactExternalId = from.id != null ? String(from.id) : null;
|
||||
const contactExternalId =
|
||||
contactSource.id != null
|
||||
? String(contactSource.id)
|
||||
: fallbackContactSource.id != null
|
||||
? String(fallbackContactSource.id)
|
||||
: null;
|
||||
|
||||
const text = cropText(message.text) ?? cropText(message.caption);
|
||||
|
||||
@@ -105,7 +136,7 @@ export function parseTelegramBusinessUpdate(raw: unknown): OmniInboundEnvelopeV1
|
||||
idempotencyKey,
|
||||
provider: "telegram_business",
|
||||
channel: "TELEGRAM",
|
||||
direction: "IN",
|
||||
direction,
|
||||
providerEventId,
|
||||
providerMessageId,
|
||||
eventType,
|
||||
@@ -119,9 +150,18 @@ export function parseTelegramBusinessUpdate(raw: unknown): OmniInboundEnvelopeV1
|
||||
businessConnectionId,
|
||||
updateId: updateId != null ? String(updateId) : null,
|
||||
chatTitle: typeof chat.title === "string" ? chat.title : null,
|
||||
chatUsername: normalizeString(chat.username),
|
||||
chatFirstName: normalizeString(chat.first_name),
|
||||
chatLastName: normalizeString(chat.last_name),
|
||||
contactUsername: normalizeString(contactSource.username),
|
||||
contactFirstName: normalizeString(contactSource.first_name),
|
||||
contactLastName: normalizeString(contactSource.last_name),
|
||||
contactTitle: normalizeString(contactSource.title),
|
||||
contactAvatarUrl: normalizeString(contactSource.photo_url),
|
||||
fromUsername: typeof from.username === "string" ? from.username : null,
|
||||
fromFirstName: typeof from.first_name === "string" ? from.first_name : null,
|
||||
fromLastName: typeof from.last_name === "string" ? from.last_name : null,
|
||||
fromIsBot: from.is_bot === true,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ export type OmniInboundEnvelopeV1 = {
|
||||
idempotencyKey: string;
|
||||
provider: string;
|
||||
channel: OmniInboundChannel;
|
||||
direction: "IN";
|
||||
direction: "IN" | "OUT";
|
||||
providerEventId: string;
|
||||
providerMessageId: string | null;
|
||||
eventType: string;
|
||||
|
||||
Reference in New Issue
Block a user