better-tg-cli 0.19.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,211 +1,116 @@
1
1
  # better-tg-cli
2
2
 
3
- An unofficial, agent-friendly command-line client for Telegram on your own account (MTProto via `teleproto`, TL layer 229).
4
- The binary is `telegram`. Fork of [skillhq/telegram](https://github.com/skillhq/telegram) with bot
5
- buttons, rich (layer 228+) bot replies, threads and forum topics, compact output for agents, and
6
- about 60 commands. Run `telegram help-all` for the full command and flag list.
7
-
8
- ## Installation
9
-
10
- ```bash
11
- brew install thevilfer/tap/better-tg-cli # standalone binary, macOS and Linux, no Node needed
3
+ [![CI](https://github.com/TheVilfer/better-tg-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/TheVilfer/better-tg-cli/actions/workflows/ci.yml)
4
+ [![npm](https://img.shields.io/npm/v/better-tg-cli?color=cb3837&logo=npm)](https://www.npmjs.com/package/better-tg-cli)
5
+ [![Homebrew](https://img.shields.io/badge/brew-thevilfer%2Ftap-fbb040?logo=homebrew)](https://github.com/TheVilfer/homebrew-tap)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
7
+
8
+ An unofficial, agent-friendly command-line client for Telegram that runs **on your own account**
9
+ (MTProto via [`teleproto`](https://www.npmjs.com/package/teleproto), TL layer 229). The command is
10
+ `telegram`: about 60 commands for reading, searching, writing, bots, groups and exports, built so
11
+ that AI agents (Claude Code, Codex, …) can drive it cheaply and safely.
12
+
13
+ ```console
14
+ $ telegram inbox -n 3
15
+ 48 unread in 7 chats (showing 3)
16
+ 1234567890 user unread=2 Alice @alice | see you at 7?
17
+ -1001234567 supergroup muted unread=41 Rust Moscow @rust_msk | anyone tried 1.90?
18
+ -1009876543 channel unread=5 Changelog | v2.4 is out
19
+ $ telegram read @alice -n 1 --json
20
+ {"chatTitle":"Alice","messages":[{"id":812,"date":"2026-09-27T10:02:11.000Z","sender":"Alice","senderId":"1234567890","text":"see you at 7?"}]}
21
+ ```
22
+
23
+ ## Why this fork
24
+
25
+ A fork of [skillhq/telegram](https://github.com/skillhq/telegram), reworked for agents:
26
+
27
+ - **Current Telegram layer.** Bot replies with rich (layer 228+) content show real text instead of
28
+ `(no text)`. You can press bot buttons (`click`) and walk bot menus.
29
+ - **Token-efficient output.** Off a TTY you get one compact line per item with the ID first, and
30
+ JSON on one line with empty fields dropped. `--max-text` trims long posts. `telegram help-all -g
31
+ <word>` prints every flag, generated from the code.
32
+ - **Exact reads.** Real pagination for `--since/--until`, `--unread`, threads and channel
33
+ comments, forum topics, `get` by ID, search filters by type, sender or date, and `me` / `Избранное`
34
+ for Saved Messages.
35
+ - **Safe by default.** The account is read-only until a human runs `write-access on [--for 1h]`
36
+ and confirms it in a terminal prompt or a macOS dialog, so an agent cannot switch it on itself.
37
+ Every write is logged to `~/.config/tg/audit.jsonl`. Secrets live in the macOS Keychain or in
38
+ 1Password.
39
+ - **Small and self-contained.** The npm package is one 0.3 MB file with zero runtime
40
+ dependencies. Homebrew installs a standalone binary with no Node.
41
+
42
+ ## Install
43
+
44
+ ```bash
45
+ brew install thevilfer/tap/better-tg-cli # standalone binary, macOS and Linux
12
46
  npm install -g better-tg-cli # Node >= 20
13
47
  ```
14
48
 
15
- Both install the `telegram` command. To use it as an agent skill (Claude Code, Codex), clone the
16
- repo into the skills folder. That folder is the skill (`SKILL.md` + `reference.md`):
17
-
18
- ```bash
19
- git clone https://github.com/TheVilfer/better-tg-cli.git ~/.agents/skills/telegram
20
- ln -s ~/.agents/skills/telegram ~/.claude/skills/telegram
21
- ```
22
-
23
- To build from source you need Node >= 20 and [Bun](https://bun.sh) (the bundler):
24
- `npm install && npm run build && npm install -g .` (or `./install.sh`).
25
-
26
- ### Updating
27
-
28
- `telegram update` updates the way it was installed: `brew upgrade`, `npm install -g better-tg-cli@latest`,
29
- or `git pull --ff-only` + build for a checkout. `telegram update --check` only reports.
30
- On a terminal the CLI checks npm once a day in the background and prints a one-line notice when a
31
- new version is out; piped output (agents) never gets it. `TG_NO_UPDATE_CHECK=1` turns it off.
32
-
33
- Hacking on the CLI: see [DEVELOPMENT.md](DEVELOPMENT.md) (run from source, isolated dev profile, debugger).
34
-
35
- Do **not** install `@skillhq/telegram`. That is the old upstream build on GramJS (layer 198), and
36
- bot replies show up as `(no text)`.
37
-
38
- **Linux note:** secrets go to the macOS Keychain or to 1Password (`telegram auth --op-vault`).
39
- Without either, the session is kept in `~/.config/tg/config.json5` (mode 0600), and write
40
- commands stay disabled.
41
-
42
- ## Authentication
43
-
44
- **Your own API keys (default, for everyone):**
45
- 1. Go to https://my.telegram.org/apps and log in with your phone number
46
- 2. Create an application and copy its `api_id` and `api_hash`
47
- 3. Run `telegram auth` and enter them, then your phone, the login code and your 2FA password
48
-
49
- **With an invite.** If the maintainer gave you an invite token, you don't need your own keys:
50
-
51
- ```bash
52
- telegram auth --invite # paste the token when asked (or: TG_INVITE=... / --invite -)
53
- ```
54
-
55
- The invite service (`broker/`) hands out the app's keys once for your login. The `api_hash` is
56
- not stored on your machine afterwards, only the `api_id` and your session. Invites are personal,
57
- limited to a few logins, and can be revoked.
58
-
59
- Your session is stored in the macOS Keychain (service `tg-cli`), or in 1Password with
60
- `--op-vault`. `telegram logout` removes it.
61
-
62
- ## Commands
63
-
64
- ### Auth & Status
65
-
66
- ```bash
67
- telegram whoami # Show logged-in account
68
- telegram check # Verify session/credentials
69
- ```
70
-
71
- ### Reading
72
-
73
- ```bash
74
- telegram chats # List all chats
75
- telegram chats --type group # Filter by type (user, group, supergroup, channel)
76
- telegram read "MetaDAO Community" -n 50 # Read last 50 messages
77
- telegram read "MetaDAO" --since "1h" # Messages from last hour
78
- telegram read @username -n 20 # Read DM with user
79
- telegram search "futarchy" --chat "MetaDAO" # Search within chat
80
- telegram search "futarchy" --all # Search all chats
81
- telegram inbox # Unread messages summary
82
- ```
83
-
84
- ### Writing
85
-
86
- ```bash
87
- telegram send @username "Hello" # Send DM
88
- telegram send "GroupName" "Hello everyone" # Send to group
89
- telegram reply "ChatName" 12345 "Response" # Reply to message ID
90
- ```
91
-
92
- ### Bot Buttons
49
+ `telegram update` upgrades an existing install, whichever of these you used. On a terminal the CLI
50
+ checks for new versions once a day. Agents and pipes never see that notice, and
51
+ `TG_NO_UPDATE_CHECK=1` turns it off.
93
52
 
94
- ```bash
95
- telegram buttons @SomeBot 12345 # List buttons on a message
96
- telegram click @SomeBot 12345 2 # Press button #2 (by index)
97
- telegram click @SomeBot 12345 "Settings" # Press by label
98
- telegram click @SomeBot 12345 1 --json # Machine-readable outcome
99
- ```
53
+ Do **not** install `@skillhq/telegram`. It is the old upstream build on GramJS (layer 198).
100
54
 
101
- Buttons show up inline in `read`/`inbox`/`search` output. After a callback
102
- press, `click` re-reads the message so you see the bot's edited reply and its
103
- new buttons — enough to navigate a bot's menus step by step. `click` needs
104
- write access enabled.
105
-
106
- ### Reactions, Forwarding & Pinning
107
-
108
- ```bash
109
- telegram react "ChatName" 12345 👍 # React with an emoji (--big, --remove)
110
- telegram reactions "ChatName" 12345 # List who reacted
111
- telegram forward "FromChat" 12345 "ToChat" # Forward message(s); comma-separate IDs
112
- telegram pin "ChatName" 12345 # Pin (--notify to alert members)
113
- telegram unpin "ChatName" 12345 # Unpin one; omit ID to unpin all
114
- ```
55
+ ### As an agent skill
115
56
 
116
- ### Editing, Deleting, Polls & Formatting
57
+ The repo itself is the skill (`SKILL.md` + `reference.md`):
117
58
 
118
59
  ```bash
119
- telegram edit "Chat" 12345 "new text" # Edit your own message
120
- telegram delete "Chat" 12,13 --just-me # Delete (revoke by default)
121
- telegram mark-read "Chat" # Clear unread badge
122
- telegram pinned "Chat" # List pinned messages
123
- telegram send @user "<b>hi</b>" --html # HTML/Markdown formatting (--markdown)
124
- telegram send @user "later" --schedule 2h # Schedule a message
125
- telegram poll "Chat" "Q?" A B C # Send a poll
126
- telegram vote "Chat" 12345 2 # Vote for option #2
127
- ```
128
-
129
- ### Real-time, Chats & Profile
130
-
131
- ```bash
132
- telegram watch "Chat" -t 30 # Stream new messages (timeout/limit required)
133
- telegram join @channel # Join (also invite links); leave/create-group/create-channel
134
- telegram archive "Chat" # Archive / unarchive; invite-link "Chat"
135
- telegram block @user # block/unblock; add-contact/del-contact
136
- telegram set-name "First" "Last" # set-bio / set-username / set-avatar
137
- telegram avatar @user # Download avatar; inline @gif "cat"; stories @user
138
- ```
139
-
140
- All of the above except reads (`reactions`, `pinned`, `watch`, `avatar`, `inline`, `stories`) are write operations and need write access enabled.
141
-
142
- ### Contacts & Groups
143
-
144
- ```bash
145
- telegram contact @username # Get contact info
146
- telegram members "GroupName" # List group members
147
- telegram admins "GroupName" # List admins only
148
- telegram groups # List all groups
149
- telegram groups --admin # Groups where you're admin
150
- telegram kick "GroupName" @username # Remove a user from a group
151
- telegram promote "GroupName" @username # Promote a member to admin
152
- telegram transfer-owner "GroupName" @username # Transfer ownership (prompts for 2FA password)
60
+ git clone https://github.com/TheVilfer/better-tg-cli.git ~/.agents/skills/telegram
61
+ ln -s ~/.agents/skills/telegram ~/.claude/skills/telegram
153
62
  ```
154
63
 
155
- > `transfer-owner` is irreversible and requires two-step verification on your account.
156
- > It works on supergroups/channels only, prompts for your 2FA password securely, and asks
157
- > you to retype the group name to confirm (`-y` skips the confirmation).
158
-
159
- ### Muting
64
+ ## Log in
160
65
 
161
- ```bash
162
- telegram mute "ChatName" # Mute forever
163
- telegram mute "ChatName" -d 1h # Mute for 1 hour
164
- telegram mute @username -d 8h # Mute DM for 8 hours
165
- telegram unmute "ChatName" # Unmute
166
- ```
66
+ **With your own API keys** (the default):
67
+ 1. Open https://my.telegram.org/apps, create an application, and copy its `api_id` and `api_hash`.
68
+ 2. Run `telegram auth` and enter them, then your phone number, the login code and your 2FA password.
167
69
 
168
- ### Folders
70
+ **With an invite.** If the maintainer gave you an invite token, you don't need your own keys.
71
+ Run `telegram auth --invite` and paste the token, or pass it as `TG_INVITE=…` or `--invite -`. The
72
+ invite service (`broker/`) hands out the app's keys once, for this login only. The `api_hash` is not
73
+ kept on your machine. Invites are personal, allow a limited number of logins, and can be revoked.
169
74
 
170
- ```bash
171
- telegram folders # List all folders
172
- telegram folder "Work" # Show chats in folder
173
- telegram folder-add "Work" "ProjectChat" # Add chat to folder
174
- telegram folder-remove "Work" "ProjectChat" # Remove chat from folder
175
- ```
75
+ The session is stored in the macOS Keychain (service `tg-cli`), or in 1Password with
76
+ `--op-vault <vault>`. `telegram logout` removes it. On Linux without 1Password, the session is kept
77
+ in `~/.config/tg/config.json5` (mode 0600) and write commands stay disabled.
176
78
 
177
- ### Utilities
79
+ ## Usage
178
80
 
179
81
  ```bash
180
- telegram sync --days 7 # Sync last 7 days to markdown
181
- telegram sync --chat "MetaDAO" --days 30 # Sync specific chat
182
- ```
183
-
184
- ## Output Formats
82
+ telegram chats --type channel # one line per chat, ID first
83
+ telegram read "Chat" --since 1h # exact range, newest first (--asc to flip)
84
+ telegram read @channel --thread 123 # comments under a post
85
+ telegram search "invoice" --chat "Work" --type document
86
+ telegram get "Chat" 812 813 # exact messages by ID
87
+ telegram download "Chat" 812 # save the attached file
88
+ telegram sync --chat "Chat" --output ./export --resume # incremental markdown export
185
89
 
186
- All read commands support multiple output formats:
187
-
188
- ```bash
189
- telegram chats --json # JSON (for scripts/AI)
190
- telegram read "Chat" --markdown # Markdown format
191
- telegram inbox --plain # Plain text (no colors)
90
+ telegram write-access on --for 1h # a human confirms this
91
+ printf '%s' "$text" | telegram send @alice - # text from stdin, no quoting problems
92
+ telegram reply "Chat" 812 "on it" --silent
93
+ telegram click @SomeBot 4410 "Settings" # press an inline button
192
94
  ```
193
95
 
194
- ## Configuration
195
-
196
- Configuration is stored in `~/.config/tg/`:
197
- - `config.json` - API credentials and session
198
- - Session data is encrypted and stored securely
96
+ Read commands take `--json`, and some also take `--markdown`. See all commands with
97
+ `telegram help-all`. [reference.md](reference.md) covers the behaviour that the flag list can't
98
+ explain: output shapes, threads, bot buttons, admin commands and troubleshooting.
199
99
 
200
100
  ## Development
201
101
 
202
- ```bash
203
- npm install
204
- npm run build
205
- npm run dev # Watch mode
206
- ```
102
+ [DEVELOPMENT.md](DEVELOPMENT.md) covers:
103
+ - running from source (`scripts/tg-dev`);
104
+ - isolated dev profiles (`TG_PROFILE`) that never touch your real session;
105
+ - Telegram test servers;
106
+ - editor debugging and tests.
107
+
108
+ Releases are cut by `scripts/release.sh patch|minor|major`. A tag builds the binaries and
109
+ publishes to GitHub Releases, npm (trusted publishing with provenance) and the Homebrew tap. See
110
+ [CONTRIBUTING.md](CONTRIBUTING.md).
207
111
 
208
112
  ## License
209
113
 
210
- MIT — see [LICENSE](LICENSE). Based on [skillhq/telegram](https://github.com/skillhq/telegram)
211
- by Derek Rein. Not affiliated with or endorsed by Telegram; "Telegram" is a trademark of its owner.
114
+ MIT, see [LICENSE](LICENSE). Based on [skillhq/telegram](https://github.com/skillhq/telegram) by
115
+ Derek Rein. Not affiliated with or endorsed by Telegram; "Telegram" is a trademark of its owner.
116
+ Use it in line with the [Telegram API Terms of Service](https://core.telegram.org/api/terms).
package/SKILL.md CHANGED
@@ -11,7 +11,7 @@ description: Full-featured Telegram CLI on the user's own account — read, sear
11
11
 
12
12
  ## Rules
13
13
 
14
- - **Chat identifiers:** `me` means Saved Messages. A numeric ID is matched exactly (use the ID shown first in `chats`/`inbox`/`search` output). `@username` resolves exactly. Any other text matches chat titles by **substring**. For writes, use an ID or @username.
14
+ - **Chat identifiers:** `me` means Saved Messages. A numeric ID is matched exactly (use the ID shown first in `chats`/`inbox`/`search` output). `@username` resolves exactly. For reads, any other text matches chat titles by **substring**. Writes accept only an exact, unique title and otherwise refuse, listing candidate IDs. Retry with the ID.
15
15
  - **Writes are off by default.** A write fails with "Write access is disabled". Only the user can turn writes on. `telegram write-access on --for 1h` shows them a confirmation dialog, which you cannot click yourself. Ask first, run it, and wait for their click. Get explicit approval for every message to other people and show the final text first.
16
16
  - **Save tokens:**
17
17
  - Start with `inbox --unmuted`, `chats -q <name>` or `search`, not a full `read`.