{"id":51016443,"url":"https://github.com/vika2603/telegram-cli","last_synced_at":"2026-06-21T11:02:16.438Z","repository":{"id":357786759,"uuid":"1217761798","full_name":"vika2603/telegram-cli","owner":"vika2603","description":"Send and read Telegram messages from the command line.","archived":false,"fork":false,"pushed_at":"2026-05-28T18:36:21.000Z","size":489,"stargazers_count":1,"open_issues_count":1,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-28T19:16:30.818Z","etag":null,"topics":["cli","daemon","go","golang","gotd","grpc","mtproto","telegram","telegram-cli"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vika2603.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-22T07:35:48.000Z","updated_at":"2026-05-28T18:36:27.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/vika2603/telegram-cli","commit_stats":null,"previous_names":["vika2603/telegram-cli"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/vika2603/telegram-cli","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vika2603%2Ftelegram-cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vika2603%2Ftelegram-cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vika2603%2Ftelegram-cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vika2603%2Ftelegram-cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vika2603","download_url":"https://codeload.github.com/vika2603/telegram-cli/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vika2603%2Ftelegram-cli/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34607126,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-21T02:00:05.568Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","daemon","go","golang","gotd","grpc","mtproto","telegram","telegram-cli"],"created_at":"2026-06-21T11:02:15.462Z","updated_at":"2026-06-21T11:02:16.430Z","avatar_url":"https://github.com/vika2603.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tg\n\nA command-line Telegram client. Script-friendly, JSON-first.\n\n## Install\n\n```sh\ngo install github.com/vika2603/telegram-cli/cmd/tg@latest\n```\n\n## Quick start\n\nGet `api_id` and `api_hash` at \u003chttps://my.telegram.org\u003e.\n\n```sh\ntg login work --api-id \u003cID\u003e --api-hash \u003cHASH\u003e\n# paste the login code from your Telegram app\n\ntg auth switch work\ntg auth list\n```\n\nPass `--qr` to `auth login` for QR login instead.\n\n## Command Map\n\n### Frequent\n\n| Command | Purpose |\n| --- | --- |\n| `tg login \u003cname\u003e` | Shortcut for `tg auth login \u003cname\u003e`. |\n| `tg logout [name]` | Shortcut for `tg auth logout [name]`. |\n| `tg send \u003cref\u003e [text...]` | Shortcut for `tg msg send \u003cref\u003e [text...]`. Repeat `--file` to attach media. |\n| `tg reply \u003cmsg-ref\u003e [text...]` | Reply to one message. Repeat `--file` to attach media. |\n| `tg inbox` | Show recent dialogs with unread counts and last messages. |\n| `tg read \u003cref\u003e` | Shortcut for `tg msg list \u003cref\u003e`. |\n| `tg digest \u003cref\u003e` | Compact history view for one chat. |\n| `tg resolve \u003cref\u003e` | Resolve one user, chat, bot, or channel. |\n\n### Account, Session, Config\n\n| Command | Purpose |\n| --- | --- |\n| `tg auth login \u003cname\u003e` | Create an account slot and log in. `--no-login` creates the slot only; `--force` re-runs auth. |\n| `tg auth logout [name]` | Revoke this CLI session. `--purge` also removes local account files. |\n| `tg auth list` | List local account slots. |\n| `tg auth switch \u003cname\u003e` | Set `default_account` for later commands. |\n| `tg auth status [name]` | Show local account health. `--probe` adds a live Telegram check. |\n| `tg session list` | List remote Telegram authorizations. |\n| `tg session revoke [hash]` | Revoke a remote session, or use `--all-others` to keep only this CLI session. |\n| `tg password set` | Set or rotate the Telegram cloud password. |\n| `tg password disable` | Remove the Telegram cloud password. |\n| `tg config get \u003ckey\u003e` | Read one config value. `--no-redact` shows `api_hash` verbatim. |\n| `tg config set \u003ckey\u003e \u003cvalue\u003e` | Write one config value. `--force` is required for `api_hash`. |\n| `tg config unset \u003ckey\u003e` | Remove one config value. |\n| `tg config edit` | Open `$VISUAL` / `$EDITOR` on the config file with rollback on parse failure. |\n| `tg config path` | Print the resolved config path. |\n| `tg config show` | Print merged config with secrets redacted. |\n\n### Daemon\n\nA per-account background service that holds a long-lived MTProto session\nso subsequent commands skip the dial / auth-resume cost (~1 s → ~0.25 s)\nand `tg watch` can stream real-time updates over a Unix socket instead\nof opening its own connection. Registration uses the host's native\nservice manager: launchd on macOS, systemd-user on Linux. The daemon is\noptional — every command still works without one. Add `--no-daemon` to\nany command to force a fresh MTProto session even when a daemon is\nreachable.\n\n| Command | Purpose |\n| --- | --- |\n| `tg daemon install` | Register the per-account daemon with the host service manager. `--force` reinstalls; `--log-file` / `--log-max-mb` tune logging. |\n| `tg daemon uninstall` | Remove the service registration. Keeps `daemon.log` and `updates.ndjson` so a re-install can pick them up. |\n| `tg daemon start` / `tg daemon stop` | Ask the OS to start or stop the service. |\n| `tg daemon status` | JSON-emitting status (installed / running / pid / log + updates paths). |\n| `tg daemon logs [-f] [-n N]` | Tail the daemon log; `-f` follows. |\n\nDaemon artifacts live under `~/.config/tg/accounts/\u003caccount\u003e/daemon/`:\n`daemon.log` (service stdout+stderr, rotated at 10 MB by default),\n`updates.ndjson` (append-only stream of every MTProto update — tailable\neven without a connected subscriber), and `daemon.sock` (Unix socket\nclient commands route through when present).\n\n### Chats, Messages, Search\n\n| Command | Purpose |\n| --- | --- |\n| `tg chat list` | List dialogs. |\n| `tg chat info \u003cref\u003e` | 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). |\n| `tg chat create \u003ctitle\u003e` | Create a supergroup. `--forum` enables topics; `--about` sets the description. |\n| `tg chat delete \u003cref\u003e` | 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`. |\n| `tg chat edit \u003cref\u003e` | Edit a supergroup: `--title`, `--about`, `--public \u003cname\u003e` / `--private`; toggles: `--forum`/`--no-forum`, `--hide-members`/`--show-members`, `--hide-history`/`--show-history`, `--slow-mode \u003cs\u003e`, `--no-forwards`/`--allow-forwards`, `--need-approval`/`--no-need-approval` (public only). |\n| `tg chat topic list \u003cref\u003e` | List a forum supergroup's topics. `--search` filters by title; `--limit` caps results (single page only, ~100 max — pagination not implemented). |\n| `tg chat topic create \u003cref\u003e \u003ctitle\u003e` | Create a topic. `--icon-color`, `--icon-emoji`, and `--random-id` (idempotent retry). |\n| `tg chat topic info \u003cref\u003e \u003ctopic-id\u003e` | Show details for one topic. |\n| `tg chat topic mute \u003cref\u003e \u003ctopic-id\u003e` / `tg chat topic unmute \u003cref\u003e \u003ctopic-id\u003e` | Mute or unmute a single topic. Mute takes `--duration`, `--until`, or `--forever` (default forever). |\n| `tg chat topic read \u003cref\u003e \u003ctopic-id\u003e` | Mark a topic as read. |\n| `tg chat topic edit \u003cref\u003e \u003ctopic-id\u003e` | Rename (`--title`), close/reopen (`--close`/`--reopen`), hide/unhide (`--hide`/`--unhide`). |\n| `tg chat topic pin \u003cref\u003e \u003ctopic-id\u003e` / `tg chat topic unpin \u003cref\u003e \u003ctopic-id\u003e` | Pin or unpin a topic. |\n| `tg chat topic delete \u003cref\u003e \u003ctopic-id\u003e` | Delete a topic and its history. Prompts unless `--yes`. |\n| `tg channel create \u003ctitle\u003e` | Create a broadcast channel. `--about` sets the description. |\n| `tg channel delete \u003cref\u003e` | Delete a channel (irreversible). Prompts unless `--yes`. |\n| `tg channel edit \u003cref\u003e` | Edit a channel: `--title`, `--about`, `--public \u003cname\u003e` / `--private`; toggles: `--no-forwards`/`--allow-forwards`, `--signatures`/`--no-signatures`. |\n| `tg channel discussion link \u003cchannel\u003e \u003cgroup\u003e` | Link a supergroup as the channel's discussion group (comments). |\n| `tg channel discussion unlink \u003cchannel\u003e` | Unlink the channel's discussion group. |\n| `tg channel discussion candidates` | List supergroups eligible to be a discussion group. |\n| `tg chat mark-read \u003cref\u003e` | Mark a chat as read. `--max-id` limits the range. |\n| `tg chat join \u003cref\u003e` | Join a channel, group, or invite link (request-needed links report `requested`). |\n| `tg chat join list \u003cref\u003e` | List pending join requests. `--link` limits to one invite link. |\n| `tg chat join approve \u003cref\u003e \u003cuser\u003e...` / `deny ...` | Approve/reject specific users, or `--all` (optionally `--link`) for every pending request. |\n| `tg chat leave \u003cref\u003e` | Leave a channel or supergroup. Prompts unless `--yes`. |\n| `tg chat mute \u003cref\u003e` | Mute notifications with `--duration`, `--until`, or `--forever`. |\n| `tg chat unmute \u003cref\u003e` | Restore notifications. |\n| `tg chat archive \u003cref\u003e` | Move a chat to the archive folder. |\n| `tg chat unarchive \u003cref\u003e` | Move a chat back to the main folder. |\n| `tg chat pin \u003cref\u003e` | Pin a chat to the top of the chat list. |\n| `tg chat unpin \u003cref\u003e` | Unpin a chat from the top of the chat list. |\n| `tg chat photo set \u003cref\u003e \u003cpath\u003e` | Set a group/channel photo (`-` reads stdin). Also available as `tg channel photo set`. |\n| `tg chat photo clear \u003cref\u003e` | Remove a group/channel photo. Also `tg channel photo clear`. |\n| `tg chat member list \u003cref\u003e` | List members (admins show their custom `rank`/title). `--filter recent\\|admins\\|bots\\|kicked\\|banned\\|contacts`, `--search`, `--limit`; `--via-link \u003clink\u003e` lists users who joined via that invite link. |\n| `tg chat invite \u003cref\u003e \u003cuser\u003e...` | 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. |\n| `tg chat invite create \u003cref\u003e` | Create an invite link. `--title`, `--expire \u003cRFC3339\\|dur\u003e`, `--usage-limit \u003cn\u003e`, `--request-needed`. |\n| `tg chat invite list \u003cref\u003e` | List invite links. `--revoked`, `--admin \u003cuser\u003e`, `--limit`. |\n| `tg chat invite revoke \u003cref\u003e \u003clink\u003e` / `delete \u003cref\u003e \u003clink\u003e` | Revoke a link, or delete a revoked one. |\n| `tg chat ban \u003cref\u003e \u003cuser\u003e` / `tg chat unban \u003cref\u003e \u003cuser\u003e` | Ban (remove + restrict) or unban a member of a group/channel. Ban prompts unless `--yes`. |\n| `tg chat admin promote \u003cref\u003e \u003cuser\u003e` / `tg chat admin demote \u003cref\u003e \u003cuser\u003e` | Grant or revoke admin rights. `--rights \u003ckeywords\u003e` 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 \u003crank\u003e` sets a custom admin title (≤16 chars); omit `--title` to keep the current title, pass `--title \"\"` to clear it. |\n| `tg chat member set-perms \u003cref\u003e \u003cuser\u003e` | Set a member's permissions with `--deny`/`--allow` keywords (`send,media,stickers,bots,polls,links,invite,pin,info,topics`) and optional `--until \u003cRFC3339\\|dur\u003e` (default permanent). |\n| `tg chat member unset-perms \u003cref\u003e \u003cuser\u003e` | Clear all permission restrictions on a member. |\n| `tg chat perms \u003cref\u003e` | Set the group's default member permissions with `--deny`/`--allow` (same keywords). |\n| `tg msg list \u003cref\u003e` | List message history. Album members (same `grouped_id`) merge into one row with an `album` array (`--limit` counts an album as one). |\n| `tg msg info \u003cmsg-ref\u003e` | 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). |\n| `tg msg send \u003cref\u003e [text...]` | Send text. Repeat `--file \u003cpath\u003e` to attach one or more files; text becomes the first media caption. Use `--name` to override upload filenames. `--sticker \u003cref\u003e` / `--gif \u003cref\u003e` send a sticker/gif — either a `msg sticker list`/`msg gif list` ref or a `\u003cmsg-ref\u003e` of an existing one (no text/`--file`). |\n| `tg msg sticker list` | List your stickers to get a sendable `ref`. `--recent` (default), `--faved`, `--installed` (sets), `--all` (recent+faved+all sets expanded; slow). |\n| `tg msg sticker fave \u003cref\u003e` / `tg msg sticker unfave \u003cref\u003e` | Add or remove a sticker from favorites (`\u003cref\u003e` is a list ref or `\u003cmsg-ref\u003e`). |\n| `tg msg sticker add \u003cset\u003e` / `tg msg sticker remove \u003cset\u003e` | Install or uninstall a sticker set. `\u003cset\u003e` is a set short name or an `https://t.me/addstickers/\u003cname\u003e` link. |\n| `tg msg gif list` | List your saved GIFs, each with a sendable `ref`. |\n| `tg msg poll \u003cref\u003e \u003cquestion\u003e \u003coption\u003e...` | Send a poll (≥2 options). `--multiple`, `--public` (default anonymous); `--correct \u003cn\u003e` makes it a quiz with optional `--explanation`. |\n| `tg msg vote \u003cmsg-ref\u003e \u003coption-number\u003e...` | Vote on a poll by 1-based option number (multiple numbers for multiple-choice polls); `--retract` to take back your vote. |\n| `tg msg download \u003cmsg-ref\u003e` | Download photo, video, document, or other message media. Defaults to the media filename; use `-o/--output` for a file path or existing directory. |\n| `tg msg edit \u003cmsg-ref\u003e` | Edit a message. |\n| `tg msg delete \u003cmsg-ref\u003e...` | Delete messages. Add `--revoke` when deleting for everyone is required. |\n| `tg msg forward \u003cmsg-ref\u003e... --to \u003cref\u003e` | Forward messages. |\n| `tg msg react \u003cmsg-ref\u003e` | Set or clear a reaction. |\n| `tg msg pin \u003cmsg-ref\u003e` / `tg msg unpin \u003cmsg-ref\u003e` | Pin or unpin a message. |\n| `tg msg schedule-list \u003cref\u003e` | List scheduled messages. |\n| `tg msg schedule-cancel \u003cref\u003e \u003cid\u003e...` | Cancel scheduled messages. |\n| `tg msg link \u003cmsg-ref\u003e` | Print the public `t.me` link for a message when available. |\n| `tg watch [\u003cref\u003e...]` | 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. |\n| `tg search msg \u003cquery\u003e` | Search messages globally, or use `--in \u003cref\u003e` for one chat. |\n| `tg search chat \u003cquery\u003e` | Search chats, users, channels, and bots. |\n\n### Contacts And Profile\n\n| Command | Purpose |\n| --- | --- |\n| `tg contact list` | List contacts. `--blocked` lists blocked users instead. |\n| `tg contact add \u003cphone\u003e` | Add a contact by phone number. |\n| `tg contact delete \u003cref\u003e` | Delete a contact. |\n| `tg contact block \u003cref\u003e` | Block a user, bot, or channel. |\n| `tg contact unblock \u003cref\u003e` | Unblock a user, bot, or channel. |\n| `tg contact report \u003cref\u003e` | Report a peer to Telegram. `--reason` (spam (default), violence, porn, child-abuse, copyright, fake, drugs, personal-details, geo-irrelevant, other), `--message \u003ccomment\u003e`, `--block` (also block the peer). Prompts unless `--yes`. |\n| `tg me` | Print the current Telegram identity. |\n| `tg profile set-name \u003cfirst\u003e` | Set first name; `--last` sets or clears last name. |\n| `tg profile set-username \u003cusername\u003e` | Set or clear the public username. |\n| `tg profile set-bio \u003ctext\u003e` | Set bio; `-` reads stdin. |\n| `tg profile set-photo \u003cpath\u003e` | Set profile photo; `-` reads stdin bytes. |\n| `tg profile delete-photo` | Remove the current profile photo. Prompts unless `--yes`. |\n| `tg profile set-status \u003conline|offline\u003e` | Set online visibility status. |\n\nPeer refs accept usernames (`@name` or `name`), phone numbers, `me`, `saved`,\nsupported `t.me` / `tg://resolve` links, and the copy-paste refs printed by\n`tg chat list`: `u:\u003cid\u003e:\u003caccess_hash\u003e` for users, `g:\u003cid\u003e` for legacy groups,\nand `c:\u003cid\u003e:\u003caccess_hash\u003e` for channels or supergroups. Numeric IDs still work\nwhen the local peer cache is warm, but the printed refs are the stable CLI form.\nMessage refs are `\u003cpeer-ref\u003e:\u003cmessage-id\u003e` and are printed by `tg read` /\n`tg msg list`, for example `@news:42` or `c:100:555:42`.\n\nThe old `tg account` group has been removed. Use `tg auth login`, `tg auth list`,\nand `tg auth switch` instead.\n\n## Output\n\nHuman output by default. Add `--json=\u003cfields\u003e` to get structured output.\nList commands emit ndjson (one JSON object per line), not a JSON array, so\nparse line by line or collect with `jq -s` (e.g. `tg read @x --json | jq -s .`);\nscalar commands emit a single object.\n\n```sh\ntg auth list --json=name,state,api_id\n# {\"name\":\"work\",\"state\":\"AUTHED\",\"api_id\":12345}\n\ntg read @news --limit 1 --json\n# {\"ref\":\"@news:42\",\"id\":42,\"date\":\"...\",\"from\":{\"ref\":\"@alice\",\"id\":123,\"type\":\"user\",\"title\":\"Alice\",\"username\":\"alice\",\"link\":\"https://t.me/alice\"},\"text\":\"hello\"}\n\ntg auth list --json=name,state --jq='.name'\n# work\n\ntg auth list --json=name,state --template='{{range .}}{{.name}}{{\"\\n\"}}{{end}}'\n# work\n```\n\n`--jq` and `--template` refine JSON output and are only valid with\n`--json`. `--output=json` is equivalent to `--json` with all fields.\n\n## Configuration\n\n`~/.config/tg/config.toml`, `0600`. Everything is optional except `version`.\n\n```toml\nversion = 1\ndefault_account = \"work\"\napi_id = 12345\napi_hash = \"...\"\n\n[output]\nformat = \"human\"   # or \"json\"\n\n[log]\nlevel = \"warn\"     # error | warn | info | debug\n\n[flood_wait]\nmode = \"fail\"      # or \"wait\"\nmax_seconds = 30\n```\n\nValues can also come from `TG_*` environment variables or command flags.\nPrecedence: **flag \u003e env \u003e config file \u003e default**.\n\n## Exit Codes\n\n| Code | Meaning |\n| --- | --- |\n| 0 | Success. Empty successful results also exit 0. |\n| 1 | Unknown error, or an error that was already printed by the command. |\n| 2 | Usage or configuration error. |\n| 3 | Authentication is required, expired, or revoked. |\n| 4 | Peer or message could not be found, or a ref was ambiguous. |\n| 5 | Telegram says the peer/message/action is forbidden. |\n| 6 | Telegram returned `FLOOD_WAIT` or rate/quota exhaustion. |\n| 7 | Network or transport failure. |\n| 8 | Conflict-like operation state: current session, invalid invite, revoke required, or bad cloud password. |\n| 9 | Internal precondition, numeric peer cache miss, unsupported operation, missing media, or unavailable message link. |\n| 72 | Another `tg` process holds the account lock. |\n| 73 | User declined a confirmation prompt. |\n| 130 | Interrupted by SIGINT / Ctrl+C. |\n\nUnder `--json`, errors are emitted on stderr as a single JSON object with\n`error.code`, `error.message`, and `exit_code` fields. stdout stays data-only.\nWhen the failure is a Telegram RPC error, `error.rpc_error` carries the exact\nTelegram enum (e.g. `CHAT_ADMIN_REQUIRED`) for programmatic matching — present\neven for errors that aren't mapped to a friendly `code`/`message`.\n\n## Shell completion\n\n```sh\ntg completion bash   \u003e /usr/local/etc/bash_completion.d/tg\ntg completion zsh    \u003e \"${fpath[1]}/_tg\"\ntg completion fish   \u003e ~/.config/fish/completions/tg.fish\n```\n\nAccount names, enum flags, and recently used peer/message refs autocomplete.\n\n## License\n\nTBD.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvika2603%2Ftelegram-cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvika2603%2Ftelegram-cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvika2603%2Ftelegram-cli/lists"}