@will-17173/telegram-cli 0.1.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 +675 -0
- package/README.md +264 -0
- package/README.zh-CN.md +264 -0
- package/dist/account/account-context.js +22 -0
- package/dist/account/account-context.js.map +1 -0
- package/dist/account/account-presets.js +22 -0
- package/dist/account/account-presets.js.map +1 -0
- package/dist/account/account-store.js +225 -0
- package/dist/account/account-store.js.map +1 -0
- package/dist/cli/app.js +21 -0
- package/dist/cli/app.js.map +1 -0
- package/dist/cli/output.js +39 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/commands/account-options.js +55 -0
- package/dist/commands/account-options.js.map +1 -0
- package/dist/commands/account.js +449 -0
- package/dist/commands/account.js.map +1 -0
- package/dist/commands/config.js +63 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/data.js +52 -0
- package/dist/commands/data.js.map +1 -0
- package/dist/commands/query.js +116 -0
- package/dist/commands/query.js.map +1 -0
- package/dist/commands/telegram.js +423 -0
- package/dist/commands/telegram.js.map +1 -0
- package/dist/commands/types.js +12 -0
- package/dist/commands/types.js.map +1 -0
- package/dist/config/credential-store.js +82 -0
- package/dist/config/credential-store.js.map +1 -0
- package/dist/config/env.js +78 -0
- package/dist/config/env.js.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/presenters/human.js +218 -0
- package/dist/presenters/human.js.map +1 -0
- package/dist/presenters/ink/DetailView.js +14 -0
- package/dist/presenters/ink/DetailView.js.map +1 -0
- package/dist/presenters/ink/TableView.js +9 -0
- package/dist/presenters/ink/TableView.js.map +1 -0
- package/dist/presenters/ink/TimelineView.js +34 -0
- package/dist/presenters/ink/TimelineView.js.map +1 -0
- package/dist/presenters/ink/display-width.js +149 -0
- package/dist/presenters/ink/display-width.js.map +1 -0
- package/dist/presenters/ink/image-preview.js +47 -0
- package/dist/presenters/ink/image-preview.js.map +1 -0
- package/dist/presenters/ink/listen-scroll.js +37 -0
- package/dist/presenters/ink/listen-scroll.js.map +1 -0
- package/dist/presenters/ink/listen-scrollbar.js +49 -0
- package/dist/presenters/ink/listen-scrollbar.js.map +1 -0
- package/dist/presenters/ink/listen.js +542 -0
- package/dist/presenters/ink/listen.js.map +1 -0
- package/dist/presenters/ink/mouse-scroll.js +55 -0
- package/dist/presenters/ink/mouse-scroll.js.map +1 -0
- package/dist/presenters/ink/render.js +45 -0
- package/dist/presenters/ink/render.js.map +1 -0
- package/dist/presenters/listen-message.js +267 -0
- package/dist/presenters/listen-message.js.map +1 -0
- package/dist/presenters/structured.js +30 -0
- package/dist/presenters/structured.js.map +1 -0
- package/dist/services/attachment-download.js +21 -0
- package/dist/services/attachment-download.js.map +1 -0
- package/dist/services/data-service.js +76 -0
- package/dist/services/data-service.js.map +1 -0
- package/dist/services/listen-album-aggregator.js +72 -0
- package/dist/services/listen-album-aggregator.js.map +1 -0
- package/dist/services/message-service.js +102 -0
- package/dist/services/message-service.js.map +1 -0
- package/dist/services/query-service.js +116 -0
- package/dist/services/query-service.js.map +1 -0
- package/dist/services/sync-service.js +134 -0
- package/dist/services/sync-service.js.map +1 -0
- package/dist/storage/chat-resolver.js +9 -0
- package/dist/storage/chat-resolver.js.map +1 -0
- package/dist/storage/message-db.js +246 -0
- package/dist/storage/message-db.js.map +1 -0
- package/dist/telegram/client-factory.js +27 -0
- package/dist/telegram/client-factory.js.map +1 -0
- package/dist/telegram/mtcute-client.js +324 -0
- package/dist/telegram/mtcute-client.js.map +1 -0
- package/dist/telegram/types.js +2 -0
- package/dist/telegram/types.js.map +1 -0
- package/package.json +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# Telegram CLI
|
|
2
|
+
|
|
3
|
+
[简体中文](README.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
A TypeScript command-line client for syncing Telegram chats, listening to live messages, searching locally stored messages, and managing Telegram tasks from the terminal.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- Sign in to Telegram and inspect the current account or available chats.
|
|
10
|
+
- Manage multiple Telegram accounts with isolated sessions and message databases.
|
|
11
|
+
- Fetch chat history into a local SQLite database for fast, offline search.
|
|
12
|
+
- Sync one chat incrementally or sync many chats with a single command.
|
|
13
|
+
- Listen for new messages in real time, with optional attachment summaries.
|
|
14
|
+
- Download attachments from channels that restrict content saving.
|
|
15
|
+
- Search, filter, summarize, and export locally stored messages.
|
|
16
|
+
- Send, edit, and delete messages from the command line.
|
|
17
|
+
- Use human-readable output or structured JSON/YAML where supported.
|
|
18
|
+
|
|
19
|
+
## Built for AI agents
|
|
20
|
+
|
|
21
|
+
Telegram CLI gives AI agents a command-based interface to Telegram and locally synced messages. After a human authenticates an account with `tg account add`, an agent can run online and local commands without browser automation.
|
|
22
|
+
|
|
23
|
+
The CLI supports agent workflows through these interfaces:
|
|
24
|
+
|
|
25
|
+
- JSON and YAML output gives agents structured data instead of terminal-formatted text.
|
|
26
|
+
- Nonzero exit codes and structured error codes let agents detect and handle failures.
|
|
27
|
+
- `--account <name>` selects an explicit account without changing the current account.
|
|
28
|
+
- Local search and analysis commands let agents inspect synced messages without reconnecting to Telegram.
|
|
29
|
+
|
|
30
|
+
For example, an agent can search one account and parse the result as JSON:
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
tg search "release" --account work --json
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
Telegram CLI requires Node.js 22 or later.
|
|
39
|
+
|
|
40
|
+
After the package is published to npm, install it globally with:
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
npm install -g @will-17173/telegram-cli
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Configuration
|
|
47
|
+
|
|
48
|
+
Configuring personal Telegram API credentials is optional. To use your own, create them at [my.telegram.org](https://my.telegram.org), then save them with:
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
tg config set --api-id <id> --api-hash <hash>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
If both `TG_API_ID` and `TG_API_HASH` are unset and the saved configuration file is missing, the CLI uses built-in Telegram API credentials. When a Telegram client is created, it writes this warning to stderr once per process:
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
warning: using default Telegram API credentials. Run tg config set --api-id <id> --api-hash <hash> to configure your own.
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Setting only one of `TG_API_ID` or `TG_API_HASH` is an error. A malformed or unreadable saved configuration file is also an error; the CLI does not fall back to the built-in credentials in either case.
|
|
61
|
+
|
|
62
|
+
Personal credentials are stored locally as sensitive configuration. Never share them. API credentials are shared by all registered accounts, while each account keeps its own authentication session.
|
|
63
|
+
|
|
64
|
+
Run `tg account add` to authenticate and create a local session. Other commands never start the interactive login flow.
|
|
65
|
+
|
|
66
|
+
You can override the root directory for configuration, account sessions, and message databases:
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
export DATA_DIR=/path/to/tg-cli-data
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Quick start
|
|
73
|
+
|
|
74
|
+
```sh
|
|
75
|
+
# Add and authenticate the first account
|
|
76
|
+
tg account add
|
|
77
|
+
|
|
78
|
+
# Check authentication status
|
|
79
|
+
tg status
|
|
80
|
+
|
|
81
|
+
# List chats, then use a chat name, username, or ID where `<chat>` appears
|
|
82
|
+
tg chats
|
|
83
|
+
|
|
84
|
+
# Save a chat's history locally
|
|
85
|
+
tg sync <chat>
|
|
86
|
+
|
|
87
|
+
# Search the locally synced messages
|
|
88
|
+
tg search "keyword" --chat <chat>
|
|
89
|
+
|
|
90
|
+
# Sync across all chats
|
|
91
|
+
tg sync-all --max-chats 20 --delay 1
|
|
92
|
+
|
|
93
|
+
# Listen for new messages from one or more chats
|
|
94
|
+
tg listen <chat-or-id> [another-chat ...] --no-media
|
|
95
|
+
|
|
96
|
+
# Send a message
|
|
97
|
+
tg send <chat> "Hello from tg"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Multiple accounts
|
|
101
|
+
|
|
102
|
+
Each Telegram account has its own persisted authentication session and local message database. Add and authenticate an account interactively with:
|
|
103
|
+
|
|
104
|
+
```sh
|
|
105
|
+
tg account add
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The first account you add becomes the current account. Adding another account does not switch the current account automatically. Use the account commands to inspect or change the selection:
|
|
109
|
+
|
|
110
|
+
```sh
|
|
111
|
+
# List registered accounts
|
|
112
|
+
tg account list
|
|
113
|
+
|
|
114
|
+
# Show the current account
|
|
115
|
+
tg account current
|
|
116
|
+
|
|
117
|
+
# Set the default account used by commands
|
|
118
|
+
tg account switch <name>
|
|
119
|
+
|
|
120
|
+
# Remove an account and its local session/data
|
|
121
|
+
tg account remove <name> --force
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Commands use the current account by default. Commands that support `--account` can target another registered account for one invocation without changing the current account:
|
|
125
|
+
|
|
126
|
+
```sh
|
|
127
|
+
tg chats --account <name>
|
|
128
|
+
tg sync-all --account <name>
|
|
129
|
+
tg search "keyword" --account <name>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Account names are shown by `tg account list`; they are normally derived from the Telegram username. Sessions and message databases remain isolated under each account's directory inside `DATA_DIR`.
|
|
133
|
+
|
|
134
|
+
Telegram API credentials apply to every registered account. You don't need to configure separate API credentials when adding another account.
|
|
135
|
+
|
|
136
|
+
## Online and local commands
|
|
137
|
+
|
|
138
|
+
Online commands connect to Telegram and require a valid session. These include `status`, `whoami`, `chats`, `history`, `sync`, `sync-all`, `refresh`, `info`, `send`, `edit`, `delete`, and `listen`.
|
|
139
|
+
|
|
140
|
+
Local commands read or modify the selected account's message database without connecting to Telegram. These include `search`, `recent`, `stats`, `top`, `timeline`, `today`, `filter`, `export`, and `purge`.
|
|
141
|
+
|
|
142
|
+
## Command reference
|
|
143
|
+
|
|
144
|
+
Run the built-in help for the complete, current command list:
|
|
145
|
+
|
|
146
|
+
```sh
|
|
147
|
+
tg --help
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Common commands:
|
|
151
|
+
|
|
152
|
+
| Command | Purpose |
|
|
153
|
+
| --- | --- |
|
|
154
|
+
| `tg account add` | Authenticate and register another Telegram account. |
|
|
155
|
+
| `tg account list` | List registered accounts and show which one is current. |
|
|
156
|
+
| `tg account current` | Show the current account. |
|
|
157
|
+
| `tg account switch <name>` | Set the default account used by commands. |
|
|
158
|
+
| `tg account remove <name> --force` | Remove an account and its local session/data. |
|
|
159
|
+
| `tg status` | Check whether the Telegram account is authenticated. |
|
|
160
|
+
| `tg whoami` | Show basic authenticated account information. |
|
|
161
|
+
| `tg config set --api-id <id> --api-hash <hash>` | Save Telegram API credentials for persistent use. |
|
|
162
|
+
| `tg chats` | List available chats. |
|
|
163
|
+
| `tg history <chat> -n <limit>` | Fetch and store full chat history (default up to 1000 messages). |
|
|
164
|
+
| `tg sync <chat>` | Incrementally sync new messages for one chat. |
|
|
165
|
+
| `tg sync-all` | Sync messages from all chats, using local last-message IDs for incremental updates. |
|
|
166
|
+
| `tg refresh` | Alias-like command for bulk sync with same runtime options as `sync-all`. |
|
|
167
|
+
| `tg listen [chat ...]` | Stream incoming messages from selected chats or all chats. |
|
|
168
|
+
| `tg listen --no-media` | Hide attachment summary lines while listening. |
|
|
169
|
+
| `tg search "keyword" --chat <chat>` | Search messages already stored locally. |
|
|
170
|
+
| `tg recent`, `tg today`, `tg stats`, `tg top`, `tg timeline` | Explore local message data. |
|
|
171
|
+
| `tg filter <keywords>` | Filter local messages by keyword with optional chat/hour filters. |
|
|
172
|
+
| `tg export <chat>` | Export local messages from a chat. |
|
|
173
|
+
| `tg send <chat> "Hello from tg"` | Send a message. |
|
|
174
|
+
| `tg edit <chat> <msgId> <text>` | Edit a message. |
|
|
175
|
+
| `tg delete <chat> <msgIds...>` | Delete one or more messages. |
|
|
176
|
+
| `tg purge <chat> --yes` | Remove a chat's locally stored messages. |
|
|
177
|
+
| `tg info <chat>` | Show metadata for a Telegram chat. |
|
|
178
|
+
|
|
179
|
+
All sync-like commands write to local SQLite storage. The `sync-all` and `refresh` commands process multiple chats based on locally stored message IDs.
|
|
180
|
+
|
|
181
|
+
Many commands support `--json` or `--yaml` for structured output. Failed commands return a nonzero exit code, so scripts can detect errors without parsing human-readable text.
|
|
182
|
+
|
|
183
|
+
Common options:
|
|
184
|
+
|
|
185
|
+
| Option | Purpose |
|
|
186
|
+
| --- | --- |
|
|
187
|
+
| `--account <name>` | Use a registered account without changing the current account. |
|
|
188
|
+
| `--json` / `--yaml` | Emit structured output when the command supports it. |
|
|
189
|
+
| `-v`, `--verbose` | Enable debug logging. |
|
|
190
|
+
| `-V`, `--version` | Print the installed version. |
|
|
191
|
+
|
|
192
|
+
Use `tg <command> --help` to inspect command-specific options. For example, `listen` supports reconnection and plain-text modes, while `search` supports sender, time, regular-expression, and result-limit filters.
|
|
193
|
+
|
|
194
|
+
### Sync and listen behavior
|
|
195
|
+
|
|
196
|
+
- `sync-all` and `refresh` are batch operations for local persistence; they are not read-only.
|
|
197
|
+
- `listen` prints a concise separator for each incoming message and can optionally suppress attachment summaries.
|
|
198
|
+
|
|
199
|
+
## Troubleshooting
|
|
200
|
+
|
|
201
|
+
### No active account
|
|
202
|
+
|
|
203
|
+
If a command reports `account_required`, add an account or select an existing one:
|
|
204
|
+
|
|
205
|
+
```sh
|
|
206
|
+
tg account add
|
|
207
|
+
tg account switch <name>
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Session is no longer valid
|
|
211
|
+
|
|
212
|
+
If Telegram returns `AUTH_KEY_UNREGISTERED`, remove the invalid local session and authenticate again:
|
|
213
|
+
|
|
214
|
+
```sh
|
|
215
|
+
tg account remove <name> --force
|
|
216
|
+
tg account add
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Default API credentials warning
|
|
220
|
+
|
|
221
|
+
The built-in API credentials remain usable, but the CLI prints a warning when it creates a Telegram client. Configure personal credentials to remove the warning:
|
|
222
|
+
|
|
223
|
+
```sh
|
|
224
|
+
tg config set --api-id <id> --api-hash <hash>
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Set both `TG_API_ID` and `TG_API_HASH` when using environment variables. Setting only one causes a configuration error.
|
|
228
|
+
|
|
229
|
+
## Local data and privacy
|
|
230
|
+
|
|
231
|
+
Persisted configuration, authentication sessions, and synced messages remain on your machine unless you copy or export them. The relevant files under `DATA_DIR` are:
|
|
232
|
+
|
|
233
|
+
```text
|
|
234
|
+
config.json
|
|
235
|
+
accounts.json
|
|
236
|
+
accounts/<name>/session
|
|
237
|
+
accounts/<name>/messages.db
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Treat persisted configuration, `.env`, Telegram credentials, session files, and SQLite data as sensitive. Never share them or commit them to version control.
|
|
241
|
+
|
|
242
|
+
## Development
|
|
243
|
+
|
|
244
|
+
This project uses pnpm:
|
|
245
|
+
|
|
246
|
+
```sh
|
|
247
|
+
pnpm install
|
|
248
|
+
pnpm dev --help
|
|
249
|
+
pnpm test
|
|
250
|
+
pnpm typecheck
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
For local source development, create a `.env` file in the project root:
|
|
254
|
+
|
|
255
|
+
```dotenv
|
|
256
|
+
TG_API_ID=your_telegram_api_id
|
|
257
|
+
TG_API_HASH=your_telegram_api_hash
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
`pnpm dev` loads this file only for local source development. An installed `tg` does not automatically load `.env`; use `tg config set --api-id <id> --api-hash <hash>` for persistent production configuration.
|
|
261
|
+
|
|
262
|
+
## License
|
|
263
|
+
|
|
264
|
+
Licensed under [GPL-3.0](LICENSE).
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# Telegram CLI
|
|
2
|
+
|
|
3
|
+
[English](README.md)
|
|
4
|
+
|
|
5
|
+
一个 TypeScript 命令行客户端,用于同步 Telegram 聊天记录、监听实时消息、搜索本地存储的消息,并在终端中管理 Telegram 任务。
|
|
6
|
+
|
|
7
|
+
## 功能
|
|
8
|
+
|
|
9
|
+
- 登录 Telegram,并查看当前账户或可用聊天列表。
|
|
10
|
+
- 管理多个 Telegram 账号,每个账号使用独立的会话和消息数据库。
|
|
11
|
+
- 将聊天记录提取到本地 SQLite 数据库,以便快速离线搜索。
|
|
12
|
+
- 通过增量同步和批量同步命令更新本地数据。
|
|
13
|
+
- 监听实时消息,并可选显示附件摘要。
|
|
14
|
+
- 从限制下载的频道中下载附件。
|
|
15
|
+
- 搜索、筛选、汇总和导出本地存储的消息。
|
|
16
|
+
- 通过命令行发送、编辑和删除消息。
|
|
17
|
+
- 在支持的场景下使用人类可读输出,或结构化的 JSON/YAML 输出。
|
|
18
|
+
|
|
19
|
+
## 为 AI Agent 设计
|
|
20
|
+
|
|
21
|
+
Telegram CLI 为 AI Agent 提供基于命令的 Telegram 和本地消息访问接口。由人工通过 `tg account add` 完成账号认证后,Agent 无需操作浏览器即可执行在线命令和本地命令。
|
|
22
|
+
|
|
23
|
+
以下接口适合 Agent 工作流:
|
|
24
|
+
|
|
25
|
+
- JSON 和 YAML 输出让 Agent 直接读取结构化数据,而不是解析终端表格。
|
|
26
|
+
- 非零退出码和结构化错误码让 Agent 能够检测并处理失败。
|
|
27
|
+
- `--account <name>` 可以明确指定账号,且不会改变 current 账号。
|
|
28
|
+
- 本地搜索和分析命令无需重新连接 Telegram,即可查询已同步消息。
|
|
29
|
+
|
|
30
|
+
例如,Agent 可以搜索指定账号,并将结果作为 JSON 解析:
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
tg search "release" --account work --json
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 安装
|
|
37
|
+
|
|
38
|
+
Telegram CLI 需要 Node.js 22 或更高版本。
|
|
39
|
+
|
|
40
|
+
在该软件包发布到 npm 后,可通过以下命令全局安装:
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
npm install -g @will-17173/telegram-cli
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## 配置
|
|
47
|
+
|
|
48
|
+
配置个人 Telegram API 凭据是可选的。如需使用自己的凭据,请先在 [my.telegram.org](https://my.telegram.org) 创建,然后通过以下命令保存:
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
tg config set --api-id <id> --api-hash <hash>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
如果 `TG_API_ID` 和 `TG_API_HASH` 均未设置,且已保存的配置文件不存在,CLI 会使用内置的 Telegram API 凭据。创建 Telegram 客户端时,每个进程只会向 stderr 输出一次以下警告:
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
warning: using default Telegram API credentials. Run tg config set --api-id <id> --api-hash <hash> to configure your own.
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
这表示 CLI 正在使用默认凭据;如需配置自己的凭据,请运行 `tg config set --api-id <id> --api-hash <hash>`。只设置 `TG_API_ID` 或 `TG_API_HASH` 其中之一会导致错误。已保存的配置文件格式错误或无法读取也会导致错误;这两种情况下 CLI 都不会改用内置凭据。
|
|
61
|
+
|
|
62
|
+
个人凭据会作为敏感配置存储在本地,切勿与他人分享。所有已添加账号共用一套 API 凭据,但每个账号都有独立的身份验证会话。
|
|
63
|
+
|
|
64
|
+
运行 `tg account add` 完成身份验证并创建本地会话。其他命令不会启动交互式登录流程。
|
|
65
|
+
|
|
66
|
+
你可以通过环境变量修改配置、账号会话和消息数据库的根目录:
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
export DATA_DIR=/path/to/tg-cli-data
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## 快速开始
|
|
73
|
+
|
|
74
|
+
```sh
|
|
75
|
+
# 添加并登录第一个账号
|
|
76
|
+
tg account add
|
|
77
|
+
|
|
78
|
+
# 检查身份验证状态
|
|
79
|
+
tg status
|
|
80
|
+
|
|
81
|
+
# 列出聊天,然后在出现 `<chat>` 的位置使用聊天名称、用户名或 ID
|
|
82
|
+
tg chats
|
|
83
|
+
|
|
84
|
+
# 将聊天记录保存到本地
|
|
85
|
+
tg sync <chat>
|
|
86
|
+
|
|
87
|
+
# 搜索已同步到本地的消息
|
|
88
|
+
tg search "keyword" --chat <chat>
|
|
89
|
+
|
|
90
|
+
# 同步全部聊天
|
|
91
|
+
tg sync-all --max-chats 20 --delay 1
|
|
92
|
+
|
|
93
|
+
# 监听实时消息(可指定多个聊天)
|
|
94
|
+
tg listen <chat-or-id> [another-chat ...] --no-media
|
|
95
|
+
|
|
96
|
+
# 发送消息
|
|
97
|
+
tg send <chat> "Hello from tg"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## 多账号
|
|
101
|
+
|
|
102
|
+
每个 Telegram 账号都有独立持久化的身份验证会话和本地消息数据库。通过以下命令交互式登录并添加账号:
|
|
103
|
+
|
|
104
|
+
```sh
|
|
105
|
+
tg account add
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
添加的第一个账号会自动成为 current 账号。继续添加其他账号时不会自动切换 current 账号,可通过以下命令查看或更改选择:
|
|
109
|
+
|
|
110
|
+
```sh
|
|
111
|
+
# 列出已添加的账号
|
|
112
|
+
tg account list
|
|
113
|
+
|
|
114
|
+
# 查看 current 账号
|
|
115
|
+
tg account current
|
|
116
|
+
|
|
117
|
+
# 设置命令默认使用的账号
|
|
118
|
+
tg account switch <name>
|
|
119
|
+
|
|
120
|
+
# 删除账号及其本地会话和数据
|
|
121
|
+
tg account remove <name> --force
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
各命令默认使用 current 账号。支持 `--account` 的命令可以临时指定另一个已添加的账号,且不会改变 current 账号:
|
|
125
|
+
|
|
126
|
+
```sh
|
|
127
|
+
tg chats --account <name>
|
|
128
|
+
tg sync-all --account <name>
|
|
129
|
+
tg search "keyword" --account <name>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
账号名称可通过 `tg account list` 查看,通常由 Telegram 用户名生成。各账号的会话和消息数据库分别保存在 `DATA_DIR` 下对应的账号目录中。
|
|
133
|
+
|
|
134
|
+
Telegram API 凭据对所有已添加账号生效,添加其他账号时无需单独配置 API 凭据。
|
|
135
|
+
|
|
136
|
+
## 在线命令与本地命令
|
|
137
|
+
|
|
138
|
+
在线命令会连接 Telegram,因此需要有效的账号会话。这类命令包括 `status`、`whoami`、`chats`、`history`、`sync`、`sync-all`、`refresh`、`info`、`send`、`edit`、`delete` 和 `listen`。
|
|
139
|
+
|
|
140
|
+
本地命令只读取或修改所选账号的消息数据库,不会连接 Telegram。这类命令包括 `search`、`recent`、`stats`、`top`、`timeline`、`today`、`filter`、`export` 和 `purge`。
|
|
141
|
+
|
|
142
|
+
## 命令参考
|
|
143
|
+
|
|
144
|
+
运行内置帮助以查看完整且最新的命令列表:
|
|
145
|
+
|
|
146
|
+
```sh
|
|
147
|
+
tg --help
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
常用命令:
|
|
151
|
+
|
|
152
|
+
| 命令 | 用途 |
|
|
153
|
+
| --- | --- |
|
|
154
|
+
| `tg account add` | 登录并添加另一个 Telegram 账号。 |
|
|
155
|
+
| `tg account list` | 列出已添加的账号及 current 状态。 |
|
|
156
|
+
| `tg account current` | 查看 current 账号。 |
|
|
157
|
+
| `tg account switch <name>` | 设置各命令默认使用的账号。 |
|
|
158
|
+
| `tg account remove <name> --force` | 删除账号及其本地会话和数据。 |
|
|
159
|
+
| `tg whoami` | 显示当前登录账号的基本信息。 |
|
|
160
|
+
| `tg config set --api-id <id> --api-hash <hash>` | 持久化保存 Telegram API 凭据。 |
|
|
161
|
+
| `tg status` | 检查 Telegram 账户是否已完成身份验证。 |
|
|
162
|
+
| `tg chats` | 列出可用聊天。 |
|
|
163
|
+
| `tg history <chat> -n <limit>` | 获取并保存完整聊天历史(默认最多 1000 条)。 |
|
|
164
|
+
| `tg sync <chat>` | 将聊天消息同步到本地存储。 |
|
|
165
|
+
| `tg sync-all` | 从全部聊天同步消息,按本地已同步进度做增量更新。 |
|
|
166
|
+
| `tg refresh` | 与 `sync-all` 相同用途的批量同步命令。 |
|
|
167
|
+
| `tg listen [chat ...]` | 实时监听指定聊天(或监听全部聊天)。 |
|
|
168
|
+
| `tg listen --no-media` | 监听时隐藏附件摘要。 |
|
|
169
|
+
| `tg search "keyword" --chat <chat>` | 搜索已存储在本地的消息。 |
|
|
170
|
+
| `tg recent`, `tg today`, `tg stats`, `tg top`, `tg timeline` | 浏览本地消息数据。 |
|
|
171
|
+
| `tg filter <keywords>` | 按关键词筛选本地消息(支持按聊天和时间范围过滤)。 |
|
|
172
|
+
| `tg export <chat>` | 导出本地存储的消息。 |
|
|
173
|
+
| `tg send <chat> "Hello from tg"` | 发送消息。 |
|
|
174
|
+
| `tg edit <chat> <msgId> <text>` | 编辑消息。 |
|
|
175
|
+
| `tg delete <chat> <msgIds...>` | 删除一条或多条消息。 |
|
|
176
|
+
| `tg purge <chat> --yes` | 移除某个聊天在本地存储的消息。 |
|
|
177
|
+
| `tg info <chat>` | 查看聊天元信息。 |
|
|
178
|
+
|
|
179
|
+
所有同步类命令都会写入本地 SQLite 数据库。`sync-all` 和 `refresh` 根据本地已保存的消息 ID 增量处理多个聊天。
|
|
180
|
+
|
|
181
|
+
许多命令支持通过 `--json` 或 `--yaml` 输出结构化数据。命令失败时会返回非零退出码,脚本无需解析人类可读文本即可判断执行结果。
|
|
182
|
+
|
|
183
|
+
常用选项:
|
|
184
|
+
|
|
185
|
+
| 选项 | 用途 |
|
|
186
|
+
| --- | --- |
|
|
187
|
+
| `--account <name>` | 临时使用已添加的账号,不改变 current 账号。 |
|
|
188
|
+
| `--json` / `--yaml` | 在命令支持时输出结构化数据。 |
|
|
189
|
+
| `-v`, `--verbose` | 启用调试日志。 |
|
|
190
|
+
| `-V`, `--version` | 输出当前安装版本。 |
|
|
191
|
+
|
|
192
|
+
使用 `tg <command> --help` 查看命令专用选项。例如,`listen` 支持自动重连和纯文本模式,`search` 支持发送者、时间、正则表达式和结果数量筛选。
|
|
193
|
+
|
|
194
|
+
### 同步与监听行为
|
|
195
|
+
|
|
196
|
+
- `sync-all` 和 `refresh` 是写入本地数据库的批量同步流程,不是只读命令。
|
|
197
|
+
- `listen` 会实时打印每条到达消息;可用 `--no-media` 关闭附件摘要显示。
|
|
198
|
+
|
|
199
|
+
## 故障排查
|
|
200
|
+
|
|
201
|
+
### 没有可用的当前账号
|
|
202
|
+
|
|
203
|
+
如果命令返回 `account_required`,请添加账号或选择已有账号:
|
|
204
|
+
|
|
205
|
+
```sh
|
|
206
|
+
tg account add
|
|
207
|
+
tg account switch <name>
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### 账号会话已经失效
|
|
211
|
+
|
|
212
|
+
如果 Telegram 返回 `AUTH_KEY_UNREGISTERED`,请删除失效的本地会话并重新登录:
|
|
213
|
+
|
|
214
|
+
```sh
|
|
215
|
+
tg account remove <name> --force
|
|
216
|
+
tg account add
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### 默认 API 凭据警告
|
|
220
|
+
|
|
221
|
+
内置 API 凭据仍可使用,但 CLI 创建 Telegram 客户端时会输出警告。配置个人凭据即可移除该警告:
|
|
222
|
+
|
|
223
|
+
```sh
|
|
224
|
+
tg config set --api-id <id> --api-hash <hash>
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
通过环境变量配置时,必须同时设置 `TG_API_ID` 和 `TG_API_HASH`。只设置其中一个会导致配置错误。
|
|
228
|
+
|
|
229
|
+
## 本地数据与隐私
|
|
230
|
+
|
|
231
|
+
除非你明确复制或导出,否则持久化配置、身份验证会话和已同步消息都会保留在本机。`DATA_DIR` 下的相关文件如下:
|
|
232
|
+
|
|
233
|
+
```text
|
|
234
|
+
config.json
|
|
235
|
+
accounts.json
|
|
236
|
+
accounts/<name>/session
|
|
237
|
+
accounts/<name>/messages.db
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
请将持久化配置、`.env`、Telegram 凭据、会话文件和 SQLite 数据视为敏感信息,切勿与他人分享或将它们提交到版本控制中。
|
|
241
|
+
|
|
242
|
+
## 开发
|
|
243
|
+
|
|
244
|
+
本项目使用 pnpm:
|
|
245
|
+
|
|
246
|
+
```sh
|
|
247
|
+
pnpm install
|
|
248
|
+
pnpm dev --help
|
|
249
|
+
pnpm test
|
|
250
|
+
pnpm typecheck
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
在本地进行源码开发时,请在项目根目录创建 `.env` 文件:
|
|
254
|
+
|
|
255
|
+
```dotenv
|
|
256
|
+
TG_API_ID=your_telegram_api_id
|
|
257
|
+
TG_API_HASH=your_telegram_api_hash
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
`pnpm dev` 仅在本地源码开发时加载此文件。安装后的 `tg` 不会自动加载 `.env`;如需持久化生产配置,请使用 `tg config set --api-id <id> --api-hash <hash>`。
|
|
261
|
+
|
|
262
|
+
## 许可证
|
|
263
|
+
|
|
264
|
+
采用 [GPL-3.0](LICENSE) 许可证。
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { getAccountRegistryPath, getDataDir } from '../config/env.js';
|
|
2
|
+
import { AccountStore } from './account-store.js';
|
|
3
|
+
import { toAccountContext } from './account-presets.js';
|
|
4
|
+
export function resolveAccountContext(input = {}) {
|
|
5
|
+
const dataDir = input.dataDir?.trim() ? input.dataDir.trim() : getDataDir();
|
|
6
|
+
const store = new AccountStore(getAccountRegistryPath(dataDir));
|
|
7
|
+
const registry = store.read();
|
|
8
|
+
const name = explicitOrCurrent(input.explicitName, registry.current_account);
|
|
9
|
+
if (!name) {
|
|
10
|
+
throw new Error('account_required: no active account found');
|
|
11
|
+
}
|
|
12
|
+
const account = store.get(name);
|
|
13
|
+
if (!account) {
|
|
14
|
+
throw new Error(`account_not_found: account "${name}"`);
|
|
15
|
+
}
|
|
16
|
+
return toAccountContext(dataDir, account);
|
|
17
|
+
}
|
|
18
|
+
function explicitOrCurrent(explicitName, currentAccount) {
|
|
19
|
+
const explicit = explicitName?.trim();
|
|
20
|
+
return explicit ? explicit : currentAccount ?? undefined;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=account-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-context.js","sourceRoot":"","sources":["../../src/account/account-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAOvD,MAAM,UAAU,qBAAqB,CAAC,QAAgC,EAAE;IACtE,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,UAAU,EAAE,CAAA;IAC3E,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC,CAAA;IAC/D,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,EAAE,CAAA;IAC7B,MAAM,IAAI,GAAG,iBAAiB,CAAC,KAAK,CAAC,YAAY,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAA;IAE5E,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAA;IAC9D,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC/B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,+BAA+B,IAAI,GAAG,CAAC,CAAA;IACzD,CAAC;IAED,OAAO,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;AAC3C,CAAC;AAED,SAAS,iBAAiB,CAAC,YAAgC,EAAE,cAA6B;IACxF,MAAM,QAAQ,GAAG,YAAY,EAAE,IAAI,EAAE,CAAA;IACrC,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,cAAc,IAAI,SAAS,CAAA;AAC1D,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
export function toAccountContext(dataDir, account) {
|
|
3
|
+
const accountCopy = Object.freeze({
|
|
4
|
+
name: account.name,
|
|
5
|
+
user_id: account.user_id,
|
|
6
|
+
username: account.username,
|
|
7
|
+
phone: account.phone,
|
|
8
|
+
display_name: account.display_name,
|
|
9
|
+
});
|
|
10
|
+
return Object.freeze({
|
|
11
|
+
account: accountCopy,
|
|
12
|
+
sessionPath: accountSessionPath(dataDir, account.name),
|
|
13
|
+
dbPath: accountDbPath(dataDir, account.name),
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
export function accountSessionPath(dataDir, accountName) {
|
|
17
|
+
return join(dataDir, 'accounts', accountName, 'session');
|
|
18
|
+
}
|
|
19
|
+
export function accountDbPath(dataDir, accountName) {
|
|
20
|
+
return join(dataDir, 'accounts', accountName, 'messages.db');
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=account-presets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-presets.js","sourceRoot":"","sources":["../../src/account/account-presets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAgBhC,MAAM,UAAU,gBAAgB,CAAC,OAAe,EAAE,OAAoB;IACpE,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;QAChC,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,YAAY,EAAE,OAAO,CAAC,YAAY;KACnC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,OAAO,EAAE,WAAW;QACpB,WAAW,EAAE,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC;QACtD,MAAM,EAAE,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC;KAC7C,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAe,EAAE,WAAmB;IACrE,OAAO,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,CAAC,CAAA;AAC1D,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,WAAmB;IAChE,OAAO,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,CAAC,CAAA;AAC9D,CAAC"}
|