Multi-account¶
tgctl-go supports multiple Telegram accounts on the same machine
with isolated stores per account.
Why isolate¶
Each account gets its own:
- gotd
tg.session(auth token) telegram.sqlite(cached messages)audit.log(write trail)media/(downloaded file-backed Telegram media)tg.session.lock(concurrent-process guard)
This means a write you make as work cannot leak into personal's
audit log, and a backfill on one account doesn't pollute the other's
SQLite. It also means losing or rotating one account's session
doesn't affect the other.
Layout on disk¶
~/Projects/your-app/
├── accounts/
│ ├── default/
│ │ ├── tg.session
│ │ ├── telegram.sqlite
│ │ ├── audit.log
│ │ └── media/
│ ├── work/
│ │ ├── tg.session
│ │ ├── telegram.sqlite
│ │ ├── audit.log
│ │ └── media/
│ └── .current ← which one is "default" right now
└── ...
If you don't use accounts-add, everything lives at
accounts/default/. The account name default is reserved and is
auto-created by the first permitted writable operation. Read-only mode never
creates it.
Commands¶
tg accounts-add <name>¶
Creates a new isolated account directory.
Then log in as that account:
accounts-add is a command, not a flag. This is valid:
This is not:
tg accounts-list¶
Lists all configured accounts, showing which is current.
tg accounts-show¶
Show paths and current account.
tg accounts-use <name>¶
Set the default account selector. Every subsequent command without
an explicit --account uses this one.
tg accounts-remove <name>¶
Delete an account directory. Permanent — back up the files first if you want them.
Selecting an account at command time¶
Account selection has one exact precedence order, highest first:
--account <name>flag on the commandTG_ACCOUNT=<name>environment variable- The current selector at
accounts/.current - Falls back to
default
tg --account work send "$TG_CHAT_ID" "..." --allow-write
TG_ACCOUNT=work tg me
tg accounts-use work && tg me
Test account walkthrough¶
For agent development, create a separate account directory and keep the account selector explicit:
cd "$TGCTL_GO_CHECKOUT"
tg accounts-add test
tg --account test login
tg --account test me
tg --account test backfill-entities --allow-write
tg --account test discover --allow-write
tg --account test stats
The files are isolated under:
Then test self-chat read/write:
tg --account test send "$TG_CHAT_ID" "hello from the sandbox account" --allow-write --json
tg --account test show "$TG_CHAT_ID" --limit 5 --json
If you rely on .env, run these from the directory containing .env.
If you run from ~/accounts/test or another directory, export
TG_API_ID and TG_API_HASH first.
Agents should usually use --account test on every call. Use
accounts-use test only for interactive shell work where changing the
default account is intentional.
The default destination for download-media and media-enabled backfill is
also selected-account scoped:
download-media --output <directory> overrides that destination for one
call. Account selection still controls which session, cache, and audit log are
used.
--read-only and TG_READONLY=1 prevent both Telegram writes and local-state
writes or creation. They therefore do not create a missing account directory,
database, session, audit log, or media directory, even if --allow-write is
also present.
Recommended use cases¶
- Personal + business split — keep work DMs in
accounts/work/and your personal account untouched - Test accounts for development — develop reply flows against
accounts/test/with a throwaway phone number, then promote toaccounts/default/once stable - Temporary backup account — register a second SIM as
accounts/backup/in case your main account hits a SpamBot restriction. Won't help recover the main, but lets you keep operating while you appeal.
See also¶
- Install — initial
.envand login - Safety model — per-account audit logs
- Library use —
--accountfrom agent subprocesses