dyzur-bot/README.md

2.8 KiB
Raw Blame History

Dyżur-bot

A telegram bot for managing the cleaning rota in hackerspace. Bot offers weekly reminders about cleaning duties as well as on demand informations. Backend read the schedule from a Google sheet, store it in local JSON file.

Running

Requires GOOGLE_CREDENTIALS_FILE (path to a Google service-account key, shared as an editor on the sheet), GOOGLE_SHEETS_ID, and BOT_TOKEN in the environment or a .env file (see service.go/sheet.go for optional SHEET_RANGE, ROTA_CACHE_PATH, SYNC_INTERVAL). Then:

go run ./cmd/dyzur-bot

The service loads the cached rota, syncs from Google Sheets in the background on SYNC_INTERVAL (default 30m), and runs the Telegram bot via long polling until interrupted (Ctrl-C / SIGTERM).

When SHEET_RANGE is unset, the bot reads the current year's tab (e.g. 2026!A1:G100), resolved on every sync — so it follows the New Year rollover automatically without a restart. A sync that fails, or that returns no duty weeks (e.g. a next-year tab that exists but hasn't been filled in yet), keeps the last-good cache instead of clearing it; if no sync succeeds for 6h the bot logs a loud stale-cache error.

Run exactly one instance per bot token. The bot uses long polling (getUpdates); two concurrent pollers on the same token make Telegram return HTTP 409 Conflict and updates get dropped. Do not scale this to multiple replicas.

Docker

docker build -t dyzur-bot .
docker run --rm --env-file .env -v dyzur-data:/data dyzur-bot

The image is a static binary on distroless (timezone data is embedded, so reminders work without system tzdata). The rota cache lives at /data/rota.json (ROTA_CACHE_PATH); mount a volume at /data to persist it across restarts.

Commands

  • /kto_sprzata — who is on cleaning duty this week.
  • /sync — refresh the rota from Google Sheets now (throttled to once per minute across the chat to avoid spamming the Sheets API).

Any other command is ignored — the bot stays silent instead of replying "unknown command".

Reminders

If GROUP_CHAT_ID is set, the bot posts a weekly duty reminder to that chat. Schedule (all optional, with defaults): REMINDER_WEEKDAY (default Monday), REMINDER_HOUR (default 9, 023), interpreted in Europe/Warsaw time.

On each fire the bot handles three weeks relative to the fire time:

  • This week — announces who is on duty. It never auto-assigns at this point; a still-empty week is announced as unstaffed.
  • One week ahead — if both slots are empty, it picks the two people with the fewest duties (random tie-break), writes their names into the sheet, and announces the assignment.
  • Two weeks ahead — if both slots are empty, it asks people to volunteer before the week is auto-assigned the following week.

Leave GROUP_CHAT_ID unset to disable reminders.