I Built a GTD Telegram Bot in Under an Hour with Claude Code

Using Claude Haiku for natural language task parsing

telegram
ai
productivity
python
How I built a Getting Things Done Telegram bot with natural language parsing using Claude Haiku, Python, and PostgreSQL - all in under an hour with Claude Code.
Author

Guy Freeman

Published

December 20, 2025

Every GTD app I’ve tried falls into one of two camps: either it’s a complex beast with more features than I’ll ever use (looking at you, OmniFocus), or it’s simple but forces me to manually categorize everything with rigid syntax.

What I wanted was simple: type “buy milk tomorrow” into my phone and have it land in the right place. No app switching, no form fields, no learning curve.

The Gap in the Market

I surveyed the landscape. Todoist has excellent natural language parsing - you can type “Call dentist next Tuesday at 2pm #errands” and it just works. But Todoist is bloated for my needs. I don’t want Kanban boards, team collaboration, or productivity gamification. I want a scratchpad that understands English.

What about Telegram bots? Telegram is already on my phone, always running, and has an excellent bot API. Surely someone has built a GTD bot?

I couldn’t find one. There are todo list bots, reminder bots, and note-taking bots. But nothing that implements actual GTD methodology - the inbox/next/scheduled/someday workflow that David Allen describes - with natural language understanding.

So I built one.

The Solution: 839 Lines of Python

Jarvis Lite is a single-file Python bot that implements GTD principles with Claude Haiku handling all the natural language parsing. The entire thing took under an hour to build using Claude Code.

The stack:

  • python-telegram-bot for the Telegram integration
  • PostgreSQL for persistent storage
  • Claude Haiku for parsing natural language into structured actions
  • APScheduler for the daily morning digest

One-click deployment to Render with a managed Postgres database.

How It Works

Natural Language Parsing with Claude Haiku

The core insight is that you don’t need complex NLP libraries or custom models. Claude Haiku is fast, cheap, and remarkably good at intent classification. Every message the user sends gets parsed through this system prompt:

Code
system_prompt = f"""You are a GTD task parser. Parse the user's message into a JSON action.

Today's date is {today_date}.

Actions:
- add: Add a new task. Extract the task text (keep @tags in the text) and determine the list.
- complete: Mark a task as done. Look for "done", "finished", "complete", etc.
- delete: Remove a task. Look for "delete", "remove", etc.
- move: Move a task to a different list. Look for "move X to Y", "X to next", "X scheduled tomorrow".
- show: Display tasks. Look for "show", "list", "what's next", etc. Can filter by @tag.
- review: Weekly review. Look for "review", "weekly review", etc.
- today: Mark a task for today's focus. Look for "today X", "focus X", "star X".
- clear_today: Clear all today markers.
- process: Start inbox processing. Look for "process", "process inbox", "triage".
- help: User needs help.

Lists:
- inbox: Default for new tasks without a specific list
- next: Tasks to do within 7 days. Look for "#next", "next:", or context implying urgency
- scheduled: Tasks with a due date. Parse dates like "tomorrow", "next monday", "Dec 15", etc.
- someday: Future/maybe tasks. Look for "someday", "maybe", "later", etc.

Context tags (@work, @home, @errands, etc.) should be kept in the task text as-is.

Respond with ONLY valid JSON, no other text:
{{
  "action": "add|complete|delete|move|show|review|today|clear_today|process|help|unknown",
  "text": "task text if adding (include @tags)",
  "list": "inbox|next|scheduled|someday|today|null",
  "task_id": null or number,
  "due_date": null or "YYYY-MM-DD",
  "text_match": "partial text to match for completion",
  "tag": "tag name without @ for filtering"
}}"""

The examples section (omitted for brevity) shows Haiku how to handle inputs like:

  • “Buy milk” → {"action": "add", "text": "Buy milk", "list": "inbox"}
  • “Call bank tomorrow” → {"action": "add", "text": "Call bank", "list": "scheduled", "due_date": "2025-12-21"}
  • “#next: finish report @work” → {"action": "add", "text": "finish report @work", "list": "next"}
  • “Done: buy milk” → {"action": "complete", "text_match": "buy milk"}
  • “3 to next” → {"action": "move", "task_id": 3, "list": "next"}

Haiku returns structured JSON that the bot then acts on. If parsing fails or the action is unknown, the message gets added to inbox as a fallback - you never lose a thought.

The GTD Data Model

The database schema is minimal:

Code
CREATE TABLE tasks (
    id SERIAL PRIMARY KEY,
    user_id BIGINT NOT NULL,
    text TEXT NOT NULL,
    list VARCHAR(20) NOT NULL DEFAULT 'inbox',
    due_date DATE,
    is_today BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    completed_at TIMESTAMP
)

Four lists matching GTD methodology:

  • inbox: Capture everything, process later
  • next: Actionable tasks for this week
  • scheduled: Tasks with specific due dates
  • someday: Maybe/future items

The is_today flag lets you pick 3-5 tasks for daily focus - a key GTD concept that most apps ignore. Context tags like @work or @errands are stored in the task text itself and searchable via “show @work”.

Morning Digest

APScheduler sends a daily summary at 7am with:

  • Your today’s focus tasks
  • Overdue items
  • Tasks due today
  • Suggested next actions

This replaces the need to open an app and review - the bot comes to you.

Building with Claude Code

The entire bot - from zero to deployed - took under an hour with Claude Code. Here’s what that looked like:

  1. I described what I wanted: a GTD Telegram bot with natural language parsing
  2. Claude Code generated the initial bot.py with the Haiku integration
  3. We iterated on the prompt engineering to improve parsing accuracy
  4. Claude Code added the database layer, then deployment configs for Render
  5. I deployed, tested with real messages, and refined

The Claude Code workflow shines for this kind of project. You’re not fighting boilerplate or looking up API docs. You describe intent and iterate on the result. The prompt engineering phase - refining how Haiku interprets messages - was the bulk of the work, and having Claude Code suggest prompt improvements was genuinely useful.

Try It

The bot is live at @gtdlitebot - though it’s currently single-user (me). The code is on GitHub if you want to deploy your own instance.

What’s Missing

This is a v0.1. Some obvious improvements:

Recurring tasks: “Water plants every Sunday” doesn’t work yet. Would need to add a recurrence pattern to the schema and logic to regenerate tasks.

Projects and areas: Real GTD has hierarchical projects. Currently everything is flat. You can fake it with tags, but it’s not the same.

Voice input: Telegram supports voice messages. Whisper transcription could make capture even more frictionless.

Time-based reminders: Push notifications at specific times, not just the morning digest.

Calendar sync: Export scheduled tasks to Google Calendar.

Analytics: What days am I most productive? What contexts get neglected? The data is there, the dashboard isn’t.

But for now, it does what I need: captures thoughts in natural language and organizes them according to GTD principles. Built in an hour. That’s the power of LLMs as parsing layers - you can build surprisingly capable tools with very little code.