better-tg-cli 0.17.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/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Derek Rein (original skillhq/telegram)
4
+ Copyright (c) 2026 Sergei Polin (better-tg-cli modifications)
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,202 @@
1
+ # better-tg-cli
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
12
+ npm install -g better-tg-cli # Node >= 20
13
+ ```
14
+
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
+ Do **not** install `@skillhq/telegram`. That is the old upstream build on GramJS (layer 198), and
27
+ bot replies show up as `(no text)`.
28
+
29
+ **Linux note:** secrets go to the macOS Keychain or to 1Password (`telegram auth --op-vault`).
30
+ Without either, the session is kept in `~/.config/tg/config.json5` (mode 0600), and write
31
+ commands stay disabled.
32
+
33
+ ## Authentication
34
+
35
+ **Your own API keys (default, for everyone):**
36
+ 1. Go to https://my.telegram.org/apps and log in with your phone number
37
+ 2. Create an application and copy its `api_id` and `api_hash`
38
+ 3. Run `telegram auth` and enter them, then your phone, the login code and your 2FA password
39
+
40
+ **With an invite.** If the maintainer gave you an invite token, you don't need your own keys:
41
+
42
+ ```bash
43
+ telegram auth --invite # paste the token when asked (or: TG_INVITE=... / --invite -)
44
+ ```
45
+
46
+ The invite service (`broker/`) hands out the app's keys once for your login. The `api_hash` is
47
+ not stored on your machine afterwards, only the `api_id` and your session. Invites are personal,
48
+ limited to a few logins, and can be revoked.
49
+
50
+ Your session is stored in the macOS Keychain (service `tg-cli`), or in 1Password with
51
+ `--op-vault`. `telegram logout` removes it.
52
+
53
+ ## Commands
54
+
55
+ ### Auth & Status
56
+
57
+ ```bash
58
+ telegram whoami # Show logged-in account
59
+ telegram check # Verify session/credentials
60
+ ```
61
+
62
+ ### Reading
63
+
64
+ ```bash
65
+ telegram chats # List all chats
66
+ telegram chats --type group # Filter by type (user, group, supergroup, channel)
67
+ telegram read "MetaDAO Community" -n 50 # Read last 50 messages
68
+ telegram read "MetaDAO" --since "1h" # Messages from last hour
69
+ telegram read @username -n 20 # Read DM with user
70
+ telegram search "futarchy" --chat "MetaDAO" # Search within chat
71
+ telegram search "futarchy" --all # Search all chats
72
+ telegram inbox # Unread messages summary
73
+ ```
74
+
75
+ ### Writing
76
+
77
+ ```bash
78
+ telegram send @username "Hello" # Send DM
79
+ telegram send "GroupName" "Hello everyone" # Send to group
80
+ telegram reply "ChatName" 12345 "Response" # Reply to message ID
81
+ ```
82
+
83
+ ### Bot Buttons
84
+
85
+ ```bash
86
+ telegram buttons @SomeBot 12345 # List buttons on a message
87
+ telegram click @SomeBot 12345 2 # Press button #2 (by index)
88
+ telegram click @SomeBot 12345 "Settings" # Press by label
89
+ telegram click @SomeBot 12345 1 --json # Machine-readable outcome
90
+ ```
91
+
92
+ Buttons show up inline in `read`/`inbox`/`search` output. After a callback
93
+ press, `click` re-reads the message so you see the bot's edited reply and its
94
+ new buttons — enough to navigate a bot's menus step by step. `click` needs
95
+ write access enabled.
96
+
97
+ ### Reactions, Forwarding & Pinning
98
+
99
+ ```bash
100
+ telegram react "ChatName" 12345 👍 # React with an emoji (--big, --remove)
101
+ telegram reactions "ChatName" 12345 # List who reacted
102
+ telegram forward "FromChat" 12345 "ToChat" # Forward message(s); comma-separate IDs
103
+ telegram pin "ChatName" 12345 # Pin (--notify to alert members)
104
+ telegram unpin "ChatName" 12345 # Unpin one; omit ID to unpin all
105
+ ```
106
+
107
+ ### Editing, Deleting, Polls & Formatting
108
+
109
+ ```bash
110
+ telegram edit "Chat" 12345 "new text" # Edit your own message
111
+ telegram delete "Chat" 12,13 --just-me # Delete (revoke by default)
112
+ telegram mark-read "Chat" # Clear unread badge
113
+ telegram pinned "Chat" # List pinned messages
114
+ telegram send @user "<b>hi</b>" --html # HTML/Markdown formatting (--markdown)
115
+ telegram send @user "later" --schedule 2h # Schedule a message
116
+ telegram poll "Chat" "Q?" A B C # Send a poll
117
+ telegram vote "Chat" 12345 2 # Vote for option #2
118
+ ```
119
+
120
+ ### Real-time, Chats & Profile
121
+
122
+ ```bash
123
+ telegram watch "Chat" -t 30 # Stream new messages (timeout/limit required)
124
+ telegram join @channel # Join (also invite links); leave/create-group/create-channel
125
+ telegram archive "Chat" # Archive / unarchive; invite-link "Chat"
126
+ telegram block @user # block/unblock; add-contact/del-contact
127
+ telegram set-name "First" "Last" # set-bio / set-username / set-avatar
128
+ telegram avatar @user # Download avatar; inline @gif "cat"; stories @user
129
+ ```
130
+
131
+ All of the above except reads (`reactions`, `pinned`, `watch`, `avatar`, `inline`, `stories`) are write operations and need write access enabled.
132
+
133
+ ### Contacts & Groups
134
+
135
+ ```bash
136
+ telegram contact @username # Get contact info
137
+ telegram members "GroupName" # List group members
138
+ telegram admins "GroupName" # List admins only
139
+ telegram groups # List all groups
140
+ telegram groups --admin # Groups where you're admin
141
+ telegram kick "GroupName" @username # Remove a user from a group
142
+ telegram promote "GroupName" @username # Promote a member to admin
143
+ telegram transfer-owner "GroupName" @username # Transfer ownership (prompts for 2FA password)
144
+ ```
145
+
146
+ > `transfer-owner` is irreversible and requires two-step verification on your account.
147
+ > It works on supergroups/channels only, prompts for your 2FA password securely, and asks
148
+ > you to retype the group name to confirm (`-y` skips the confirmation).
149
+
150
+ ### Muting
151
+
152
+ ```bash
153
+ telegram mute "ChatName" # Mute forever
154
+ telegram mute "ChatName" -d 1h # Mute for 1 hour
155
+ telegram mute @username -d 8h # Mute DM for 8 hours
156
+ telegram unmute "ChatName" # Unmute
157
+ ```
158
+
159
+ ### Folders
160
+
161
+ ```bash
162
+ telegram folders # List all folders
163
+ telegram folder "Work" # Show chats in folder
164
+ telegram folder-add "Work" "ProjectChat" # Add chat to folder
165
+ telegram folder-remove "Work" "ProjectChat" # Remove chat from folder
166
+ ```
167
+
168
+ ### Utilities
169
+
170
+ ```bash
171
+ telegram sync --days 7 # Sync last 7 days to markdown
172
+ telegram sync --chat "MetaDAO" --days 30 # Sync specific chat
173
+ ```
174
+
175
+ ## Output Formats
176
+
177
+ All read commands support multiple output formats:
178
+
179
+ ```bash
180
+ telegram chats --json # JSON (for scripts/AI)
181
+ telegram read "Chat" --markdown # Markdown format
182
+ telegram inbox --plain # Plain text (no colors)
183
+ ```
184
+
185
+ ## Configuration
186
+
187
+ Configuration is stored in `~/.config/tg/`:
188
+ - `config.json` - API credentials and session
189
+ - Session data is encrypted and stored securely
190
+
191
+ ## Development
192
+
193
+ ```bash
194
+ npm install
195
+ npm run build
196
+ npm run dev # Watch mode
197
+ ```
198
+
199
+ ## License
200
+
201
+ MIT — see [LICENSE](LICENSE). Based on [skillhq/telegram](https://github.com/skillhq/telegram)
202
+ by Derek Rein. Not affiliated with or endorsed by Telegram; "Telegram" is a trademark of its owner.
package/SKILL.md ADDED
@@ -0,0 +1,56 @@
1
+ ---
2
+ name: telegram
3
+ description: Full-featured Telegram CLI on the user's own account — read, search, send, edit and delete messages, read comments/threads and forum topics, manage groups and channels, press bot buttons, react, forward, pin, poll/vote, watch live messages, manage contacts and your own profile, and sync history. Use when the user asks about Telegram messages, wants to check inbox or unread, search chats, send/edit/delete messages, format messages, schedule a message, mute/unmute chats, kick/block users, press bot buttons or navigate bot menus, react with emoji, forward or pin messages, create polls or vote, join/leave/create/archive chats, get invite or message links, watch for new messages in real time, query inline bots, read stories, download media or avatars, manage contacts, or update their own name/bio/username/avatar. Also «телеграм», «тг», «телега», «проверь телеграм», «что в тг», «напиши в телеграм», «прочитай чат», «найди в телеге».
4
+ ---
5
+
6
+ # Telegram CLI
7
+
8
+ `telegram <command>` runs on the user's own account (MTProto, not a bot).
9
+
10
+ **Before using an unfamiliar flag, run `telegram help-all -g <word>`.** It lists every command and flag, generated from the code, so it is always current. For behaviour details (threads, bot buttons, sync, JSON shapes, errors), read `reference.md` next to this file.
11
+
12
+ ## Rules
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.
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
+ - **Save tokens:**
17
+ - Start with `inbox --unmuted`, `chats -q <name>` or `search`, not a full `read`.
18
+ - Add `--max-text 200` when skimming.
19
+ - Use `get <chat> <id>` to fetch exactly what you need.
20
+ - Plain output off a TTY is already compact, one line per item with the ID first. Use `--json` only when you parse with jq.
21
+ - **Long or multi-line text:** pass `-` and pipe it through stdin (`printf '%s' "$text" | telegram send <chat> -`). This avoids quoting bugs.
22
+
23
+ ## Core commands
24
+
25
+ ```bash
26
+ telegram inbox --unmuted -n 20 # unread chats, most unread first (IDs first)
27
+ telegram chats -q "name" # find a chat's ID; --unread, --type channel, --archived
28
+ telegram read <chat> -n 20 # newest first; --asc, --since 1d, --until 2026-09-01
29
+ telegram read <chat> --unread # only what the user hasn't read yet
30
+ telegram read <chat> --from @user # one sender; --before/--after <msgId> for paging
31
+ telegram read <chat> --thread <postId> # comments under a post; posts with comments show 💬N in read output
32
+ telegram topics <forum> ; telegram read <forum> --topic <id>
33
+ telegram get <chat> <id> [id...] # exact messages
34
+ telegram search "query" -n 20 # global; --chat <c> [--from @u], --type photo|url|document|voice|mentions, --since 7d
35
+ telegram info <chat> # members, about, linked comments chat, forum?
36
+ telegram members <group> -q name ; telegram contacts -q name
37
+ telegram send <chat> "text" # --reply-to <id>, --topic <id>, --html, --silent, --schedule 2h
38
+ telegram reply <chat> <msgId> "text"
39
+ telegram send-file <chat> ./file.pdf -c "caption"
40
+ telegram edit <chat> <msgId> "new text" ; telegram delete <chat> <id,id>
41
+ telegram click <bot> <msgId> <index|label> # press a bot button; `read` shows [index] label (type)
42
+ telegram react <chat> <msgId> 👍 ; telegram forward <from> <ids> <to> ; telegram pin <chat> <id>
43
+ telegram download <chat> <msgId> -o ./dir
44
+ telegram link <chat> <msgId> # t.me link (channels/supergroups)
45
+ telegram watch [chat] -t 60 -n 10 --json # live stream; always bound it with -t/-n
46
+ telegram sync --chat <c> --output ./dir --resume # markdown export, incremental
47
+ telegram mark-read <chat> ; telegram mute <chat> -d 8h
48
+ ```
49
+
50
+ ## JSON shapes (with `--json`)
51
+
52
+ `chats`, `contacts` and `members` return an array. `read` and `get` return `{chatTitle, messages[]}`. `search` returns an array of `{messages[]}`, and global hits carry `chatId` and `chatTitle`. `inbox` returns `{totalUnread, chatsWithUnread, chats[]}`; it skips archived chats unless you pass `--include-archived`, and the totals cover all chats even when `-n` cuts the list. Chat objects have `id`, `title`, `type`, `username`, `unreadCount`, `muted`, `archived` and `lastMessage`. Messages have `id`, `date`, `sender`, `senderId`, `text`, `replyToMsgId`, `isOutgoing`, `media`, `buttons` and `replies` (the comment count). Empty fields are omitted.
53
+
54
+ ## If `telegram` is missing
55
+
56
+ Reinstall with `brew install thevilfer/tap/better-tg-cli` or `npm install -g better-tg-cli`, or from this folder with `npm install && npm run build && npm install -g .` (needs Bun). **Never** install `@skillhq/telegram` from npm or update this skill with the skills CLI: that is an old GramJS build, and bot replies come back as `(no text)`.