# Telegram chat — AgentBridge as a Telegram chat client

AgentBridge can connect to Telegram **as a user account** (a "userbot") and act like any
other chat client you already support (the TUI, the HTML/Giraffe web client): people write
to your account in a **private chat**, the message (text and/or file attachments) is handed
to the agents, and the reply — text plus any files the agent attaches — comes back into the
same chat.

This is **text chat with attachments only**. The Telegram Client API (MTProto) does not
support audio calls, so Telegram is **not** a voice medium: the media list stays
**SIP (phone calls) and Voice (desktop microphone)** — Telegram adds a chat client, nothing
more. The transport is the [WTelegramClient](https://github.com/wiz0u/WTelegramClient)
library (userbot, MTProto); no HTTP/API polling is involved.

## How it works

```
Telegram user ⇄ private chat message (text + files) ⇄ WTelegramClient (userbot)
                                                          │
                              filter: private chats only, own messages (echo) ignored
                                                          │
                           access gate — allow-list (AllowedUsers; empty = nobody)
                           or first message = shared access PIN → enrolled + welcome
                                                          │
                              per-user FIFO queue (messages answered in arrival order)
                                                          │
        DownloadFileAsync (incoming files, ≤25 MB) → FileAttachment     │
                                                          │
                                              SessionStore + AgentHarness.ExecuteAction
                                              (one chat session per user, 30-min idle expiry)
                                                          │
        SendMessageAsync (reply) + SendMediaAsync (agent's attachments, ≤25 MB each)
```

- **Private chats only.** Messages in groups/channels are ignored (as are the bot's own
  messages, so replies never echo into an endless loop).
- **Closed by default.** Only the users listed in `AllowedUsers` (numeric Telegram id or
  `@username`) can talk to the agent. **Empty = nobody** — a stranger who finds the account
  is ignored until they authenticate.
- **Enrollment with the access PIN.** An unlisted user who sends the **access PIN** — the
  same PIN used for SIP calls (`Sip:Pin`, changed from the TUI with `/sip config set Pin`;
  the two mediums share one PIN and one attempt/lockout budget) — is added to `AllowedUsers`
  automatically and receives the same welcome used after a SIP login, as text
  ("How can I help you?"). Wrong PINs count against the shared gate and can lock the PIN
  out machine-wide for the configured hours. No PIN configured = the enrollment path is
  disabled (allow-list only).
- **Attachments both ways.** Incoming documents/photos are downloaded (cap 25 MB) and go
  through the same server-side Markdown conversion as the HTML uploads (`/v1/files`), so the
  agent reads their content. Files the agent attaches in its answer (the `done` method's
  `"attachments"` field) are sent back as Telegram documents (cap 25 MB each).
- **One conversation per user.** Each user keeps a multi-turn session (history); after
  30 minutes of silence the session is disposed and a fresh one starts on the next message.

## Configuration (`telegram.json`)

Telegram configuration lives in its own file, **`PersistentData\telegram.json`**
— separate from `PersistentData\appsettings.json` on purpose, and never touched by updates
(see [autoupdate.md](autoupdate.md) "the file storage tiers", same protection as `providers.json`).
You can edit it by hand, from the TUI (`/telegram`), or with the guided setup scripts
(`scripts/setup-telegram.bat` on Windows, `scripts/setup-telegram.sh` on Linux/macOS —
English prompts, they create or update `telegram.json`).

| Key | Default | Description |
|---|---|---|
| `Enabled` | `false` | Master switch — the bridge starts at boot only when true |
| `ApiId` | built-in | App api_id — AgentBridge ships with its own app identity, no need to create one. Override to use a per-install app |
| `ApiHash` | built-in | App api_hash — same as above |
| `PhoneNumber` | `""` | Account phone number, international format (e.g. `+393331234567`) — **the only key a new deployment must set** |
| `SessionPath` | `"telegram.session"` | Session file (auth keys) stored under `PersistentData\`. After the first login the session persists: no code is asked again |
| `AllowedUsers` | `[]` | Users allowed to talk to the agent — numeric ids and/or `@usernames`, comma-separated in the TUI. **Empty = nobody** (closed by default): users enroll by sending the access PIN (see above) or are added from the TUI |
| `Agent` | `"default-agent"` | Agent set used for the conversations (see AgentTools.Resolve) |

> **Access PIN.** Telegram shares the external-client access PIN with SIP: set it once with
> `/sip config set Pin <code>` (shown masked as `Sip:Pin` in the appsettings config). The PIN
> gate is machine-wide — wrong attempts from SIP **and** Telegram accumulate and a lockout
> blocks both for `Sip:LockoutHours`.

## First login (one time only)

The first login needs the **verification code** Telegram sends (SMS/call/other Telegram
app), and the 2FA password if the account has one. The TUI guides it — nothing blocks the
server boot, the bridge simply waits in a pending-login state:

```
/telegram status                        → phase "code" (login pending)
/telegram login-code 12345              → paste the code from Telegram
/telegram status                        → phase "on" (connected)
```

The `.session` file is written automatically; the next starts log in silently.

## TUI commands

| Command | Meaning |
|---|---|
| `/telegram status` | Live state: enabled, phase (`off`/`conn`/`code`/`2fa`/`on`/`err`), logged-in user, allow-list, agent |
| `/telegram config` | Show the effective configuration (api_hash masked) |
| `/telegram config set <key> <value>` | Change one config key and persist it to `telegram.json` (connection keys restart the bridge) |
| `/telegram config reload` | Re-read `telegram.json` (hand edits made outside the TUI) and apply them |
| `/telegram login-code <code>` | Complete the pending login (verification code or 2FA password) |
| `/telegram allow <user>` | Add a user (id or @username) to the allow-list and persist |
| `/telegram disallow <user>` | Remove a user from the allow-list and persist |

The status bar shows a `tg:` segment (`on` = connected, `code` = waiting for the login
code, ...) refreshed by the same 3-second poll as SIP.

**Telegram is an in-process chat client — it exposes no HTTP endpoints.** The
`/telegram` TUI commands call the `TelegramBridge` directly in the same process; the
message transport is entirely the WTelegramClient library. There is nothing to configure
over HTTP: the configuration surface is the TUI, the setup scripts, and `telegram.json`
itself.

## Getting your api_id / api_hash

**You normally don't need these.** AgentBridge ships with its own Telegram app identity
(`ApiId`/`ApiHash` compiled in) — a deployment only sets `PhoneNumber` and completes the
first login with the verification code.

Override the built-in credentials **only** when you want a per-install app identity (for
example to keep independent deployments from sharing one app):

1. Open https://my.telegram.org/apps and sign in with the account you want to use.
2. Create an application (any name/description — these identify *your* app, not the user).
3. Put your values in `telegram.json` (`ApiId` / `ApiHash`) — they take precedence over
   the built-in ones (or set them with `/telegram config set ApiId <id>` and
   `/telegram config set ApiHash <hash>`).

## Notes and limitations

- **A userbot, not a bot.** The bridge signs in as a real user account. Telegram's terms
  of service apply; don't use it for spam. If you prefer a bot account, use a BotFather
  token instead — out of scope here.
- **No audio.** The Telegram Client API has no audio-call support: voice messages are
  treated as file attachments, not as a conversation medium.
- **Security.** The api_hash and the `.session` file are credentials: protect them like the
  API keys in `providers.json`. The session file allows full access to the account.
- **Telegram sessions are per-device.** Telegram may show a new active session in the
  account settings after the first login — normal.
