better-tg-cli 0.18.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,209 +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`).
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.
25
52
 
26
- ### Updating
53
+ Do **not** install `@skillhq/telegram`. It is the old upstream build on GramJS (layer 198).
27
54
 
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.
55
+ ### As an agent skill
32
56
 
33
- Do **not** install `@skillhq/telegram`. That is the old upstream build on GramJS (layer 198), and
34
- bot replies show up as `(no text)`.
35
-
36
- **Linux note:** secrets go to the macOS Keychain or to 1Password (`telegram auth --op-vault`).
37
- Without either, the session is kept in `~/.config/tg/config.json5` (mode 0600), and write
38
- commands stay disabled.
39
-
40
- ## Authentication
41
-
42
- **Your own API keys (default, for everyone):**
43
- 1. Go to https://my.telegram.org/apps and log in with your phone number
44
- 2. Create an application and copy its `api_id` and `api_hash`
45
- 3. Run `telegram auth` and enter them, then your phone, the login code and your 2FA password
46
-
47
- **With an invite.** If the maintainer gave you an invite token, you don't need your own keys:
57
+ The repo itself is the skill (`SKILL.md` + `reference.md`):
48
58
 
49
59
  ```bash
50
- telegram auth --invite # paste the token when asked (or: TG_INVITE=... / --invite -)
51
- ```
52
-
53
- The invite service (`broker/`) hands out the app's keys once for your login. The `api_hash` is
54
- not stored on your machine afterwards, only the `api_id` and your session. Invites are personal,
55
- limited to a few logins, and can be revoked.
56
-
57
- Your session is stored in the macOS Keychain (service `tg-cli`), or in 1Password with
58
- `--op-vault`. `telegram logout` removes it.
59
-
60
- ## Commands
61
-
62
- ### Auth & Status
63
-
64
- ```bash
65
- telegram whoami # Show logged-in account
66
- telegram check # Verify session/credentials
67
- ```
68
-
69
- ### Reading
70
-
71
- ```bash
72
- telegram chats # List all chats
73
- telegram chats --type group # Filter by type (user, group, supergroup, channel)
74
- telegram read "MetaDAO Community" -n 50 # Read last 50 messages
75
- telegram read "MetaDAO" --since "1h" # Messages from last hour
76
- telegram read @username -n 20 # Read DM with user
77
- telegram search "futarchy" --chat "MetaDAO" # Search within chat
78
- telegram search "futarchy" --all # Search all chats
79
- telegram inbox # Unread messages summary
80
- ```
81
-
82
- ### Writing
83
-
84
- ```bash
85
- telegram send @username "Hello" # Send DM
86
- telegram send "GroupName" "Hello everyone" # Send to group
87
- telegram reply "ChatName" 12345 "Response" # Reply to message ID
88
- ```
89
-
90
- ### Bot Buttons
91
-
92
- ```bash
93
- telegram buttons @SomeBot 12345 # List buttons on a message
94
- telegram click @SomeBot 12345 2 # Press button #2 (by index)
95
- telegram click @SomeBot 12345 "Settings" # Press by label
96
- telegram click @SomeBot 12345 1 --json # Machine-readable outcome
97
- ```
98
-
99
- Buttons show up inline in `read`/`inbox`/`search` output. After a callback
100
- press, `click` re-reads the message so you see the bot's edited reply and its
101
- new buttons — enough to navigate a bot's menus step by step. `click` needs
102
- write access enabled.
103
-
104
- ### Reactions, Forwarding & Pinning
105
-
106
- ```bash
107
- telegram react "ChatName" 12345 👍 # React with an emoji (--big, --remove)
108
- telegram reactions "ChatName" 12345 # List who reacted
109
- telegram forward "FromChat" 12345 "ToChat" # Forward message(s); comma-separate IDs
110
- telegram pin "ChatName" 12345 # Pin (--notify to alert members)
111
- telegram unpin "ChatName" 12345 # Unpin one; omit ID to unpin all
112
- ```
113
-
114
- ### Editing, Deleting, Polls & Formatting
115
-
116
- ```bash
117
- telegram edit "Chat" 12345 "new text" # Edit your own message
118
- telegram delete "Chat" 12,13 --just-me # Delete (revoke by default)
119
- telegram mark-read "Chat" # Clear unread badge
120
- telegram pinned "Chat" # List pinned messages
121
- telegram send @user "<b>hi</b>" --html # HTML/Markdown formatting (--markdown)
122
- telegram send @user "later" --schedule 2h # Schedule a message
123
- telegram poll "Chat" "Q?" A B C # Send a poll
124
- telegram vote "Chat" 12345 2 # Vote for option #2
125
- ```
126
-
127
- ### Real-time, Chats & Profile
128
-
129
- ```bash
130
- telegram watch "Chat" -t 30 # Stream new messages (timeout/limit required)
131
- telegram join @channel # Join (also invite links); leave/create-group/create-channel
132
- telegram archive "Chat" # Archive / unarchive; invite-link "Chat"
133
- telegram block @user # block/unblock; add-contact/del-contact
134
- telegram set-name "First" "Last" # set-bio / set-username / set-avatar
135
- telegram avatar @user # Download avatar; inline @gif "cat"; stories @user
136
- ```
137
-
138
- All of the above except reads (`reactions`, `pinned`, `watch`, `avatar`, `inline`, `stories`) are write operations and need write access enabled.
139
-
140
- ### Contacts & Groups
141
-
142
- ```bash
143
- telegram contact @username # Get contact info
144
- telegram members "GroupName" # List group members
145
- telegram admins "GroupName" # List admins only
146
- telegram groups # List all groups
147
- telegram groups --admin # Groups where you're admin
148
- telegram kick "GroupName" @username # Remove a user from a group
149
- telegram promote "GroupName" @username # Promote a member to admin
150
- 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
151
62
  ```
152
63
 
153
- > `transfer-owner` is irreversible and requires two-step verification on your account.
154
- > It works on supergroups/channels only, prompts for your 2FA password securely, and asks
155
- > you to retype the group name to confirm (`-y` skips the confirmation).
156
-
157
- ### Muting
64
+ ## Log in
158
65
 
159
- ```bash
160
- telegram mute "ChatName" # Mute forever
161
- telegram mute "ChatName" -d 1h # Mute for 1 hour
162
- telegram mute @username -d 8h # Mute DM for 8 hours
163
- telegram unmute "ChatName" # Unmute
164
- ```
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.
165
69
 
166
- ### 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.
167
74
 
168
- ```bash
169
- telegram folders # List all folders
170
- telegram folder "Work" # Show chats in folder
171
- telegram folder-add "Work" "ProjectChat" # Add chat to folder
172
- telegram folder-remove "Work" "ProjectChat" # Remove chat from folder
173
- ```
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.
174
78
 
175
- ### Utilities
79
+ ## Usage
176
80
 
177
81
  ```bash
178
- telegram sync --days 7 # Sync last 7 days to markdown
179
- telegram sync --chat "MetaDAO" --days 30 # Sync specific chat
180
- ```
181
-
182
- ## 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
183
89
 
184
- All read commands support multiple output formats:
185
-
186
- ```bash
187
- telegram chats --json # JSON (for scripts/AI)
188
- telegram read "Chat" --markdown # Markdown format
189
- 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
190
94
  ```
191
95
 
192
- ## Configuration
193
-
194
- Configuration is stored in `~/.config/tg/`:
195
- - `config.json` - API credentials and session
196
- - 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.
197
99
 
198
100
  ## Development
199
101
 
200
- ```bash
201
- npm install
202
- npm run build
203
- npm run dev # Watch mode
204
- ```
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).
205
111
 
206
112
  ## License
207
113
 
208
- MIT — see [LICENSE](LICENSE). Based on [skillhq/telegram](https://github.com/skillhq/telegram)
209
- 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`.