Documentation menu
Getting started
New in v2.0
Feature deep dives
Reference
Quickstart
Quickstart
From an empty host to a delivered forward: the three install routes, the guided wizard, your first task and the checks that prove it serves.
Verified against the checkout built for v2.2.4 · updated 20 Oct 2026
On this page
This is the shortest honest path from an empty host to a message that actually lands in a destination chat. Every route below ends in the same place — one guided wizard, the same four services, the same CLI afterwards — so the install choice does not lock you in.
Before you start
Have the bot token and your numeric Telegram id ready; the wizard asks for nothing else you cannot press enter through.
| Requirement | Details |
|---|---|
| Container path | Docker Engine with the Compose v2 plugin — docker compose version has to answer. atf platform prints the exact install command for this specific distribution. |
| Native path | Python 3.11+ and either Bash (Linux, macOS, WSL) or PowerShell (Windows). scripts/setup.sh walks python3, python3.13, python3.12, python3.11 and refuses to continue when none of them is 3.11+. |
| Telegram | A bot token from @BotFather, and your own numeric Telegram user id for ADMIN_USER_ID. |
| Hardware | 1 vCPU and 512 MB RAM is enough to start four services; media staging is the only thing that wants more disk. |
| Network | Outbound access to Telegram. Ports 8088 (dashboard) and 8080 (REST API) must be free; core and logger gRPC stay inside the compose network on 50051 and 50052. |
Pick an install route
cp .env.example .env → docker compose up -d
Four containers from one file: atf-core, atf-logger, atf-api, atf-web. Nothing else is installed on the host.
Best when: A host you control with docker already present.
./scripts/setup.sh
Creates .venv, installs dependencies, puts atf on PATH and hands over to the wizard. Same program on Windows: python scripts\bootstrap.py.
Best when: A VPS or home server where you want the CLI and native services.
curl -fsSL .../install.sh | bash
Installs git and Python when missing, clones the repository and ends in the same wizard. The portable build (atf release portable → dist/atf.pyz) needs no checkout at all.
Best when: A machine you do not want to prepare by hand.
The container route is the one most operators should take. It is also the shortest: two commands after a clone.
git clone https://github.com/Opselon/AutoTelegramForward.git
cd AutoTelegramForward
# route 1 — containers only
cp .env.example .env # fill ATF_API_ID, ATF_API_HASH, ATF_BOT_TOKEN, ADMIN_USER_ID
docker compose up -d
docker compose ps # atf-core, atf-logger, atf-api, atf-web
# route 2 — native script (same wizard, no docker)
./scripts/setup.sh # venv + deps + atf on PATH + guided setup
./scripts/setup.sh --check # read-only readiness report, changes nothing
# route 3 — zero prerequisite, or the single-file build
curl -fsSL https://raw.githubusercontent.com/Opselon/AutoTelegramForward/master/install.sh | bash
atf release portable # -> dist/atf.pyz, standard library only
python3 atf.pyz setup # the same wizard, no checkout neededThe guided wizard
atf setup is one command for a machine that has never run ATF. It asks, validates, builds, then verifies — in that order, and it refuses a wrong answer instead of storing it.
Detect the host
Reads the OS, distribution and architecture, then probes
docker, the daemon anddocker compose version. On a machine without docker it offers source mode instead of failing.atf setupEvery path — installer,
setup.sh, orpython3 atf.pyz setup— lands in this one wizard.Ask only what it cannot work out
Run mode, Telegram credentials, admin id, dashboard URL, TLS and the boot-service questions. Each answer is validated as you type it; a malformed value is refused rather than stored.
atf setup --check # read-only readiness report atf setup --print-answers # emit the answers templateSecrets are typed blind and echoed back masked in a review panel before anything is written.
Write .env
The answers become
.envwith mode0600. The keys the stack cannot run without areATF_API_ID,ATF_API_HASH,ATF_BOT_TOKEN,ADMIN_USER_IDandATF_MASTER_KEY.A placeholder left in a required key is treated as missing, not as a value.
Build and start
Runs the static validator first, then builds and starts the four services in order: logger → core → api → web.
atf up # build + start the whole stack (validator-gated) atf setup --no-build --no-start # prepare .env onlyUse --force only when you have read the validator failure and accepted it.
Prove each service is serving
Inspects every service and reports container, status, state, reachability, endpoint and version. A container that started but cannot answer is reported as not serving.
atf system services # colourised table + fix hints; exit 1 if something is down atf system services --json # {services:[...], healthy:N, total:4, failing:[...]}"docker compose returned 0" is not evidence; this probe is.
What it asks, and how each answer is checked
| Question | Validator — a wrong answer is refused, never written |
|---|---|
| Run mode | docker, source or portable — anything else is refused. |
| Bot token (@BotFather) | Must match <digits>:<35+ chars>. Typed blind, stored in .env as 0600. |
api_id | Numeric and ≥ 1. Defaults to the public Telegram Desktop value when you press enter. |
api_hash | Exactly 32 hex characters, from my.telegram.org. |
| Admin user id | Numeric and ≥ 1 — your own Telegram id, not a username. |
| Dashboard URL | Must start with http:// or https://. |
| TLS domain | Optional; if you set one, a valid domain and a contact email become required. |
| Boot service / start now / mint token | Explicit yes/no answers. The boot service is a systemd unit that starts the stack at boot. |
For automation, drive the same wizard without a terminal:
atf setup --check # read-only readiness report (safe before anything exists)
atf setup --yes # take every default, never prompt (CI / cron)
atf setup --answers answers.json # non-interactive answers
atf setup --print-answers # emit the answers template
atf setup --no-build --no-start # prepare .env only
atf setup --source-wizard # bare-metal path for a machine without dockerFirst run
Two things must be true before a single message can move: the bot credentials are in .env, and the stack is up. Nothing about the token is echoed back — the CLI redacts it from every line it prints.
ATF_API_ID=17349
ATF_API_HASH=344583e45741c457fe1862106095a5eb
ATF_BOT_TOKEN=123456:ABC-DEF... # from @BotFather — never a real token in a ticket or a chat
ADMIN_USER_ID=123456789 # your numeric Telegram id
ATF_MASTER_KEY=<long random string>
ATF_WEB_URL=http://localhost:8088ATF_MASTER_KEY is what encrypts session strings, bot tokens and AI keys at rest, so generate it and keep it. Then bring the stack up and look at the board:
atf up # build + start all four services (docker path)
atf status # per-service state, ports, reachability, task counts, dashboard URL
atf validate --strict # static checks: env, compose, catalog parity, secrets, database, ports
atf doctor --fix # deeper diagnosis; repairs what it canThe dashboard is the Rust gateway plus React SPA on port 8088. The REST API answers on 8080. Open the dashboard at http://localhost:8088 and sign in with the credential the wizard minted (or with a single-use login link the bot issues — the link carries a short-lived code, never a session token).
Link your Telegram account
Forwarding happens as some Telegram account, so one has to be authorised before the first task can deliver. Open the bot in Telegram, send /start and use Login: enter the phone number in international format, then the OTP Telegram sends you, then your 2FA password if the account has one. The resulting session is encrypted with ATF_MASTER_KEY and stored in data/atf.db; the bot deletes the message that carried the credentials. The same login is available from the dashboard and the REST API. The full walkthrough, including what to do when the OTP never arrives, is in account linking.
Your first task
A task is one source list plus one target list. The bot can create it (/settings → Create task), and the CLI can create it with the same fields:
atf rules create --name "News mirror" --source @MarketNews --target @MyBroadcast
atf rules list # confirm it exists and is on
atf rules show <id> # the full task as the server sees it
# prove the pipeline before you trust it with live traffic
atf rules simulate <id> --text "Breaking: market surge t.me/spam @admin"
atf logs tail --follow -n 20 # then watch the first real delivery
atf logs stats # delivered / dropped / retried countsWhat success looks like
An install is finished when all of these hold — not when a build command returns zero.
atf status— the live board: services, ports, reachability, task counts and the dashboard URL.atf system services— all four services OK, running, reachable, with their endpoints.- The dashboard answers on
http://localhost:8088(the value ofATF_WEB_URLin.env). atf rules listshows your task, with stateon.- A real post from the source lands in the target and
atf logs tail --followshows[PIPELINE:DISPATCH]followed by[PIPELINE:DELIVERED]for it.
Common first-run failures
These four cover almost every first install. Each fix is a command you can run right now.
| Symptom | Cause | Fix |
|---|---|---|
docker is not usable here | No docker, or the daemon is down. | Run atf platform for this host’s exact install command, start the daemon, or take the no-docker path with atf setup --source-wizard. |
port 8088 is already in use | Another process owns the dashboard port. | atf validate --runtime names the owner through its ports check; free it or change the published port in the compose file. |
The bot says it is unconfigured although .env is filled | The container was started before the .env change, so it never received the value. | atf system restart. The container-env check detects exactly this condition. |
| The first task forwards nothing; logs say the upstream is disconnected | The Telegram account session was never authorised. | atf sessions list to see it, then link the account from the bot (see below) and retry the task. |
The rest of the catalogue — stale containers, missing network aliases, a wizard waiting on a piped stdin, TLS and certificate renewal — lives in the Operations & troubleshooting runbook, and atf doctor names the failing check and its own fix line for each one.