f25ff56babfece2db1e6d7d590a7c9392d3a58f2
willhaben-tracker
Telegram bot that monitors classified ads on willhaben.at and notifies you about new listings matching your keywords, plus price drops on tracked ads. Notifications include photos when available.
Prerequisites
- Docker
- Docker Compose (v2.x)
Quick Start
cp .env.example .env
# Edit .env with your bot token and database credentials
docker compose up -d --build
Deploy on Tizona (NAS)
Copy-paste these commands from your local machine:
# 1. Clone repo on tizona (run as root via SSH)
ssh tizona "mkdir -p /mnt/user/appdata && rm -rf /mnt/user/appdata/willhaben-tracker"
ssh tizona "git clone https://git.lago.dev/Lago/willhaben-tracker.git /mnt/user/appdata/willhaben-tracker"
# 2. Copy .env (must exist locally)
scp .env tizona:/mnt/user/appdata/willhaben-tracker/.env
# 3. Start stack on tizona
ssh tizona "cd /mnt/user/appdata/willhaben-tracker && docker compose up -d --build"
# 4. Verify everything is running
ssh tizona "cd /mnt/user/appdata/willhaben-tracker && docker compose ps"
Update (pull + rebuild)
ssh tizona "cd /mnt/user/appdata/willhaben-tracker && \
git pull origin main && \
docker compose build worker --no-cache && \
docker compose up -d"
Full reset (wipe data, keep schema)
ssh tizona "cd /mnt/user/appdata/willhaben-tracker && \
docker compose down && \
rm -rf data/db && mkdir -p data/db && \
docker compose up -d --build"
Backup & Restore
# Dump database
ssh tizona "docker compose exec db pg_dump -U postgres postgres" > backup_$(date +%F).sql
# Restore
cat backup_2024-01-01.sql | ssh tizona "cd /mnt/user/appdata/willhaben-tracker && docker compose exec -T db psql -U postgres postgres"
Troubleshooting
| Problem | Fix |
|---|---|
role "supabase_admin" does not exist in Studio |
Full reset (wipes data, re-runs init scripts) |
| Migrations didn't run on new tables | data/db/ had stale data — delete it and restart |
Worker crashes with UndefinedTableError |
Docker image was built before migration commit — force rebuild: docker compose build worker --no-cache && docker compose up -d |
| Studio shows "unhealthy" but APIs work | Cosmetic health check issue — ignore unless you can't browse tables |
Configuration
Edit .env before first startup. All values are read by the worker and database services.
| Variable | Description | Default |
|---|---|---|
TELEGRAM_BOT_TOKEN |
Token from @BotFather | (required) |
POSTGRES_USER |
PostgreSQL username | postgres |
POSTGRES_PASSWORD |
PostgreSQL password | (required) |
POSTGRES_DB |
Database name | postgres |
JWT_SECRET |
PostgREST JWT signing key | auto-generated default |
DEFAULT_INTERVAL_MINUTES |
Default scrape interval per keyword | 5 |
Architecture
| Service | Image | Port | Purpose |
|---|---|---|---|
| db | postgres:15-alpine | 55632 | PostgreSQL database |
| rest | postgrest/postgrest:v12.2.0 | — | REST API over the database |
| kong | kong:2.8.1 | 55621 | Reverse proxy / gateway |
| studio | supabase/studio | 55630 | Supabase Studio admin UI |
| meta | supabase/postgres-meta:v0.84.2 | — | Database metadata service |
| worker | (built from ./worker) | — | Scraper + Telegram bot |
Telegram Bot UI
All users must be whitelisted before use. The bot uses inline keyboards (buttons) instead of text commands for a clean experience. Times are shown in Vienna timezone.
Commands (global menu, appears when you type /)
| Command | Access | Description |
|---|---|---|
/start |
Anyone | Open main menu |
/admin |
Admin only | Open admin panel |
Main Menu (/start)
Tap one of the buttons:
- ➕ Add Keyword → Bot asks for keyword text → Shows confirmation with Yes/No
- 📋 My Keywords → Sends a formatted card per keyword with status, interval (Vienna tz), last scrape, subscriber count. Each card has action buttons:
⏸ Stop/▶ Start— Toggle active state✏️ Edit— Submenu to change name or interval- Change Name: type new name → confirm Yes/No → in-place update
- Change Interval: preset buttons (1m, 3m, 5m, 10m, 30m, 60m) or ⌨️ Custom
🗑 Remove— Confirm Yes/No → deletes subscription
- 📊 Stats — Keywords count, ads indexed, notifications sent
Admin Panel (/admin)
- ➕ Add User — Enter Telegram ID → adds user
- 👥 List Users — Shows all users with status icons and admin badges
- 🗑 Remove User — Enter Telegram ID → removes user
Default Admin
On first boot, Telegram ID 298181113 is seeded as an admin user. Add additional admins via the /admin panel.
Description
Languages
Python
98.7%
Shell
1.1%
Dockerfile
0.2%