File size: 8,660 Bytes
c325199
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4415545
 
c325199
 
 
 
 
 
 
 
 
 
 
 
 
4415545
 
 
 
 
 
 
 
 
 
c325199
 
 
 
 
 
 
 
 
4415545
 
 
c325199
 
 
 
 
 
 
 
 
 
4415545
 
c325199
 
4415545
 
 
 
 
c325199
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# 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.