{"id":50647277,"url":"https://github.com/ChuYanLon/telegram.nvim","last_synced_at":"2026-06-09T08:01:12.487Z","repository":{"id":359281042,"uuid":"1243023030","full_name":"ChuYanLon/telegram.nvim","owner":"ChuYanLon","description":"A Telegram chat client inside Neovim, powered by TDLib + TypeScript + Lua","archived":false,"fork":false,"pushed_at":"2026-06-05T06:53:33.000Z","size":10900,"stargazers_count":9,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-05T08:12:07.832Z","etag":null,"topics":["chat","lua","neovim","neovim-plugin","plugin","tdlib","telegram","tui","typescript"],"latest_commit_sha":null,"homepage":"https://chuyanlon.github.io/telegram.nvim","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ChuYanLon.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","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-05-19T01:31:23.000Z","updated_at":"2026-06-05T06:51:47.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ChuYanLon/telegram.nvim","commit_stats":null,"previous_names":["chuyanlon/telegram.nvim"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/ChuYanLon/telegram.nvim","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChuYanLon%2Ftelegram.nvim","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChuYanLon%2Ftelegram.nvim/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChuYanLon%2Ftelegram.nvim/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChuYanLon%2Ftelegram.nvim/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ChuYanLon","download_url":"https://codeload.github.com/ChuYanLon/telegram.nvim/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChuYanLon%2Ftelegram.nvim/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34096955,"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-09T02:00:06.510Z","response_time":63,"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":["chat","lua","neovim","neovim-plugin","plugin","tdlib","telegram","tui","typescript"],"created_at":"2026-06-07T14:00:19.052Z","updated_at":"2026-06-09T08:01:12.473Z","avatar_url":"https://github.com/ChuYanLon.png","language":"Lua","funding_links":[],"categories":["Utility"],"sub_categories":["Cursorline"],"readme":"# telegram.nvim\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n[![Node](https://img.shields.io/badge/node-%3E%3D18-brightgreen)](package.json)\n[![CI](https://github.com/ChuYanLon/telegram.nvim/actions/workflows/ci.yml/badge.svg)](https://github.com/ChuYanLon/telegram.nvim/actions/workflows/ci.yml)\n[![Neovim](https://img.shields.io/badge/neovim-%3E%3D0.9-blueviolet)](https://neovim.io)\n\nA Telegram chat tool for neovim, similar to telega.el\n\nBackend powered by TDLib + Node.js (TypeScript), frontend in pure Lua with HTTP + WebSocket communication.\n\n\u003e 💬 Join the discussion on Telegram: [t.me/+h4aEOaABJJ1mMzhl](https://t.me/+h4aEOaABJJ1mMzhl)\n\n## Screenshots\n\n\u003e Partial screenshots — see Feature Status below for the full list.\n\n| | |\n|-|-|\n| \u003cimg width=\"400\" src=\"https://github.com/user-attachments/assets/0ff29034-aaca-4d3a-8994-3418436f20d0\" /\u003e | \u003cimg width=\"400\" src=\"https://github.com/user-attachments/assets/cb7b56cd-e498-47b2-9808-49af00b0d2c8\" /\u003e |\n| \u003cimg width=\"400\" src=\"https://github.com/user-attachments/assets/46ec08d6-a275-47e0-a196-7d0eab7a51d5\" /\u003e | \u003cimg width=\"400\" src=\"https://github.com/user-attachments/assets/80f9c8e0-edc6-43a4-a6b5-e34b48a3d2fa\" /\u003e |\n| \u003cimg width=\"400\" src=\"https://github.com/user-attachments/assets/bb72b4a5-15e3-4cf5-89cb-c4673cea40db\" /\u003e | \u003cimg width=\"400\" src=\"https://github.com/user-attachments/assets/2bedeb8e-ced1-4173-a7fd-5073344155b3\" /\u003e |\n| \u003cimg width=\"400\" src=\"https://github.com/user-attachments/assets/9efb7eac-0175-4b00-bf5c-ba48cee129c6\" /\u003e | \u003cimg width=\"400\" src=\"https://github.com/user-attachments/assets/8e14abba-cbd2-44d7-add2-db16e08ca38e\" /\u003e |\n| \u003cimg width=\"400\" src=\"https://github.com/user-attachments/assets/20f1304d-7f6c-4fba-82f7-b7510d590481\" /\u003e | \u003cimg width=\"400\" src=\"https://github.com/user-attachments/assets/abc5d65b-1799-4459-93f0-734b886cef07\" /\u003e |\n| \u003cimg width=\"400\" src=\"https://github.com/user-attachments/assets/a5f07ec6-bc8c-4a78-89cd-14d4c40520e9\" /\u003e | \u003cimg width=\"400\" src=\"https://github.com/user-attachments/assets/8b50a9ae-8ca1-44c3-9ea1-4e3aa4631e56\" /\u003e |\n| \u003cimg width=\"400\" src=\"https://github.com/user-attachments/assets/79c6a18d-eeef-4a9b-97cd-1078a02db548\" /\u003e | \u003cimg width=\"400\" src=\"https://github.com/user-attachments/assets/480cccf9-6b2b-420f-8a01-6553b78cc92e\" /\u003e |\n| \u003cimg width=\"400\" src=\"https://github.com/user-attachments/assets/f5f98e2a-b823-42e0-b5e4-8ccdfaee0739\" /\u003e | \u003cimg width=\"400\" src=\"https://github.com/user-attachments/assets/f03d1de1-55e0-49ba-ac76-2117515d2db3\" /\u003e |\n\n## Feature Status\n\n### What works\n\n- [x] Login with phone number, verification code, and 2FA password\n- [x] Session persists across restarts (no re-login)\n- [x] `:TgLogout` to clear auth and start fresh\n- [x] Group list with unread badges, inline fuzzy search (Snacks picker with `vim.ui.select` fallback)\n- [x] Open/close chats, switch between groups\n- [x] Scroll infinitely in both directions (older and newer messages)\n- [x] Receive new messages in real-time via WebSocket\n- [x] Typing indicators and online member count\n- [x] Cursor position is remembered per chat (tracked by message ID)\n- [x] Messages are marked as read when opening a chat; per-message read tracking with `last_read_id` persistence\n- [x] Unread-aware loading — opens at first unread message with unread divider\n- [x] Date separators between messages, loading indicators, and empty state\n- [x] Send plain text messages (with reply context)\n- [x] Send messages with formatting — type markdown syntax (`**bold**`, `### heading`) in input; Telegram clients (Android, iOS, Desktop) parse markdown natively, Neovim buffer renders via markdown treesitter\n- [x] Edit your own messages\n- [x] Delete your own messages (Delete for me / Revoke for everyone)\n- [x] Forward messages to another chat\n- [x] Reply to a message with quote context\n- [x] Search messages and jump to the result position\n- [x] URLs are highlighted and clickable\n- [x] Code blocks (backtick) are detected and formatted\n- [x] Single-panel chat layout with floating input popup\n- [x] Adjustable panel position — `panel_position` option (`\"right\"`, `\"left\"`, `\"bottom\"`, `\"top\"`); width via `g:telegram_width` (default 50), height via `g:telegram_height` (default 15)\n- [x] `?` opens a help popup with all keybindings\n- [x] Target line highlighting (reply/edit/delete/forward) using theme's `Diff*` colors\n- [x] `:TgPr` — create GitHub PR with branch picker, auto-fill, optional merge\n- [x] `:TgIssue` — list, create branch, close, assign, open in browser\n- [x] Proxy support (SOCKS5 / HTTP) for restricted regions\n- [x] Service messages shown as readable text with prefix symbols\n- [x] Download HD media — `@refreshmedia` downloads highest-quality version of photos/videos under cursor (async, non-blocking)\n- [x] Context-aware tool picker — `@` only shows applicable tools (e.g. `refreshmedia` only on media messages)\n- [x] Wake-up safe — messages received after sleep are batched and rendered at once, no Neovim freeze\n- [x] Admin custom titles — shows `[头衔]` next to admin names in messages and member list; admins without title show `[Administrator]`\n- [x] Photo / sticker / video / file inline preview — rendered as `![Photo](/path)` markdown; works with image renderers like `snacks.nvim` image module\n- [x] Private chats (direct 1-on-1 messages) — press `c` on a message to open DM with the sender\n- [x] Channel support — view channels and their messages; admin tools (member list, change info) shown based on permissions\n- [x] Group management — view members (including admins and creator), ban/unban, restrict/unrestrict, promote/demote admins, add members by @username\n- [x] Group settings — change title/description, granular default permissions editor (14 permission types with toggle-all), leave group, unsubscribe from channel, delete history\n- [x] Invite links — create (with optional member limit and expiration), view, edit, and revoke invite links\n- [x] Pin / unpin messages — press `p` on a message to pin/unpin; permission check for `can_pin_messages`\n- [x] React to messages — press `r` to open reaction picker with 40+ verified emojis; same emoji toggles off, different auto-switches; real-time sync via WebSocket\n- [x] Real-time sync between devices — edits, deletions, reactions, group info changes, user name/status changes sync via WebSocket from other clients\n- [x] Online status — session reports as online with periodic heartbeat; device shown as `telegram.nvim` in Telegram's active sessions list\n- [x] Favorites (Saved Messages) — dedicated chat with 📌 icon in picker; press `s` on any message to save with confirmation\n- [x] View counts — channel messages show `👀 N` footer with k/M formatting; real-time update via WebSocket\n- [x] Read receipts — outgoing private messages show `(read HH:MM)` in header when read by recipient\n- [x] Edited indicator — edited messages show `[edited]` footer\n- [x] Copy message text — press `yy` to copy message text to system clipboard\n- [x] Toggle title bar — `@toggleheader` shows/hides the floating title bar; configurable via `hide_title` option\n- [x] Connection status — title bar shows red dot when disconnected from Telegram\n- [x] Input editor redesign — bottom panel with context preview; markdown syntax highlighting while typing\n- [x] Customizable keymaps — all keys configurable via `setup({ keys = { ... } })`\n- [x] Configurable panel position — `panel_position = \"right\" | \"left\" | \"bottom\" | \"top\"`\n- [x] Theme adaptation — all highlight groups derive from your Neovim theme (`Comment`, `DiffAdd`, `DiagnosticOk`, etc.)\n\n### What doesn't work yet\n\n- [ ] **Send media** (photos, videos, files, audio) — can't upload anything yet\n- [ ] **Send stickers / GIFs**\n- [ ] **Create polls**\n- [ ] **Scheduled messages**\n- [ ] **Poll, contact, location, dice, game, call display** — fallback shows label, content not interactive\n- [ ] **Inline bots** / bot commands\n\n### Customizing keys\n\n```lua\nrequire(\"telegram\").setup({\n  keys = {\n    input_editor = \"I\",  -- rebind i → I\n    refresh = \"\u003cF5\u003e\",\n    help = \"\u003cF1\u003e\",\n    ban = false,  -- disable ban key\n  },\n})\n```\n\nAll available keys and their defaults:\n\n| Key name | Default | Action |\n|----------|---------|--------|\n| `tool_picker` | `@` | Open tool picker |\n| `input_editor` | `i` | Open message input editor |\n| `reply` | `\u003cCR\u003e` | Reply to / jump to message |\n| `edit` | `e` | Edit own message |\n| `delete` | `d` | Delete / revoke message |\n| `forward` | `f` | Forward message |\n| `pin` | `p` | Pin / unpin message |\n| `reaction` | `r` | React to message (opens emoji picker) |\n| `save` | `s` | Save message to Favorites (with confirmation) |\n| `copy` | `yy` | Copy message text to clipboard |\n| `refresh` | `G` | Refresh messages, jump to bottom |\n| `ban` | `B` | Ban message sender |\n| `open_dm` | `c` | Open DM with message sender |\n| `help` | `?` | Toggle help popup |\n| `editor_submit` | `\u003cCR\u003e` | Submit message in editor |\n| `editor_cancel` | `\u003cEsc\u003e` | Cancel editing |\n| `help_close` | `\u003cEsc\u003e` | Close help popup |\n| `help_close_q` | `q` | Close help popup (alt) |\n| `perms_down` | `j` | Permission editor: move down |\n| `perms_up` | `k` | Permission editor: move up |\n| `perms_toggle` | `\u003cTab\u003e` | Permission editor: toggle item |\n| `perms_up_alt` | `\u003cS-Tab\u003e` | Permission editor: move up (alt) |\n| `perms_save` | `\u003cCR\u003e` | Permission editor: save |\n| `perms_discard` | `\u003cEsc\u003e` | Permission editor: discard |\n\nSet any key to `false` to disable it.\n\n### Service messages\n\nSystem messages (members added, group renamed, etc.) are rendered as readable text with a prefix symbol. The text color follows the `Comment` highlight group.\n\n| Prefix | Display | Example |\n|--------|---------|---------|\n| `[+]` | Member joined | `[+] Kitty joined this group via invite link at 2026-05-28 19:49` |\n| `[+]` | Member added | `[+] Kitty added Bob at 2026-05-28 19:49` |\n| `[-]` | Member left | `[-] Kitty left the group at 2026-05-28 19:49` |\n| `[~]` | Group changed | `[~] Kitty changed the group name at 2026-05-28 19:49` |\n| `[~]` | Group photo changed | `[~] Kitty changed the group photo at 2026-05-28 19:49` |\n| `[~]` | Group upgraded | `[~] Kitty upgraded from a basic group at 2026-05-28 19:49` |\n| `[*]` | Message pinned | `[*] Kitty pinned a message at 2026-05-28 19:49` |\n| `[\u003e]` | Group/topic created | `[\u003e] Kitty created this group at 2026-05-28 19:49` |\n| `[!]` | Auto-delete timer set | `[!] Kitty set auto-delete timer at 2026-05-28 19:49` |\n\n### Media labels\n\nMedia messages are shown as thumbnails or tags:\n\n| Tag | Meaning |\n|-----|---------|\n| `![Photo](/path)` | Photo sent (clickable, HD via `@refreshmedia`) |\n| `![Video](/path)` | Video sent (clickable) |\n| `![Animation](/path)` | GIF sent (clickable) |\n| `![Document](/path)` | File sent (clickable) |\n| `![Audio](/path)` | Music sent (clickable) |\n| `![Voice](/path)` | Voice message (clickable) |\n| `![Video Note](/path)` | Video message (clickable) |\n| `![Sticker](/path)` | Sticker sent (clickable) |\n| `[Poll]` | Poll created |\n| `[Contact]` | Contact shared |\n| `[Location]` | Location shared |\n| `[Dice]` | Dice rolled |\n| `[Game]` | Game played |\n| `[Call]` | Voice/video call |\n| emoji character | Animated emoji (inline text) |\n| `![Video](/thumbnail)` | Video thumbnail preview (click `@openlink` to play) |\n\n## Requirements\n\n- **Node.js** (\u003e= 18)\n- **curl**\n- **libtdjson** — TDLib shared library (minimum version **1.8.64**) — `libtdjson.so` (Linux), `libtdjson.dylib` (macOS), `tdjson.dll` (Windows)\n- **snacks.nvim** — optional, used for the chat picker with fuzzy search (falls back to `vim.ui.select` if not installed)\n- **ImageMagick** — optional, required by snacks.nvim image module to display non-PNG images (e.g. JPEG photos). Install with `brew install imagemagick` on macOS\n- **gh** (GitHub CLI) — optional, required for `:TgPr` and `:TgIssue` commands\n\n### Installing libtdjson\n\n```bash\ngit clone https://github.com/tdlib/td.git\ncd td\nmkdir build \u0026\u0026 cd build\ncmake -DCMAKE_BUILD_TYPE=Release \\\n    -DCMAKE_INSTALL_PREFIX=~/.local \\\n    -DCMAKE_CXX_FLAGS=\"-O2 -g0\" \\\n    ..\ncmake --build . --target install -j$(nproc)\nldconfig 2\u003e/dev/null || true\n```\n\n\n## Installation\n\n### lazy.nvim\n\n```lua\n{\n  \"ChuYanLon/telegram.nvim\",\n  build = \"npm i\",\n  event = \"VeryLazy\",\n  dependencies = {\n    -- \"folke/snacks.nvim\",   -- optional: enables fuzzy-find chat picker\n  },\n  keys = {\n    { \"\u003cleader\u003ett\", \"\u003ccmd\u003eTg\u003cCr\u003e\", desc = \"Toggle Telegram\" },\n    { \"\u003cleader\u003etL\", \"\u003ccmd\u003eTgLogout\u003cCr\u003e\", desc = \"Logout Telegram\" },\n    { \"\u003cleader\u003etp\", \"\u003ccmd\u003eTgPr\u003cCr\u003e\", desc = \"Create PR\" },\n    { \"\u003cleader\u003eti\", \"\u003ccmd\u003eTgIssue\u003cCr\u003e\", desc = \"Manage Issues\" },\n  },\n  cmd = {\n    \"Tg\",\n    \"TgLogout\",\n    \"TgPr\",\n    \"TgIssue\",\n  },\n  opts = {\n    -- tdlib_path = \"/path/to/libtdjson.so\",         -- optional: .so (Linux) / .dylib (macOS) / .dll (Windows)\n    -- proxy = \"socks5://127.0.0.1:7890\",             -- optional: for regions where Telegram is blocked\n  },\n}\n```\n\n`build = \"npm i\"` installs Node.js dependencies automatically on first install.\n\n## Lua API\n\n### Statusline\n\n`require(\"telegram\").lualine` is a pre-built lualine component:\n\n```lua\nrequire(\"lualine\").setup({\n  sections = {\n    lualine_x = { require(\"telegram\").lualine },\n  },\n})\n```\n\nFor other statuslines (heirline, feline, etc.):\n\n```lua\nrequire(\"telegram\").status()       -- \"disconnected\" | \"connecting\" | \"connected\" | \"error\"\nrequire(\"telegram\").status_color() -- { fg = \"#...\" }   -- color matching current status\nrequire(\"telegram\").total_unread() -- total, mentions   -- unread counts across all chats\n```\n\nDisplays `  ` with:\n- 🟢 green — connected, no unread\n- 🟡 yellow — connecting\n- ⚫ gray — disconnected\n- 🔴 red — error or has @mentions\n- Shows unread count after icon when there are new messages, e.g. `  5`\n- Appends `!` when there are @mentions, e.g. `  3!`\n\n## Commands\n\n| Command       | Description                                                                                                                   |\n| ------------- | ----------------------------------------------------------------------------------------------------------------------------- |\n| `:Tg`         | Global toggle: opens tg window if closed, hides it if open (from any buffer). First run: server + auth, then opens last chat |\n| `:TgLogout`   | Log out, clear auth data, next `:Tg` starts fresh                                                                             |\n| `:TgSend`     | Send a message: `:TgSend \u003ctext\u003e` to current chat, or `:TgSend \u003cchatId\u003e \u003ctext\u003e` to specific chat                                      |\n| `:TgTool`     | Open tool picker (`@` equivalent)                                                                                             |\n| `:TgPr`       | Propose changes from a feature branch to main — choose squash or full merge, branch auto-deletes on completion                |\n| `:TgIssue`    | Browse your assigned issues — create, close, assign, and create branches directly from an issue                               |\n\n\u003e The server runs on ports 8080/8081 (configurable via `setup({ http_port, ws_port })` or `TG_PORT`/`TG_WS_PORT` env vars). Opening `:Tg` in another Neovim instance will connect to the same server — only the instance that started it will stop it on exit.\n\n## Neovim Keymaps\n\n```lua\n-- Configure inside lazy.nvim `keys`, or map manually:\nvim.keymap.set(\"n\", \"\u003cleader\u003ett\", \"\u003ccmd\u003eTg\u003cCr\u003e\", { desc = \"Toggle Telegram\" })\nvim.keymap.set(\"n\", \"\u003cleader\u003etL\", \"\u003ccmd\u003eTgLogout\u003cCr\u003e\", { desc = \"Logout Telegram\" })\nvim.keymap.set(\"n\", \"\u003cleader\u003etp\", \"\u003ccmd\u003eTgPr\u003cCr\u003e\", { desc = \"Create PR\" })\nvim.keymap.set(\"n\", \"\u003cleader\u003eti\", \"\u003ccmd\u003eTgIssue\u003cCr\u003e\", { desc = \"Manage Issues\" })\n```\n\nIn the chat picker (`@` → chats):\n- Built-in fuzzy search (Snacks picker when available, `vim.ui.select` fallback)\n- `\u003cCR\u003e` — select chat\n- `\u003cEsc\u003e` — close\n\n## Auth Flow\n\nFirst run of `:Tg`:\n\n1. Backend starts on port 8080\n2. TDLib enters authentication flow\n3. Neovim shows an input prompt — **async and non-blocking**, you can keep editing\n4. Enter: **phone number** → **verification code** → (optional) **2FA password**\n5. On success, the group list opens automatically\n\nCancelling the input prompt (ESC / close dialog) aborts auth and cleans cached state. The next `:Tg` starts from scratch.\n\n## Configuration\n\nPass options via `setup()`:\n\n```lua\nrequire(\"telegram\").setup({\n  -- tdlib_path = \"/path/to/libtdjson.so\",  -- only if auto-detection fails\n  -- proxy = \"socks5://127.0.0.1:7890\",     -- proxy for TDLib connections\n  -- data_dir = \"/path/to/data\",            -- default: plugin root\n  -- http_port = 8080,                      -- HTTP server port\n  -- ws_port = 8081,                        -- WebSocket server port\n  -- notify_chat_types = { \"private\", \"mention\" },  -- types: \"private\", \"group\", \"channel\"; add \"mention\" for @mentions\n  -- hide_title = false,  -- start with floating title bar hidden\n  -- panel_position = \"right\",  -- \"right\" | \"left\" | \"bottom\" | \"top\"\n})\n```\n\nEnvironment variable overrides:\n\n| Env var | Overrides |\n|---------|-----------|\n| `TG_TDLIB_PATH` | `tdlib_path` |\n| `TG_PROXY` | `proxy` |\n| `TG_PORT` | HTTP server port (default: `8080`) |\n| `TG_WS_PORT` | WebSocket server port (default: `8081`) |\n| `TG_DATA_DIR` | Data directory for `tdlib_db/` and `tdlib_files/` (default: plugin root) |\n\n\nThe server auto-detects `libtdjson` on startup via:\n- **Linux**: `ldconfig -p`, common paths (`/usr/lib`, `/usr/local/lib`, `~/.local/lib`, `/usr/lib64`, `/opt/lib`), `LD_LIBRARY_PATH`, and `find`\n- **macOS**: `mdfind` and common paths (`/opt/homebrew/lib`, `/usr/local/lib`)\n- **Windows**: `where tdjson.dll` and common paths (`%LOCALAPPDATA%`, `%PROGRAMFILES%`)\n\nOverride with `setup({ tdlib_path = \"...\" })` or the `TG_TDLIB_PATH` env var.\n\n\u003e **Note on `proxy`:** In regions where Telegram is blocked (e.g. China), TDLib cannot connect to Telegram's servers directly. Set a SOCKS5 or HTTP proxy here. Supported formats:\n\u003e - `socks5://127.0.0.1:7890`\n\u003e - `socks5://user:pass@127.0.0.1:7890`\n\u003e - `http://127.0.0.1:8080`\n\n## FAQ\n\n**Q: Verification code never arrives (SMS not received)**\nA: If you're in a region where Telegram is blocked (e.g. China), TDLib needs a proxy to connect. Set `proxy` in your config:\n\n```lua\nrequire(\"telegram\").setup({\n  proxy = \"socks5://127.0.0.1:7890\",\n})\n```\n\nYour proxy needs to support SOCKS5 (e.g. ClashX, V2Ray, Shadowsocks). On Windows, a system-level VPN/proxy may already cover TDLib's traffic; on macOS, TDLib ignores system proxy settings and must be configured explicitly.\n\n**Q: \"libtdjson.so not found\" / \"Cannot find libtdjson\"**\nA: The server auto-detects the library on startup. If auto-detection fails, install TDLib (see \"Installing libtdjson\" above) or set a custom path via `setup({ tdlib_path = \"...\" })` or the `TG_TDLIB_PATH` env var.\n\n**Q: Do I need to re-authenticate every time Neovim restarts?**\nA: No. TDLib caches session state in `tdlib_db/`. Auth persists across restarts.\n\n**Q: Why does the server use TypeScript?**\nA: The backend was migrated from JavaScript to TypeScript (v0.3.0) for better type safety and maintainability in a multi-contributor project. The server runs via `tsx`, which is installed automatically by `npm install` — no extra setup needed.\n\n**Q: How do I switch accounts?**\nA: Run `:TgLogout`, or manually delete the `tdlib_db/` and `tdlib_files/` directories.\n\n**Q: Port conflict?**\nA: Default ports are 8080/8081. Configure via `setup({ http_port = ..., ws_port = ... })` or `TG_PORT`/`TG_WS_PORT` env vars. The plugin checks if a server is already running and reconnects if it's ours. If occupied by another process, startup fails — change to different ports. Server process is terminated on Neovim exit.\n\n## Development Workflow\n\n- **`main`** — stable branch, protected, no direct pushes\n- **`feat/*` / `fix/*` / `chore/*`** — feature/fix branches, created from `main`\n- PRs target `main` — use `:TgPr` to create and optionally merge\n- Merge options: **squash** or **commit**\n- After merge, GitHub auto-deletes the source branch (set in repo settings)\n- CI runs on every push and PR (test + typecheck)\n\n## Contributing\n\nAll contributions are welcome! Just open a pull request targeting `main`. See the [full guide](CONTRIBUTING.md) for details.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FChuYanLon%2Ftelegram.nvim","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FChuYanLon%2Ftelegram.nvim","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FChuYanLon%2Ftelegram.nvim/lists"}