fix: OUT messages no longer create unread status + handle Telegram read receipts

Only inbound (IN) messages determine hasUnread in getContacts(). Telegram
read_business_message events are now parsed and processed to auto-mark
contacts as read for the entire team.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Ruslan Bakiev
2026-02-25 14:53:55 +07:00
parent 6291797bb6
commit 0f87586e81
3 changed files with 73 additions and 2 deletions

View File

@@ -445,9 +445,46 @@ async function upsertContactInbox(input: {
});
}
async function handleReadBusinessMessage(env: OmniInboundEnvelopeV1) {
const teamId = await resolveTeamId(env);
if (!teamId) return;
const n = env.payloadNormalized ?? ({} as OmniInboundEnvelopeV1["payloadNormalized"]);
const externalChatId = String(n.threadExternalId ?? n.contactExternalId ?? "").trim();
if (!externalChatId) return;
const thread = await prisma.omniThread.findFirst({
where: { teamId, channel: "TELEGRAM", externalChatId },
select: { contactId: true },
});
if (!thread) return;
const teamUsers = await prisma.teamMember.findMany({
where: { teamId },
select: { userId: true },
});
const now = new Date();
// ContactThreadRead is not in omni_chat's Prisma schema, use raw upsert
await Promise.all(
teamUsers.map((u) =>
prisma.$executeRaw`
INSERT INTO "ContactThreadRead" ("id", "teamId", "userId", "contactId", "readAt")
VALUES (gen_random_uuid(), ${teamId}, ${u.userId}, ${thread.contactId}, ${now})
ON CONFLICT ("userId", "contactId") DO UPDATE SET "readAt" = ${now}
`,
),
);
console.log(`[omni_chat] read_business_message: marked contact ${thread.contactId} as read for ${teamUsers.length} users`);
}
async function ingestInbound(env: OmniInboundEnvelopeV1) {
if (env.channel !== "TELEGRAM") return;
if (env.eventType === "read_business_message") {
await handleReadBusinessMessage(env);
return;
}
const teamId = await resolveTeamId(env);
if (!teamId) {
console.warn("[omni_chat] skip inbound: team not resolved", env.providerEventId);