9c83ed98c602418b3262d91fd38be2a2c9064387
Previous approach (send \u200C then immediately delete it) lost the reply keyboard because Telegram may not persist the keyboard from a deleted message. Now we delete the OLD keyboard message and keep the new one, ensuring the reply keyboard is always present and correct.
WorkTime Bot
A single-user Telegram time-tracking bot. Clock in/out, toggle remote/onsite, mark day off, get daily reports, and export monthly Excel reports.
Quick Start
cp .env.example .env
# edit .env — set BOT_TOKEN and BOT_ALLOWED_USERS
docker compose up -d
Environment Variables
| Variable | Purpose |
|---|---|
BOT_TOKEN |
Telegram Bot API token (required) |
BOT_ALLOWED_USERS |
Comma-separated Telegram user IDs (empty = allow all) |
HTTPS_PROXY |
Outbound proxy for Telegram API (e.g. http://proxy:10808) |
DB_PATH |
Path to SQLite database (default: db.sqlite3) |
BOT_WEBHOOK_URL |
Set for webhook mode (omit for polling) |
Usage
Persistent reply keyboard at the bottom: Clock In / Clock Out
Inline menu on /start:
- Clock In / Clock Out
- Report / Export
- Toggle Remote/Onsite / Day Off
Commands
| Command | Action |
|---|---|
/start |
Show inline menu |
Clock In or /clockin |
Record clock-in |
Clock Out or /clockout |
Record clock-out |
/remote |
Toggle remote/onsite mode |
/report |
Today's work & break summary |
/export |
Monthly .xlsx report |
/dayoff |
Toggle today as day off |
Daily report is sent automatically at 23:00.
How Break Time Works
The gap between a clock-out and the next clock-in is counted as break:
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
Project Structure
├── cmd/bot/ main.go, webhook.go
├── internal/
│ ├── bot/ handlers, export, totals
│ └── db/ SQLite store
├── db/schema.sql Database schema
├── Dockerfile
└── docker-compose.yml
Build
docker compose up -d --build
Description
Languages
Go
99.6%
Makefile
0.2%
Dockerfile
0.2%