Telegram digest — daily and weekly reports

Last updated: May 19, 2026

Telegram digest — daily and weekly reports

Telegram digest is a periodic summary sent via the Telegram bot. Backed by telegram-digest.service.ts processDigests() called by cron every 15 minutes (lock ID 100011). 3 digest configs in telegram_notification_pref: daily_digest_enabled + daily_digest_hour, weekly_digest_enabled + weekly_digest_day + weekly_digest_hour, digest_timezone (IANA). Dedup via telegram_digest_log (past 14 days). Per-user timezone resolution.

Who is this for

Anyone who wants a curated batch of insights instead of (or in addition to) real-time alerts. Especially:

  • Mediabuyers who want a morning briefing without scrolling through real-time alerts

  • Owners who want a weekly executive view

  • Casual users who prefer summaries over notifications

How digest works

Cron job in server.ts fires telegramDigestService.processDigests() every 15 minutes (lock ID 100011, prevents duplicate execution across instances).

For each active user with daily OR weekly digest enabled:

  1. Resolve user's digest_timezone (IANA string, e.g. "Europe/Rome")

  2. Check if current time in user's timezone matches their preferred digest hour

  3. If yes + not already sent this period (check telegram_digest_log for past 14 days):

    • Generate digest content

    • Send via bot

    • Record in telegram_digest_log to prevent re-send

  4. If failure: emit event_type: 'telegram.delivery_failed' (non-blocking — doesn't break the cron)

Configuration

Set digest preferences via PUT /api/v1/telegram/preferences:

{
  "daily_digest_enabled": true,
  "daily_digest_hour": 9,        // 0-23 in user TZ
  "weekly_digest_enabled": true,
  "weekly_digest_day": 1,        // 0=Sunday ... 6=Saturday
  "weekly_digest_hour": 9,       // 0-23
  "digest_timezone": "Europe/Rome"
}

Defaults: digests off until explicitly enabled.

Common patterns

Daily morning brief:

{ "daily_digest_enabled": true, "daily_digest_hour": 9, "digest_timezone": "Europe/Rome" }

Daily summary arrives at 09:00 Rome time every day.

Weekly Monday review:

{ "weekly_digest_enabled": true, "weekly_digest_day": 1, "weekly_digest_hour": 9, "digest_timezone": "Europe/Rome" }

Weekly summary arrives Monday 09:00 Rome time.

Both daily + weekly:

Enable both. Daily arrives every day at chosen hour; weekly adds a richer summary on chosen day.

Disable digests, keep real-time alerts:

{ "daily_digest_enabled": false, "weekly_digest_enabled": false }

Real-time alerts (per ntf-104) continue independently.

What's in a digest

Daily digest typically includes:

  • Key KPI changes vs yesterday

  • Top campaigns by spend / ROAS (last 24h)

  • Rule executions summary

  • Sync status (any failures?)

  • Notable alerts grouped (vs raw real-time noise)

Weekly digest typically includes:

  • Period summary (vs prior week)

  • Top + bottom performers

  • Account-level spend + revenue

  • Rule fires count + outcomes

  • Trends (CTR drift, CPA evolution)

  • Subscriptions / billing reminders

Content tuned for Telegram readability (short, scannable, emoji-anchored).

Per-user timezone

digest_timezone is an IANA timezone string (e.g. "Europe/Rome", "America/New_York"). Used to convert user's preferred daily_digest_hour / weekly_digest_hour into UTC for the cron.

Default: workspace timezone if user hasn't set their own.

For accuracy: verify your timezone is set correctly.

Dedup mechanism

telegram_digest_log records each successful digest send:

  • user_id

  • digest_type (daily / weekly)

  • period_key (e.g. "2026-05-17-daily" or "2026-W20-weekly")

Past 14 days of dedup history checked before sending. If a period_key already exists for this user + type: skip (already sent).

Prevents:

  • Duplicate sends if cron runs twice within the same period

  • Duplicate sends after a deployment restart

  • Spam if cron lock fails

Cron infrastructure

  • Cron interval: 15 minutes

  • Lock ID: 100011 (PostgreSQL advisory lock — prevents concurrent execution across cluster)

  • Lock owner: typically the cron service instance

  • Backoff: failure non-blocking; retries naturally next 15-min tick

What happens if you're offline

  • Digest still attempts to send at the preferred hour

  • If you've blocked the bot: send fails → telegram_link.is_active = false

  • Future digests skip you (since bot link inactive)

  • Re-link to resume (per ntf-104)

If you turn off Telegram for the day: digest queued and delivered when Telegram pushes (usually instant — Telegram caches messages for offline users).

Vs real-time alerts

Aspect

Real-time alerts

Digest

Latency

Instant (SQS)

At configured hour

Cadence

Per event

Daily + weekly

Volume

Per event

1-2 messages/day max

Content

Single event

Aggregated summary

Toggle

alert_* per type

daily_digest_enabled + weekly_digest_enabled

Use both: real-time for critical events (account disconnected, payment failure, rule action failure), digest for routine performance summary.

Use cases

Mediabuyer morning routine

Daily digest at 09:00. Read on phone over coffee. Decide what needs attention before opening Wevion UI.

Owner weekly review

Weekly digest Monday 09:00. Get last week's headline numbers without logging in. Triage what to drill into.

Team-wide visibility (owner fan-out)

If you're the team owner and team members have notifications enabled: you also receive their notifications (with "Team: [memberName]" prefix). Digest is per-user, not aggregated team-wide.

Multi-timezone team

Each user sets their own digest_timezone. Owner in Rome gets digest at 09:00 Rome time; mediabuyer in NYC gets at 09:00 NYC time.

Common issues

  • Digest didn't arrive at expected time: check digest_timezone is correct; cron is every 15 min so digest fires at next 15-min boundary after target hour

  • Digest missing some campaigns: data freshness lag (15-min sync); recent campaigns may not appear in immediate-next digest

  • Duplicate digests: rare; telegram_digest_log dedup should prevent. If happens: report bug + check telegram_digest_log table for duplicate period_key

  • Digest too long / too short: content tuning is system-level; provide feedback for adjustment

  • Digest content empty: account has no activity in window; expected for new / inactive accounts

Common mistakes

  • Wrong timezone: digest arrives at unexpected hour; verify digest_timezone IANA string

  • Daily + weekly on same day overlap: Monday morning both daily + weekly fire if same hour; expected behavior

  • Expecting digest to include real-time alerts: digest is summary; real-time alerts arrive separately

  • Expecting hourly digest: not supported; only daily + weekly

Related