Oshun Platform · Guides & deep dives

Telegram Architecture, Data, Contracts, and Integrations

The global registry defines telegram-bot, telegram-miniapp, and

12sections5 minread2tables

On this page

Telegram functionality is split into a provider-neutral channel policy core, Telegram-specific pure contracts, the live BFF composition, member/admin/web adapters, the Mini App, and deployment. Keeping those layers distinct prevents a pure planner or demo surface from being mistaken for a deployed effect.

Component map#

flowchart TB subgraph Core[libs/oshun/messaging-channels] R[Registry + dispatcher + boundary] T[telegram/* contracts and handler] end subgraph Runtime[apps/oshun/bff] WH[Webhook route] AD[Grounding, rooms, reminders, effects, upgrade adapters] ST[Binding, user state, update claim/dedupe] DL[Bot API delivery + scheduled cycle] end subgraph Surfaces[Apps] MA[telegram-miniapp] WB[web profile/login] AM[admin channel registry] LP[telegram-bot long-poll package] end TG[Telegram Bot API/client] <--> WH WH --> T T --> AD AD --> ST T --> DL DL --> TG MA --> WH WB --> WH AM --> WH LP --> T R --> T

Channel registry and dispatcher#

The global registry defines telegram-bot, telegram-miniapp, and telegram-channel with capability, cost, residency, consent, retention, disclosure, and crisis metadata. The dispatcher maps typed intents and content variants to a delivery/suppression decision after tier, crisis, quiet-hour, frequency, tenant, opt-in, residency, content-class, and capability checks.

The boundary layer defines allowed content classes, disclosure mechanism, provenance preservation, audit event names, and durable-memory ingestion/ redaction. It is pure policy; it does not call Telegram.

See Channel abstraction, routing, and boundaries.

Shared Telegram library#

libs/oshun/messaging-channels/src/telegram owns:

Module family Responsibility
bot, room-commands, rooms Update and command types/handler, room reads/writes, crisis and response construction.
command-surface, deep-links Private/group command registration, menu button, start payloads, discoverability.
keyboard, bot-api-limits, deliver Inline buttons/callback data, Telegram constraints, response-to-Bot-API translation and delivery.
effects, reminders, reminder-requests Save/preferences/timezone/delivery/unlink ports and reminder parsing/lifecycle.
sophia-grounder, rendering Retrieval/grounding adapter and disclosure/provenance rendering.
stt-provider, tts-provider, presence behavior Voice download/transcription/synthesis seams and chat actions.
security Login Widget/initData verification, scoped Mini App sessions, sensitive-action classification.
inline, publishing Inline results/abuse and editorial-channel post/takedown models.
upgrade, payments Upgrade port and Telegram invoice/payment lifecycle models.
rate-limit, webhook-registration Abuse/rate port and operational webhook/username description/verdict.

These modules prefer pure functions and typed ports. Provider I/O enters through an injected fetch/adapter or the BFF composition.

Live BFF webhook#

The supported live inbound route under apps/oshun/bff/src/routes/telegram.ts performs request/secret verification, update parsing, durable claim/dedupe, runtime composition, handler invocation, Bot API delivery, provider-result inspection, and update outcome. BFF modules compose:

  • Sophia retrieval/grounding bridge;
  • rooms and reminders adapters;
  • save/preference/timezone/unlink effects;
  • member local time/zone;
  • upgrade/payment bridge;
  • Mini App surface/security state;
  • durable user/binding/update stores;
  • command-surface and webhook registration;
  • scheduled reminder/outbound delivery cycle.

The webhook can reply to an inbound update only after effect and safety policy agree. It does not treat generating response JSON as delivery.

Standalone bot package#

apps/oshun/telegram-bot contains a long-poll-capable composition and tests, but its README explicitly says it is not a deployed service. It must remain a thin client of BFF-owned durable APIs if used; process-local room/reminder state would diverge from web/BFF state. Do not deploy it beside the webhook with both consuming the same bot updates.

Mini App#

apps/oshun/telegram-miniapp is a Next.js application with landing and dynamic surface routes, Telegram theme/WebApp bridge, Mini App client, curated surface data/renderers, unit/component tests, and Playwright coverage. The BFF owns initData verification, session issuance, allowed scopes, CORS policy, and real domain calls.

Static/view data and local status interactions are presentation; they become product effects only when a verified scoped call reaches a system of record. See Mini App, authentication, and account linking.

Web profile and authentication#

apps/oshun/web/src/auth/telegram owns the Login Widget integration. apps/oshun/web/src/app/profile/telegram owns link status/control UI. BFF binding storage enforces provider identity uniqueness and durable lifecycle. Web E2E tests cover widget/profile bridge, binding, and delivery integration.

Admin channel registry#

apps/oshun/admin/src/app/messaging/telegram-channels loads and presents Telegram editorial channel configuration/health for authorized operators. Its actions must use the admin/session and channel registry boundary, keep bot tokens out of the browser, distinguish configured from provider-verified, and preserve publication/audit ownership.

Core persisted records#

Exact schemas belong to their packages/migrations, but the architecture needs these logical identities:

Record Key invariants
Telegram binding Stable Telegram user id ↔ Oshun member; uniqueness, verification source/time, consent/status, version, unlink/revocation, audit.
User/channel state Member/chat delivery stop, voice/settings/timezone/quiet hours, version, last relevant provider state.
Update claim/dedupe Bot/update id, kind, claim/lease, attempts, terminal outcome, expiry; unique enough to prevent repeated effects.
Reminder Member/binding/chat, domain content/reference, local expression, resolved instant/zone, status, attempts/lease, delivery/action identity.
Delivery Intent/content, chat, message/correlation/idempotency, provider calls/responses/message ids, partial/permanent/blocked state.
Mini App session/security state Verified Telegram identity, Oshun binding, scopes, issue/expiry, audience/issuer, revocation/replay state.
Editorial channel/post Tenant/channel identity, domain, review/schedule/version, provider message id, correction/takedown, delivery/audit.
Payment/upgrade Member/order/plan/amount/currency/rail, invoice/payload/charge, pre-checkout/payment/refund, entitlement and reconciliation.

Secrets and raw content are not part of every record. Data classification, retention, deletion, and redaction apply per field/purpose.

Idempotency and ordering#

Telegram retries webhooks and can deliver different update kinds around the same user action. The BFF claims updates durably and effects use stable idempotency. Callback, reminder, payment, and membership state machines validate current state/version; late, duplicated, edited, and reordered updates cannot repeat a save/payment/entitlement or restore stopped delivery accidentally.

Outbound sends have their own idempotency and receipt state. Telegram does not offer a universal send idempotency key, so Oshun must fence attempts and reconcile uncertain provider outcomes rather than blindly retrying.

Integration boundaries#

  • Sophia: grounded retrieval/abstention and evidence/provenance; Telegram handles channel rendering, not truth production.
  • Tara/Arete/Nyx/Nisaba: domains own room state/effects; Telegram owns the compact interaction and delivery.
  • Iris/member identity: durable memory/consent/profile and binding context; Telegram transport data is minimized.
  • Payments/entitlements: billing owns price/order/entitlement/refund; Telegram owns invoice/update transport where used.
  • Veritas/editorial: editorial owner approves/version-controls content; Telegram channel adapter publishes and records delivery/takedown.
  • V3 sessions: target product owns session/entitlement; Telegram carries a safe reminder/deep link.

Contract change checklist#

  • Update the closed command/update/callback/surface/scope/content/status vocabulary and all exhaustive handlers.
  • Regenerate or update clients/config where applicable.
  • Migrate durable records with mixed-version compatibility and rollback/ forward-fix guidance.
  • Verify private/group/channel/inline and member/tenant boundaries.
  • Add adapter and webhook-to-real-effect/delivery tests; pure-planner coverage alone is insufficient.
  • Update deployment tasks/settings/secrets, webhook/command registration, dashboards/alerts/runbooks, and this handbook.
  • Re-run Docs Center generation and integrity/browser gates.