Telegram Word Pair Reminder Bot
This is a Telegram bot built using Go that allows users to upload word pairs and receive reminders with those pairs.
Features
- Upload word pairs as a CSV file (
word1,word2 or tab/semicolon separated).
- Clear uploaded word pairs.
- Set the number of pairs to send in reminders.
- Set the frequency of reminders per day.
- Periodic reminders sent to users with random word pairs.
Project Structure
cmd/tg-word-reminder/main.go: application entrypoint.
pkg/bot/handlers: Telegram command/update handlers.
pkg/bot/game: quiz session state and matching logic.
pkg/bot/reminders: reminder scheduling and delivery.
pkg/bot/importexport: CSV parsing and export helpers.
pkg/db: GORM models and database initialization.
pkg/config: JSON config loader.
pkg/logger: slog wrapper.
pkg/ui: inline keyboard rendering and callback data parsing.
pkg/internal/testutil: shared test helpers.
Prerequisites
- Go 1.25 or newer
- PostgreSQL database
- A Telegram bot token (create one using BotFather)
Installation
-
Clone the repository:
git clone <repository-url>
cd <repository-directory>
-
Create a production .env for Docker Compose:
# .env
POSTGRES_USER=your_db_user
POSTGRES_PASSWORD=your_db_password
POSTGRES_DB=your_db_name
Keep these values in sync with the database settings in config.json.
-
Create a configuration file:
Copy config.example.json to config.json and set your Telegram bot token and database credentials to match .env.
cp config.example.json config.json
For local development values and .env.development, see Local Development (Docker Compose).
-
Run the bot with Docker Compose:
docker compose up --build
Run detached if you prefer:
docker compose up -d --build
Local Development (Docker Compose)
For local development, use Docker Compose to run the bot and PostgreSQL.
-
Create a development .env.development file:
# .env.development
POSTGRES_USER=tgwr
POSTGRES_PASSWORD=tgwr_local_password
POSTGRES_DB=tgwrdb
Keep these values in sync with the database settings in config.json.
-
Update database settings in config.json:
Set database values to match .env.development:
- host:
db
- user:
tgwr
- password:
tgwr_local_password
- dbname:
tgwrdb
- port:
5432
- sslmode:
disable
-
Start the stack with the development env file:
docker compose --env-file .env.development up --build
Run detached if you prefer:
docker compose --env-file .env.development up -d --build
Use --env-file .env.development with other Compose commands too.
-
Useful Compose commands:
Tail logs for the bot:
docker compose --env-file .env.development logs -f tg-word-reminder
-
Connect to the local database (in-container):
docker compose --env-file .env.development exec db psql -U tgwr -d tgwrdb
-
Connect to the local database (host):
psql -h 127.0.0.1 -U tgwr -d tgwrdb
Database Backups (Docker Compose)
The Compose stack includes a db-backup service that runs pg_dump every hour and keeps four days of plain SQL backups (compressed with gzip) in ./backups.
Defaults (override via .env or .env.development):
BACKUP_INTERVAL_SECONDS=3600
BACKUP_RETENTION_DAYS=4
Restore a backup:
gunzip -c backups/<backup-file>.sql.gz | psql -h 127.0.0.1 -U tgwr -d tgwrdb
Testing
Run unit tests locally:
go test ./...
Usage
You can send a CSV file with word pairs to the bot to upload them. The first two columns are used as word1 and word2 (comma, tab, or semicolon separated). Please refer to the example file example.csv for the correct format.
- Commands:
/start: initialize your account.
/getpair: get a random word pair.
/game: start a quiz session.
/review: start a review session.
/settings: configure reminders and pair counts.
/export: download your vocabulary.
/clear: remove all uploaded word pairs.
/feedback: send feedback to the admins (private chat only).
Database Setup
The bot uses a PostgreSQL database. Ensure that the database is set up and accessible based on the configuration provided in config.json. The bot will automatically create the necessary tables for storing word pairs and user settings.
Logging
The bot uses the standard library's slog package for logging. Logs are printed to stdout by default.
Optional config.json logging settings:
"logging": {
"level": "info",
"file": "/app/logs/tg-word-reminder.log"
}
level: debug, info, or error (defaults to info).
file: when set, logs are written to both stdout and the file path.
compose.yml mounts ./logs to /app/logs so file logs persist across container restarts.
Feedback
Configure feedback delivery in config.json with admin IDs:
"feedback": {
"enabled": true,
"admin_ids": [123456789],
"timeout_minutes": 5
}
Admin IDs must be numeric Telegram user IDs. Use @Get_myidrobot (or similar) to find your numeric ID.
Contributing
Contributions are welcome! Please feel free to submit a pull request or open an issue for any enhancements or bug fixes.
License
This project is licensed under the MIT License. See the LICENSE file for details.
Acknowledgments