app/
Owns bootstrap: config loading, logger setup, dependency wiring, and graceful shutdown.
Telegram Bot Documentation
A Go Telegram bot that stores user links, ignores duplicates, and sends a random saved link back after every configured number of successful saves.
The bot runs as a polling Telegram consumer. It accepts plain-text links from users,
stores them in sqlite, persists its acknowledged Telegram offset, and exposes a manual
random-link command through /rnd. The business rules live in the service
layer so Telegram integration remains thin.
Use this flow to run the bot locally.
go.mod.github.com/mattn/go-sqlite3 uses CGO.cp .env.example .env
set -a
source .env
set +a
go run .
# or
make run
The application reads os.Getenv only. It does not auto-load .env.
The bot reads configuration from environment variables.
| Variable | Required | Description |
|---|---|---|
BOT_TOKEN |
Yes | Telegram bot token issued by BotFather. |
DATABASE_PATH |
Yes* | Path to the sqlite database file, for example data/sqlite/storage.db. |
DATABASE_URL |
Fallback | Accepted as an alternative source for the sqlite path. |
SEND_EVERY_N |
Yes | Send a random saved link after every N successful saves. |
LOG_LEVEL |
No | One of debug, info, warn, or error. Defaults to info. |
ENV |
No | Application environment such as local, dev, staging, or production. Defaults to local. |
TELEGRAM_HOST |
No | Optional Telegram API host or full base URL. Defaults to api.telegram.org. Invalid values fail startup with a normal error. |
* Either DATABASE_PATH or DATABASE_URL must be set.
/start sends the intro and help message./help shows supported bot behavior./rnd returns one random saved link for the current user.http:// and https:// links are accepted.app/Owns bootstrap: config loading, logger setup, dependency wiring, and graceful shutdown.
consumer/poller/Polls Telegram updates in batches, passes events to the processor, and stops the current batch on the first processing error.
events/telegram/Maps Telegram updates into internal events, routes commands, turns service results into user-facing messages, and persists the next acknowledged Telegram offset after successful processing.
service/Owns business rules: validation, normalization, duplicate handling, counters, and scheduled random-link sends.
storage/Persists links, message counters, and bot runtime state. The sqlite implementation is the production backend.
clients/telegram/Small HTTP client for getUpdates and sendMessage with request timeout support, startup URL validation, and POST form bodies for outgoing messages.
main.goStays intentionally thin and delegates application startup to app.Run().
Production data is stored in sqlite with three main tables:
links: keeps user_id, normalized link, and created_at, with a unique (user_id, link) constraint.message_counters: tracks how many links each user has saved and when that counter changed.bot_state: stores internal runtime state such as the persisted Telegram update offset.The database directory is created automatically on startup. The bot initializes schema and indexes before it starts processing updates.
Run the standard checks before shipping changes.
go test ./...
go test -race ./...
go vet ./...
test -z "$(gofmt -l .)"
You can also use:
make test
make lint
BOT_TOKEN is required: export the token in the process environment before startup.DATABASE_PATH or DATABASE_URL is required: configure a sqlite location.invalid telegram api base url: fix TELEGRAM_HOST so it is a valid host or full base URL.SEND_EVERY_N and confirm the user has saved links.SIGINT and SIGTERM.
This repository publishes the content of docs/ to GitHub Pages through
.github/workflows/pages.yml. The deployment runs on pushes to main
and on manual workflow dispatch.