Skip to content

Latest commit

 

History

139 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Telegram Work Hours Logger Bot

Track daily work hours by chatting with your own Telegram bot. Messages are parsed, stored in MongoDB, surfaced in quick summary commands, and optionally translated into pay estimates (weekday/weekend/holiday). Scheduled reminders keep you logging on time.

How It Works

  • Webhook: Telegram sends updates to /api/bot; we authenticate the sender and route either to command handlers or work-log parsing.
  • Logging: Natural language like “Worked 6 hours on design yesterday” becomes a normalised entry (date, hours, tag, raw_message, timestamp).
  • Summaries: /summary, /today, /paycycle, /paycycles, etc. aggregate from MongoDB and return Markdown responses with pay breakdowns when configured.
  • Reminders: GitHub Actions triggers /api/reminder four times daily (only one run sends); the reminder engine checks the 3–11 PM window in DEFAULT_TIMEZONE.
  • Tags & pay: Any entry whose tag matches PAY_RATE_HOLIDAY_TAGS uses the holiday rate. /category without arguments shows all discovered tags so you can drill into one.

For deeper architecture context, see the Technical Overview.

Quick Start

  1. Create a bot with @BotFather and copy the token.
  2. Get your Telegram user ID via @userinfobot.
  3. Provision MongoDB (Atlas recommended) and copy the connection string.
  4. Set the environment variables (below) on your host.
  5. Deploy (Vercel/Railway/Render/Fly or node bot.js locally).
  6. Register the webhook: curl https://api.telegram.org/bot<token>/setWebhook -d '{"url":"https://<domain>/api/bot"}'.
  7. DM the bot: Worked 6 hours today → expect a ✅ reply.

Command Cheat Sheet

Command Description
/summary Weekly & monthly totals with weekday/weekend/holiday breakdowns and pay estimates (if rates configured).
/today Today’s entries, time/tags per line, holiday marker, pay totals.
/log Latest 5 entries (newest first).
/category [tag] Lists all tags when omitted; totals and entry count when provided.
/paycycle [tag] Current pay-cycle hours plus a detailed entry list (capped 50). Works standalone or with optional tag to filter by project.
/paycycles [tag] Last 5 pay cycles summary with totals and pay estimates. Works standalone or with optional tag to filter.
/help Cheat sheet including configured pay rates.
/delete … Preview/delete the most recent entries (confirmation required).
/stats, /validate, /reset confirm, /backup, /reminder … Admin utilities.

Tag Filtering Examples

The /paycycle and /paycycles commands work standalone and support optional tag filtering to view earnings for specific projects/categories:

/paycycle              → Shows all entries in current pay cycle (default)
/paycycle project1     → Shows only "project1" entries  
/paycycle freelance    → Shows only "freelance" entries
/paycycles             → Shows last 5 cycles with all entries (default)
  • Tag parameter is completely optional - commands work fine without it
  • Filtering uses case-insensitive partial matching (e.g., "proj" matches "project1", "project2")
  • Displays filtered count vs total entries when active
  • Works across all 5 pay cycles when using /paycycles The API Quick Reference describes each command’s response format.

Configuration

# Required
TELEGRAM_BOT_TOKEN=...
AUTHORIZED_USER_ID=...
MONGODB_URI=...

# Optional pay/rate settings
PAY_RATE=45.0
PAY_RATE_WEEKDAY=45.0
PAY_RATE_WEEKEND=60.0
PAY_RATE_SATURDAY=55.0
PAY_RATE_SUNDAY=65.0
PAY_RATE_HOLIDAY=80.0
PAY_RATE_HOLIDAY_TAGS=holiday,public_holiday,public holiday
PAY_RATE_HOLIDAY_MESSAGE=Public Holiday
PAY_RATE_CURRENCY=AUD
PAY_RATE_LOCALE=en-AU
PAY_RATE_SYMBOL=$

# Date format preference (optional)
DATE_FORMAT_PREFERENCE=DMY
# Options: DMY (DD/MM/YYYY, default) or MDY (MM/DD/YYYY)

# Pay cycle configuration (optional)
PAY_CYCLE_START_DATE=2025-08-04
# Format: YYYY-MM-DD (recommended to be a Monday for easier tracking)
# Default: 2025-08-04 - All pay periods are calculated from this date

PAY_CYCLE_LENGTH_DAYS=14
# Number of days in each pay cycle
# Default: 14 (bi-weekly/fortnightly)

# Reminder API authentication
REMINDER_SECRET=...
  • Leave the pay variables unset or zero to hide earnings in outputs.
  • Holiday pay: Activates when the message tag matches any value in PAY_RATE_HOLIDAY_TAGS. Examples:
    • "Worked 8 hours on holiday" → Uses holiday pay rate
    • "7.5 hours on public holiday" → Uses holiday pay rate
    • "6 hrs on public_holiday" → Uses holiday pay rate
  • DEFAULT_TIMEZONE inside src/bot/services/reminder.js defaults to Australia/Melbourne; change it (and cron schedules) if you deploy elsewhere.

Reminders at a Glance

  • Workflow: .github/workflows/daily-reminder.yml (four cron slots per day; deterministic slot selection).
  • Secrets: BOT_WEBHOOK_URL, AUTHORIZED_USER_ID, REMINDER_SECRET (optional REMINDER_RANDOM_SEED).
  • Endpoint: POST /api/reminder with Authorization: Bearer <REMINDER_SECRET>.
  • See the GitHub Actions Guide for cron tuning and troubleshooting.

Data & Project Layout

  • Mongo collection work_entries with { date, hours, tag, raw_message, timestamp } and indexes on date, tag, timestamp.
  • Key folders:
    • api/ → Webhook + reminder handlers.
    • src/bot/handlers/commands.js, messageParser.js.
    • src/bot/services/database.js, reminder.js.

Troubleshooting

Issue Quick check
Bot silent curl getWebhookInfo; confirm HTTPS domain + AUTHORIZED_USER_ID.
Reminders missing Inspect GitHub Actions logs; ensure run time is inside 3–11 PM in DEFAULT_TIMEZONE and REMINDER_SECRET matches.
Pay/holiday missing Check PAY_RATE* env vars > 0 and log message contains a recognised tag.
/category empty Log entries with …on <tag> then rerun /category.

Documentation Map

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages