# willhaben-tracker Telegram bot that monitors classified ads on [willhaben.at](https://www.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 ```bash 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: ```bash # 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) ```bash 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) ```bash 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 ```bash # 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 Commands All users must be whitelisted before use. Run `/start` to activate your account. | Command | Access | Description | |------------------------------------|-------------|--------------------------------------------------| | `/start` | Anyone | Activate account and show help message | | `/add ` | Active user | Subscribe to keyword (shared across users) | | `/list` | Active user | List your subscriptions with subscriber counts | | `/delete ` | Active user | Unsubscribe from a keyword | | `/interval ` | Active user | Change scrape interval (1-1440 min) | | `/stats` | Active user | Show keywords, ads tracked, notifications | | `/adduser [admin]` | Admin only | Add or promote a user by Telegram ID | | `/removeuser ` | Admin only | Remove a user from the bot | | `/users` | Admin only | List all registered users and their roles | ## Default Admin On first boot, Telegram ID `298181113` is seeded as an admin user. Add additional admins via `/adduser admin`.