Files
HealthLog/src/lib/telegram-cleanup.ts
T
Marc-André Bombeck b24a893b66 feat(telegram): log mood and act on measurement reminders in chat
Extend the self-cleaning Telegram bot beyond medication. A mood reminder
now carries a 1-5 inline keyboard plus a "Note..." force-reply and a
"Later" action; a tap logs a MoodEntry (source TELEGRAM, server-side,
user resolved from the linked chat, idempotent on a per-tap externalId)
and confirms with a calm callback toast, no chat echo. An optional
free-text note attaches to that entry via the prompt-context correlation.
A measurement reminder carries "Done" (satisfies the cadence) and
"Later" (pushes nextDueAt forward) — completion and snooze only, no value
capture.

Prompts and replies self-clean in ~30 minutes: the window drops from 1h
and moves to a shared helper, the sender schedules an unanswered prompt's
deletion at send time, and the existing 15-min sweep also prunes expired
prompt-context rows. The webhook keeps the shared-secret + timingSafeEqual
+ rate-limit-before-secret posture; every write callback authenticates via
the stored chat binding. The Telegram chat id is added to the egress
redaction denylist.
2026-06-21 11:13:33 +02:00

50 lines
1.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* v1.19.0 — shared self-clean scheduling for the Telegram bot.
*
* The interactive mood + measurement flows ride the existing
* `TelegramScheduledDeletion` table + the ~15-min pg-boss sweep
* (`cleanupScheduledTelegramDeletions`). This helper centralises the
* "schedule these message ids for deletion in ~30 minutes" write so the
* webhook (free-text replies) and the sender (unanswered prompts) agree on
* the window. The sweep deletes the bot's own prompt AND, where its id was
* captured, the user's reply — both within Telegram's 48-hour window.
*/
import type { Prisma, PrismaClient } from "@/generated/prisma/client";
import { prisma as defaultPrisma } from "@/lib/db";
/**
* Auto-delete delay for interactive-flow prompts + answers. ~30 minutes
* keeps the chat clean and unbiased while staying well inside Telegram's
* 48-hour deletion ceiling. The sweep ticks every ~15 min, so real
* deletion lands at 30–45 min — invisible slack, no dedicated queue.
*/
export const TELEGRAM_AUTO_DELETE_DELAY_MS = 30 * 60 * 1000;
/**
* Schedule one or more Telegram message ids for best-effort deletion after
* `TELEGRAM_AUTO_DELETE_DELAY_MS`. Best-effort: a write failure must never
* break the inbound/outbound flow it rides on.
*/
export async function scheduleTelegramAutoDelete(
userId: string,
chatId: string,
messageIds: number[],
client: PrismaClient | Prisma.TransactionClient = defaultPrisma,
): Promise<void> {
const ids = messageIds.filter((id): id is number => Number.isFinite(id));
if (ids.length === 0) return;
const deleteAfter = new Date(Date.now() + TELEGRAM_AUTO_DELETE_DELAY_MS);
try {
await client.telegramScheduledDeletion.createMany({
data: ids.map((messageId) => ({
userId,
chatId,
messageId,
deleteAfter,
})),
});
} catch {
// Best-effort — the message simply lingers until the next send re-cleans.
}
}