https://github.com/vika2603/telegram-cli
Send and read Telegram messages from the command line.
https://github.com/vika2603/telegram-cli
cli daemon go golang gotd grpc mtproto telegram telegram-cli
Last synced: 3 days ago
JSON representation
Send and read Telegram messages from the command line.
- Host: GitHub
- URL: https://github.com/vika2603/telegram-cli
- Owner: vika2603
- Created: 2026-04-22T07:35:48.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2026-05-28T18:36:21.000Z (27 days ago)
- Last Synced: 2026-05-28T19:16:30.818Z (27 days ago)
- Topics: cli, daemon, go, golang, gotd, grpc, mtproto, telegram, telegram-cli
- Language: Go
- Size: 478 KB
- Stars: 1
- Watchers: 0
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# tg
A command-line Telegram client. Script-friendly, JSON-first.
## Install
```sh
go install github.com/vika2603/telegram-cli/cmd/tg@latest
```
## Quick start
Get `api_id` and `api_hash` at .
```sh
tg login work --api-id --api-hash
# paste the login code from your Telegram app
tg auth switch work
tg auth list
```
Pass `--qr` to `auth login` for QR login instead.
## Command Map
### Frequent
| Command | Purpose |
| --- | --- |
| `tg login ` | Shortcut for `tg auth login `. |
| `tg logout [name]` | Shortcut for `tg auth logout [name]`. |
| `tg send [text...]` | Shortcut for `tg msg send [text...]`. Repeat `--file` to attach media. |
| `tg reply [text...]` | Reply to one message. Repeat `--file` to attach media. |
| `tg inbox` | Show recent dialogs with unread counts and last messages. |
| `tg read ` | Shortcut for `tg msg list `. |
| `tg digest ` | Compact history view for one chat. |
| `tg resolve ` | Resolve one user, chat, bot, or channel. |
### Account, Session, Config
| Command | Purpose |
| --- | --- |
| `tg auth login ` | Create an account slot and log in. `--no-login` creates the slot only; `--force` re-runs auth. |
| `tg auth logout [name]` | Revoke this CLI session. `--purge` also removes local account files. |
| `tg auth list` | List local account slots. |
| `tg auth switch ` | Set `default_account` for later commands. |
| `tg auth status [name]` | Show local account health. `--probe` adds a live Telegram check. |
| `tg session list` | List remote Telegram authorizations. |
| `tg session revoke [hash]` | Revoke a remote session, or use `--all-others` to keep only this CLI session. |
| `tg password set` | Set or rotate the Telegram cloud password. |
| `tg password disable` | Remove the Telegram cloud password. |
| `tg config get ` | Read one config value. `--no-redact` shows `api_hash` verbatim. |
| `tg config set ` | Write one config value. `--force` is required for `api_hash`. |
| `tg config unset ` | Remove one config value. |
| `tg config edit` | Open `$VISUAL` / `$EDITOR` on the config file with rollback on parse failure. |
| `tg config path` | Print the resolved config path. |
| `tg config show` | Print merged config with secrets redacted. |
### Daemon
A per-account background service that holds a long-lived MTProto session
so subsequent commands skip the dial / auth-resume cost (~1 s → ~0.25 s)
and `tg watch` can stream real-time updates over a Unix socket instead
of opening its own connection. Registration uses the host's native
service manager: launchd on macOS, systemd-user on Linux. The daemon is
optional — every command still works without one. Add `--no-daemon` to
any command to force a fresh MTProto session even when a daemon is
reachable.
| Command | Purpose |
| --- | --- |
| `tg daemon install` | Register the per-account daemon with the host service manager. `--force` reinstalls; `--log-file` / `--log-max-mb` tune logging. |
| `tg daemon uninstall` | Remove the service registration. Keeps `daemon.log` and `updates.ndjson` so a re-install can pick them up. |
| `tg daemon start` / `tg daemon stop` | Ask the OS to start or stop the service. |
| `tg daemon status` | JSON-emitting status (installed / running / pid / log + updates paths). |
| `tg daemon logs [-f] [-n N]` | Tail the daemon log; `-f` follows. |
Daemon artifacts live under `~/.config/tg/accounts//daemon/`:
`daemon.log` (service stdout+stderr, rotated at 10 MB by default),
`updates.ndjson` (append-only stream of every MTProto update — tailable
even without a connected subscriber), and `daemon.sock` (Unix socket
client commands route through when present).
### Chats, Messages, Search
| Command | Purpose |
| --- | --- |
| `tg chat list` | List dialogs. |
| `tg chat info ` | Show one user, chat, bot, or channel. `--full` adds members/admins/online counts, about, linked discussion group, pinned message, and slow mode (supergroups/channels only). |
| `tg chat create ` | Create a supergroup. `--forum` enables topics; `--about` sets the description. |
| `tg chat delete ` | Delete a supergroup/channel (irreversible), or remove a user DM from your chat list (`--revoke` also deletes it on the other side). Prompts unless `--yes`. |
| `tg chat edit ` | Edit a supergroup: `--title`, `--about`, `--public ` / `--private`; toggles: `--forum`/`--no-forum`, `--hide-members`/`--show-members`, `--hide-history`/`--show-history`, `--slow-mode `, `--no-forwards`/`--allow-forwards`, `--need-approval`/`--no-need-approval` (public only). |
| `tg chat topic list ` | List a forum supergroup's topics. `--search` filters by title; `--limit` caps results (single page only, ~100 max — pagination not implemented). |
| `tg chat topic create ` | Create a topic. `--icon-color`, `--icon-emoji`, and `--random-id` (idempotent retry). |
| `tg chat topic info ` | Show details for one topic. |
| `tg chat topic mute ` / `tg chat topic unmute ` | Mute or unmute a single topic. Mute takes `--duration`, `--until`, or `--forever` (default forever). |
| `tg chat topic read ` | Mark a topic as read. |
| `tg chat topic edit ` | Rename (`--title`), close/reopen (`--close`/`--reopen`), hide/unhide (`--hide`/`--unhide`). |
| `tg chat topic pin ` / `tg chat topic unpin ` | Pin or unpin a topic. |
| `tg chat topic delete ` | Delete a topic and its history. Prompts unless `--yes`. |
| `tg channel create ` | Create a broadcast channel. `--about` sets the description. |
| `tg channel delete ` | Delete a channel (irreversible). Prompts unless `--yes`. |
| `tg channel edit ` | Edit a channel: `--title`, `--about`, `--public ` / `--private`; toggles: `--no-forwards`/`--allow-forwards`, `--signatures`/`--no-signatures`. |
| `tg channel discussion link ` | Link a supergroup as the channel's discussion group (comments). |
| `tg channel discussion unlink ` | Unlink the channel's discussion group. |
| `tg channel discussion candidates` | List supergroups eligible to be a discussion group. |
| `tg chat mark-read ` | Mark a chat as read. `--max-id` limits the range. |
| `tg chat join ` | Join a channel, group, or invite link (request-needed links report `requested`). |
| `tg chat join list ` | List pending join requests. `--link` limits to one invite link. |
| `tg chat join approve ...` / `deny ...` | Approve/reject specific users, or `--all` (optionally `--link`) for every pending request. |
| `tg chat leave ` | Leave a channel or supergroup. Prompts unless `--yes`. |
| `tg chat mute ` | Mute notifications with `--duration`, `--until`, or `--forever`. |
| `tg chat unmute ` | Restore notifications. |
| `tg chat archive ` | Move a chat to the archive folder. |
| `tg chat unarchive ` | Move a chat back to the main folder. |
| `tg chat pin ` | Pin a chat to the top of the chat list. |
| `tg chat unpin ` | Unpin a chat from the top of the chat list. |
| `tg chat photo set ` | Set a group/channel photo (`-` reads stdin). Also available as `tg channel photo set`. |
| `tg chat photo clear ` | Remove a group/channel photo. Also `tg channel photo clear`. |
| `tg chat member list ` | List members (admins show their custom `rank`/title). `--filter recent\|admins\|bots\|kicked\|banned\|contacts`, `--search`, `--limit`; `--via-link ` lists users who joined via that invite link. |
| `tg chat invite ...` | Add users to a group or channel. Each row reports `invited` true/false plus a `skip_reason` (e.g. `privacy_restricted`) when Telegram declined to add a user. |
| `tg chat invite create ` | Create an invite link. `--title`, `--expire `, `--usage-limit `, `--request-needed`. |
| `tg chat invite list ` | List invite links. `--revoked`, `--admin `, `--limit`. |
| `tg chat invite revoke ` / `delete ` | Revoke a link, or delete a revoked one. |
| `tg chat ban ` / `tg chat unban ` | Ban (remove + restrict) or unban a member of a group/channel. Ban prompts unless `--yes`. |
| `tg chat admin promote ` / `tg chat admin demote ` | Grant or revoke admin rights. `--rights ` grants a specific set (`info,post,edit,delete,ban,invite,pin,add_admins,anonymous,call,topics,post_stories,edit_stories,delete_stories`); omit `--rights` for a broad default set. `--title ` sets a custom admin title (≤16 chars); omit `--title` to keep the current title, pass `--title ""` to clear it. |
| `tg chat member set-perms ` | Set a member's permissions with `--deny`/`--allow` keywords (`send,media,stickers,bots,polls,links,invite,pin,info,topics`) and optional `--until ` (default permanent). |
| `tg chat member unset-perms ` | Clear all permission restrictions on a member. |
| `tg chat perms ` | Set the group's default member permissions with `--deny`/`--allow` (same keywords). |
| `tg msg list ` | List message history. Album members (same `grouped_id`) merge into one row with an `album` array (`--limit` counts an album as one). |
| `tg msg info ` | Show one message's details: media info (file name/size/mime, dimensions, duration, sticker emoji, web-page title/url), album members (each with media detail), and poll content (question, numbered options, tallies). |
| `tg msg send [text...]` | Send text. Repeat `--file ` to attach one or more files; text becomes the first media caption. Use `--name` to override upload filenames. `--sticker ` / `--gif ` send a sticker/gif — either a `msg sticker list`/`msg gif list` ref or a `` of an existing one (no text/`--file`). |
| `tg msg sticker list` | List your stickers to get a sendable `ref`. `--recent` (default), `--faved`, `--installed` (sets), `--all` (recent+faved+all sets expanded; slow). |
| `tg msg sticker fave ` / `tg msg sticker unfave ` | Add or remove a sticker from favorites (`` is a list ref or ``). |
| `tg msg sticker add ` / `tg msg sticker remove ` | Install or uninstall a sticker set. `` is a set short name or an `https://t.me/addstickers/` link. |
| `tg msg gif list` | List your saved GIFs, each with a sendable `ref`. |
| `tg msg poll ...` | Send a poll (≥2 options). `--multiple`, `--public` (default anonymous); `--correct ` makes it a quiz with optional `--explanation`. |
| `tg msg vote ...` | Vote on a poll by 1-based option number (multiple numbers for multiple-choice polls); `--retract` to take back your vote. |
| `tg msg download ` | Download photo, video, document, or other message media. Defaults to the media filename; use `-o/--output` for a file path or existing directory. |
| `tg msg edit ` | Edit a message. |
| `tg msg delete ...` | Delete messages. Add `--revoke` when deleting for everyone is required. |
| `tg msg forward ... --to ` | Forward messages. |
| `tg msg react ` | Set or clear a reaction. |
| `tg msg pin ` / `tg msg unpin ` | Pin or unpin a message. |
| `tg msg schedule-list ` | List scheduled messages. |
| `tg msg schedule-cancel ...` | Cancel scheduled messages. |
| `tg msg link ` | Print the public `t.me` link for a message when available. |
| `tg watch [...]` | Stream new messages, edits, and deletes as ndjson until cancelled. `--kind=message,edit,delete` filters event kinds; `--limit N` exits after N events. When a daemon is running, routes through its socket; otherwise opens a foreground MTProto session. |
| `tg search msg ` | Search messages globally, or use `--in ` for one chat. |
| `tg search chat ` | Search chats, users, channels, and bots. |
### Contacts And Profile
| Command | Purpose |
| --- | --- |
| `tg contact list` | List contacts. `--blocked` lists blocked users instead. |
| `tg contact add ` | Add a contact by phone number. |
| `tg contact delete ` | Delete a contact. |
| `tg contact block ` | Block a user, bot, or channel. |
| `tg contact unblock ` | Unblock a user, bot, or channel. |
| `tg contact report ` | Report a peer to Telegram. `--reason` (spam (default), violence, porn, child-abuse, copyright, fake, drugs, personal-details, geo-irrelevant, other), `--message `, `--block` (also block the peer). Prompts unless `--yes`. |
| `tg me` | Print the current Telegram identity. |
| `tg profile set-name ` | Set first name; `--last` sets or clears last name. |
| `tg profile set-username ` | Set or clear the public username. |
| `tg profile set-bio ` | Set bio; `-` reads stdin. |
| `tg profile set-photo ` | Set profile photo; `-` reads stdin bytes. |
| `tg profile delete-photo` | Remove the current profile photo. Prompts unless `--yes`. |
| `tg profile set-status ` | Set online visibility status. |
Peer refs accept usernames (`@name` or `name`), phone numbers, `me`, `saved`,
supported `t.me` / `tg://resolve` links, and the copy-paste refs printed by
`tg chat list`: `u::` for users, `g:` for legacy groups,
and `c::` for channels or supergroups. Numeric IDs still work
when the local peer cache is warm, but the printed refs are the stable CLI form.
Message refs are `:` and are printed by `tg read` /
`tg msg list`, for example `@news:42` or `c:100:555:42`.
The old `tg account` group has been removed. Use `tg auth login`, `tg auth list`,
and `tg auth switch` instead.
## Output
Human output by default. Add `--json=` to get structured output.
List commands emit ndjson (one JSON object per line), not a JSON array, so
parse line by line or collect with `jq -s` (e.g. `tg read @x --json | jq -s .`);
scalar commands emit a single object.
```sh
tg auth list --json=name,state,api_id
# {"name":"work","state":"AUTHED","api_id":12345}
tg read @news --limit 1 --json
# {"ref":"@news:42","id":42,"date":"...","from":{"ref":"@alice","id":123,"type":"user","title":"Alice","username":"alice","link":"https://t.me/alice"},"text":"hello"}
tg auth list --json=name,state --jq='.name'
# work
tg auth list --json=name,state --template='{{range .}}{{.name}}{{"\n"}}{{end}}'
# work
```
`--jq` and `--template` refine JSON output and are only valid with
`--json`. `--output=json` is equivalent to `--json` with all fields.
## Configuration
`~/.config/tg/config.toml`, `0600`. Everything is optional except `version`.
```toml
version = 1
default_account = "work"
api_id = 12345
api_hash = "..."
[output]
format = "human" # or "json"
[log]
level = "warn" # error | warn | info | debug
[flood_wait]
mode = "fail" # or "wait"
max_seconds = 30
```
Values can also come from `TG_*` environment variables or command flags.
Precedence: **flag > env > config file > default**.
## Exit Codes
| Code | Meaning |
| --- | --- |
| 0 | Success. Empty successful results also exit 0. |
| 1 | Unknown error, or an error that was already printed by the command. |
| 2 | Usage or configuration error. |
| 3 | Authentication is required, expired, or revoked. |
| 4 | Peer or message could not be found, or a ref was ambiguous. |
| 5 | Telegram says the peer/message/action is forbidden. |
| 6 | Telegram returned `FLOOD_WAIT` or rate/quota exhaustion. |
| 7 | Network or transport failure. |
| 8 | Conflict-like operation state: current session, invalid invite, revoke required, or bad cloud password. |
| 9 | Internal precondition, numeric peer cache miss, unsupported operation, missing media, or unavailable message link. |
| 72 | Another `tg` process holds the account lock. |
| 73 | User declined a confirmation prompt. |
| 130 | Interrupted by SIGINT / Ctrl+C. |
Under `--json`, errors are emitted on stderr as a single JSON object with
`error.code`, `error.message`, and `exit_code` fields. stdout stays data-only.
When the failure is a Telegram RPC error, `error.rpc_error` carries the exact
Telegram enum (e.g. `CHAT_ADMIN_REQUIRED`) for programmatic matching — present
even for errors that aren't mapped to a friendly `code`/`message`.
## Shell completion
```sh
tg completion bash > /usr/local/etc/bash_completion.d/tg
tg completion zsh > "${fpath[1]}/_tg"
tg completion fish > ~/.config/fish/completions/tg.fish
```
Account names, enum flags, and recently used peer/message refs autocomplete.
## License
TBD.