Telegram Bot Documentation

tg_bot_golang

A Go Telegram bot that stores user links, ignores duplicates, and sends a random saved link back after every configured number of successful saves.

Overview

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.

Go Telegram Bot API sqlite GitHub Actions

Quick Start

Use this flow to run the bot locally.

  1. Install Go using the version declared in go.mod.
  2. Install a C compiler because github.com/mattn/go-sqlite3 uses CGO.
  3. Copy the example environment file, fill in the values, and export them in your shell.
  4. Start the application with Go or Make.
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.

Configuration

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.

Commands and Behavior

User commands

  • /start sends the intro and help message.
  • /help shows supported bot behavior.
  • /rnd returns one random saved link for the current user.

Link handling rules

  • Only full http:// and https:// links are accepted.
  • Fragments are removed during normalization.
  • Hosts are lowercased and default ports are dropped.
  • Duplicate links for the same user are rejected without incrementing the counter.

Architecture

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.go

Stays intentionally thin and delegates application startup to app.Run().

Storage

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.

Quality Checks

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

Operations

Troubleshooting

  • 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.
  • No random link is sent: verify SEND_EVERY_N and confirm the user has saved links.
  • sqlite build errors: install a C compiler in the build or runtime environment.

Shutdown behavior

  • The process listens for SIGINT and SIGTERM.
  • Polling stops through context cancellation.
  • In-flight Telegram HTTP requests are canceled via context.
  • The next Telegram offset is already in sqlite for successfully processed updates.
  • sqlite is closed before exit.

Docs Deployment

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.

  1. Push the repository with the Pages workflow enabled.
  2. In GitHub repository settings, open Pages.
  3. Select GitHub Actions as the build and deployment source if it is not already enabled.
  4. After the workflow succeeds, GitHub Pages serves the static site from the published artifact.