# WorkTime Bot A single-user Telegram time-tracking bot with **multi-calendar support** (Gregorian, Jalali/Persian, Hijri). Clock in/out, toggle remote/onsite, mark day off, get daily reports at a configurable time, browse history by month, and export monthly `.xlsx` reports. ## Quick Start ```bash cp .env.example .env # edit .env — set BOT_TOKEN and BOT_ALLOWED_USERS docker compose up -d ``` ## Environment Variables | Variable | Default | Purpose | | ------------------- | ------------ | ----------------------------------------------------- | | `BOT_TOKEN` | — | Telegram Bot API token **(required)** | | `BOT_ALLOWED_USERS` | (all) | Comma-separated Telegram user IDs (empty = allow all) | | `HTTP_PROXY` | — | Outbound HTTP proxy for Telegram API | | `HTTPS_PROXY` | — | Outbound HTTPS proxy for Telegram API | | `DB_PATH` | `db.sqlite3` | Path to SQLite database file | | `BOT_WEBHOOK_URL` | — | Set for webhook mode (omit for long-polling) | | `BOT_LISTEN` | `:8080` | Listen address for webhook mode | | `BOT_TLS_CERT` | — | TLS certificate path (webhook HTTPS) | | `BOT_TLS_KEY` | — | TLS key path (webhook HTTPS) | ## Calendar Support Users can choose between three calendars via `/settings`: - **Gregorian** — standard international calendar - **Jalali** (Persian/Solar Hijri) — official calendar of Iran and Afghanistan - **Hijri** (Islamic lunar) — used in many Muslim-majority countries The history view, export month picker, and date displays all adapt to the user's chosen calendar. The `/export` and `/edit` commands accept dates in the user's calendar. Internally, all dates are stored as Gregorian. ## Usage **Persistent reply keyboard** at the bottom of the chat: `Clock In` / `Clock Out` **Inline menu** on `/start`: | Button | Action | | -------------------- | --------------------------------- | | Clock In / Clock Out | Record work event | | Report | Today's work & break summary | | Export | Pick a month → download `.xlsx` | | History | Browse past days in calendar view | | Toggle Remote/Onsite | Switch work type | | Day Off | Mark today as day off | | Settings | Timezone, accent, calendar type | ### Commands | Command | Action | | --------------------- | ------------------------------------------------------- | | `/start` | Show inline menu | | `/clockin` | Record clock-in | | `/clockout` | Record clock-out | | `/remote` | Toggle remote/onsite | | `/report` | Today's work & break summary | | `/export` | Export this month (optional `YYYY-MM` in your calendar) | | `/dayoff` | Toggle today as day off | | `/edit YYYY-MM-DD` | View/edit events for a specific date | | `/settimezone ` | Set timezone (e.g. `Asia/Tehran`) | | `/settings` | Open settings menu | ## Daily Report A daily summary is sent automatically at the user's configured report time (default `23:00`). The scheduler checks every 30 seconds. ## How Break Time Works The gap between a clock-out and the next clock-in is counted as break. Gaps shorter than the **min break threshold** (default 5 minutes) are absorbed into work time. ``` 09:00 Clock In → work starts 12:00 Clock Out → work: 3h, break starts 13:00 Clock In → break: 1h, work resumes 17:00 Clock Out → work: 4h total: 7h work, 1h break ``` ## Export The `/export` command opens a month picker. Select any month in your calendar and download an `.xlsx` file with columns: Date, Clock In, Clock Out, Type, Work, Break. Four color themes are available in settings: **Ocean**, **Beach**, **Rose**, **Catppuccin**. ## Project Structure ``` ├── cmd/bot/ │ ├── main.go Entrypoint, polling/webhook, scheduler │ └── webhook.go Webhook mode with TLS support ├── internal/ │ ├── bot/ │ │ ├── handlers.go Message/callback routing, views, menu builders │ │ ├── totals.go Break/work computation state machine │ │ ├── export.go Excel (.xlsx) report generation │ │ └── dateutil.go Gregorian/Jalali/Hijri conversions & calendars │ └── db/ │ ├── store.go SQLite store │ └── migrations/ Goose-managed SQL migrations │ └── 001_init.sql Initial schema ├── .gitea/workflows/ │ └── ci.yml Gitea Actions CI ├── Dockerfile ├── docker-compose.yml ├── Makefile ├── .env.example └── README.md ``` ## Build & Run ```bash # Local (requires Go 1.26+ and CGo-free SQLite) make run # Docker docker compose up -d --build ```