# Telegram Channels, Inline, Media, Payments, and Deep Links

Beyond private bot chat, Oshun models Telegram broadcast channels, inline
results, files/media, Mini App/deep-link navigation, and upgrade/payment state.
These surfaces share policy and provenance but use different Telegram APIs,
audiences, privacy assumptions, and delivery evidence.

```mermaid
flowchart LR
  Intent[Allowed member or editorial intent] --> Context{Telegram context}
  Context -- private bot --> Bot[Commands rooms media and upgrade]
  Context -- group --> Group[Shared-safe passage answer or deep-link fallback]
  Context -- inline --> Inline[Attributed non-personal share result]
  Context -- editorial channel --> Channel[Reviewed scheduled broadcast]
  Context -- Mini App --> Mini[Verified embedded surface]
  Bot --> Delivery[Bot API call plan and real provider response]
  Group --> Delivery
  Inline --> Delivery
  Channel --> Delivery
  Mini --> Session[initData verification and scoped BFF session]
  Bot --> Payment[Optional upgrade invoice and entitlement composition]
  Payment --> Delivery
  Delivery --> Receipt[Message callback payment or takedown receipt]
```

The context determines audience and API shape. A private capability does not
become group- or channel-safe, and a call plan is not delivery until Telegram's
application response is inspected.

## Editorial Telegram channels

`telegram-channel` is the editorial broadcast target for curated Tara, Arete,
Nyx, and Nisaba content. An editorial post carries channel/domain, content and
source/provenance, disclosure, schedule/publication identity, review/policy
state, and immutable version.

The publishing module can synthesize a Telegram-ready post and model scheduled
publication/takedown. The actual operator flow also needs:

- registered channel/chat identity and bot administrator permissions;
- tenant/editorial allowlist and environment separation;
- review/approval/embargo and idempotent schedule;
- Bot API send/edit/delete composition and application response;
- delivery message id, timestamps, failures/retries, and audit;
- correction/replacement/takedown relation to the original;
- safe text/media limits and rights for public distribution.

The channel is deliberately not crisis-capable. A public post cannot be used as
personal crisis delivery. Member preference/binding is not the authorization for
editorial publication.

Admin discovery and configuration live at
`apps/oshun/admin/src/app/messaging/telegram-channels`; browser coverage lives
in `apps/oshun/admin/e2e/telegram-channel-registry.spec.ts`. The operator
walkthrough is
[Messaging · Telegram channels](../../../ADMIN_WALKTHROUGH/cross-product/messaging-telegram-channels.md).

## Inline mode

Inline queries let a member invoke the bot from another chat and choose a
bounded share card. Builders create:

- attributable share cards with stable result id, title/description/body, deep
  link, and disclosure/provenance;
- Sophia grounded results that preserve evidence/abstention semantics;
- no result or safe refusal for abuse, unauthorized/private data, unavailable
  evidence, or content that cannot be shared.

Telegram caps result count and result-id bytes. Result ids are deterministic
enough for caching/idempotency without embedding sensitive content. Inline
queries are rate/abuse limited and never expose personal library, settings,
reminders, account, payment, or restricted source state.

Selecting an inline result is a Telegram-side share, not an Oshun durable save
unless a separate callback/effect succeeds. Attribution links use the closed
deep-link vocabulary.

## Text, files, photos, and voice delivery

The delivery translator turns a `BotResponse` into Bot API calls. It handles:

- plain/grounded text, safe parse mode, disclosure and provenance;
- message splitting within Telegram's text limit;
- inline keyboard attachment and callback-data limits;
- Telegram file ids versus upload/downloadable media references;
- photos/documents/voice forms declared by the response;
- chat actions and callback answers through their specific methods;
- multiple calls and partial failure reporting.

Media references are untrusted. Downloads/uploads use allowlisted schemes and
destinations, bounded size/time/type, no token leakage on redirects, and
validated provider responses. A source's rights must permit the intended
private/group/public delivery. File ids and provider URLs are identifiers, not
permanent proof of ownership or availability.

Telegram may answer HTTP 200 with `{ok:false}`; application body decides
success. Rate-limit/retry-after, blocked/forbidden chat, invalid entity/markup,
oversized content, missing file, and transient server/network failures are
classified separately. A multi-part response is not globally successful when one
required part failed.

## Start deep links

`https://t.me/<bot>?start=<payload>` maps a closed, bounded payload to a
command. Current mappings cover ritual/sit, check-in, tonight/sky, passage/read,
library, continue/resume, streak, settings, ask, and upgrade aliases. Unknown,
malformed, or stale payloads fall back to the greeting instead of becoming
arbitrary commands.

The bot username is normalized safely; payloads only use Telegram's allowed
character set and maximum length. Deep links do not carry member ids, resource
secrets, session tokens, raw URLs, or payment data. The member still passes
command scope, binding, authorization, policy, and availability checks after
arrival.

## Mini App buttons

Private chats can carry Web App buttons to a curated Mini App surface. Telegram
does not allow the same affordance everywhere, so group contexts use a known
`start` deep-link fallback where one exists. Missing mapping means the button is
omitted rather than pointed at a generic screen that cannot perform its label.

The Mini App base origin is configured/deployed; link builders allow only known
surface slugs and safe origin/URL construction. Opening a button is navigation,
not authentication—the Mini App still verifies initData and obtains a scoped
session.

## Upgrade flow

`/upgrade` delegates to a typed upgrade port. Possible outcomes include a ready
link/invoice choice, unavailable/not connected, ineligible/denied, invalid, or
failed. Upgrade copy and buttons follow the actual outcome and keep the payment
provider/rail explicit.

The current command description identifies a crypto upgrade path, and BFF/
payments-bridge code owns the customer-surface routing. The Telegram platform
also has typed invoice/payment lifecycle utilities. These are related but must
not be conflated: a generic Telegram invoice planner is not proof that the live
Oshun upgrade command uses Telegram fiat payments.

## Telegram invoice lifecycle

The modeled lifecycle covers:

1. Create invoice request with stable product/order/member/currency/amount and
   provider payload identity.
2. Send invoice through a configured Telegram/payment composition.
3. Receive and validate pre-checkout query; re-check order, amount/currency,
   inventory/entitlement, user/binding, expiry, and duplicate state.
4. Approve or reject within Telegram's deadline with safe copy.
5. Receive successful-payment update; verify identifiers and amount/currency,
   claim idempotently, and grant entitlement through the real billing system.
6. Persist receipt/provider charge identity and audit.
7. Handle refund/reversal through the configured provider, reconcile
   entitlement, and notify accurately.

Bot payloads are opaque, signed/unguessable or server-resolved references—not a
client-authoritative price or entitlement. A successful Telegram payment update
does not directly edit plan state without billing verification and idempotency.

## Payments safety and privacy

- Keep provider tokens, invoices, charge ids, and receipts out of ordinary
  message logs and durable chat memory.
- Never request card, seed phrase, private key, or payment secret in chat.
- Personal upgrade/payment commands are private-chat-only.
- Use the member's actual entitlement, country/currency/rail availability, and
  current price at pre-checkout, not only invoice creation.
- Separate provider acceptance, billing/entitlement application, receipt
  delivery, and refund state; expose pending/recovery when they diverge.
- Reconcile duplicate/reordered update delivery and partial outages.

## Cross-domain and V3 links

Telegram deep links and reminders can re-enter V1 member rooms and V3 session
experiences where the target product owns a safe public route and the member
passes identity/entitlement checks. Link construction names intent/surface, not
raw internal database identity. The target shows its own disclosure, memory,
rights, and safety state.

## Verification

- Editorial create/review/schedule/send/edit/correct/takedown with admin role,
  provider response, retry, and audit.
- Inline result limits, stable ids, attribution, grounding, abuse, and absence
  of private content.
- Text splitting, multibyte callback/id limits, keyboard/media construction,
  upload/download failure, Bot API application errors, and partial delivery.
- Deep-link allowed/alias/unknown/malformed/maximum/bot-addressed routes and
  post-arrival authorization.
- Private Web App button and group fallback/omission behavior.
- Upgrade outcomes and, if deployed, invoice/pre-checkout/payment/entitlement/
  refund idempotency and failure reconciliation.

Primary shared modules are `publishing.ts`, `inline.ts`, `deliver.ts`,
`deep-links.ts`, `keyboard.ts`, `upgrade.ts`, and `payments.ts` under
`libs/oshun/messaging-channels/src/telegram`.
