user needs to set up Telegram CLI for the first time, authenticate or log in to a Telegram account, re-authenticate an expired session, or configure a profile.
Scanned 9/2/2026
Install to Claude Code
npx -y skills add terrylica/cc-skills --skill setup --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Setup?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/terrylica-setup-efa64e54)More formats (shields.io, HTML) on the badges page.
---
name: setup
description: user needs to set up Telegram CLI for the first time, authenticate or log in to a Telegram account, re-authenticate an expired session, or configure a profile.
allowed-tools: Bash, Read, Write, AskUserQuestion
disable-model-invocation: false
---
> **Prerequisite — `cc-plugin-root`.** This skill resolves its scripts with `cc-plugin-root <plugin>`
> (the `CLAUDE_PLUGIN_ROOT` placeholder is not a shell variable and expands to empty). If the command is missing, run
> `/itp:setup` (its first step installs it), or link it directly:
>
> ```bash
> mkdir -p ~/.local/bin && ln -sfn \
> ~/.claude/plugins/marketplaces/cc-skills/scripts/cc-plugin-root ~/.local/bin/cc-plugin-root
> ```
# Telegram CLI Setup
One-time (or re-)authentication of a personal Telegram account for the GramJS CLI.
> **Self-Evolving Skill**: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.
## Engine + session model (read first)
The CLI uses **GramJS** (MTProto). Each profile's login is a **GramJS StringSession**
stored at `~/.local/share/gramjs/<profile>.session`. The Telegram API id/hash come
from 1Password at runtime. (Historical note: this replaced the Telethon/`uv`
implementation in 2026-06; old `~/.local/share/telethon/*.session` files are not
reused — accounts log in once more here.)
```bash
ROOT="$(cc-plugin-root tlg)"
SCRIPT="$ROOT/scripts/tg-cli.ts"
```
## Profiles
| Profile | 1Password Item | Item UUID | Phone |
| ------------- | -------------------------------- | ---------------------------- | ------------ |
| `eon` | Telegram API - EonLabsOperations | `iqwxow2iidycaethycub7agfmm` | +15559876543 |
| `missterryli` | Telegram API - missterryli (CN) | `dk456cs3v2fjilppernryoro5a` | +86 (CN) |
## Prerequisites
- `bun` available, and deps installed once: `cd "$(dirname "$SCRIPT")" && bun install`
- 1Password CLI (`op`) signed in; the item above present in the `Claude Automation` vault.
## Auth is non-interactive (3 steps)
The Bash tool has no stdin, so the CLI never prompts. Authentication is split into
`send-code` (requests the code) and `sign-in` (submits it). Get the code from the
user with **AskUserQuestion** between the two steps.
### Step 0 — check current state (no SMS sent)
```bash
bun "$SCRIPT" check-auth eon # exit 0 + JSON if authorized; exit 1 if not
```
If it reports `authorized: true`, you're done. Otherwise continue.
### Step 1 — request a login code
```bash
bun "$SCRIPT" send-code eon
# → JSON: { "status": "code_sent", "phone": "...", "phone_code_hash": "<HASH>", ... }
```
Telegram delivers the code to the account's **Telegram app first**, then SMS. The
code **expires within a couple of minutes** — move straight to Step 2.
### Step 2 — get the code from the user (AskUserQuestion)
Ask the user for the digits (they type them in the "Other" box). Also ask whether
they have two-factor (cloud password) enabled.
### Step 3 — sign in with the code
```bash
bun "$SCRIPT" sign-in eon --code <CODE> --hash <HASH>
# 2FA enabled? add: --password '<cloud password>'
# → JSON: { "authorized": true, "user_id": ..., "username": ..., "session_file": ... }
```
Run `sign-in` **once** per code — a failed/duplicate attempt invalidates the code
(`PHONE_CODE_EXPIRED`); if that happens, redo Step 1 for a fresh code.
### Step 4 — verify
```bash
bun "$SCRIPT" whoami -p eon
```
## Anti-Patterns (NEVER DO)
| Anti-Pattern | Why It Fails |
| ---------------------------------------------------- | ------------------------------------------------------------------------ |
| Expecting an interactive login prompt | The CLI never reads stdin; use `send-code` + `sign-in` |
| Running `sign-in` twice with the same code | The first attempt consumes it → `PHONE_CODE_EXPIRED`; request anew |
| Dawdling between `send-code` and `sign-in` | Codes expire in ~minutes; collect the code immediately and sign in |
| Reusing an old `~/.local/share/telethon` session | Wrong format/engine — GramJS sessions live under `~/.local/share/gramjs` |
| Checking only file existence for "is it authorized?" | A session file can exist but be expired — use `check-auth` |
## Session Management
| File | Purpose |
| ------------------------------------------- | ------------------------------- |
| `~/.local/share/gramjs/eon.session` | EonLabsOperations StringSession |
| `~/.local/share/gramjs/missterryli.session` | missterryli StringSession |
Sessions expire when revoked in Telegram → Settings → Devices, or after prolonged
inactivity. When expired, `check-auth` reports `authorized: false`; rerun the 3-step flow.
## Adding New Profiles
Add the profile to the `PROFILES` map in `scripts/tg-cli.ts` and store credentials in
the `Claude Automation` 1Password vault with fields `App ID`, `App API Hash`, and
`Phone Number`. (Override per-invocation with `TELEGRAM_API_ID`/`TELEGRAM_API_HASH`
env vars to skip 1Password.)
## Post-Execution Reflection
After this skill completes, check before closing:
1. **Did `check-auth` confirm an authorized session?** If not, fix the step/error that blocked it.
2. **Did the CLI's auth interface drift?** If `send-code`/`sign-in` flags changed, update the commands above.
3. **Was a workaround needed?** Capture it here so the next setup doesn't rediscover it.
Only update if the issue is real and reproducible — not speculative.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!