← All projects

Qumio

Personal AI assistant on Telegram. Ask for your emails, calendar, or tasks and get a structured answer back.

Live28 Mar 20264 min read
OpenClawTelegramGoogle APIsDockerObsidian

What it does

Qumio is a personal AI assistant on Telegram. One chat, one container, everything local.

Email briefing. A local sub-agent fetches Gmail, strips PII with typed placeholders, groups messages by context, and returns an executive-style briefing.

Calendar. Today's schedule with times and a date header.

Obsidian notes. Quick notes from Telegram land in today's daily note with timestamps. Email briefings can be saved there too. Append-only, never overwrites.

On-demand news. Ask about any topic and a sub-agent searches the web, reads top results, and returns dated bullet points with source URLs.

Morning delivery. Four cron jobs fire at 7:00, 7:01, 7:02, and 7:03 AEST. AI, tech, geopolitics, Australian politics. Each one fetches news, saves to Obsidian, then sends to Telegram. By the time I pick up my phone, the briefing is waiting.

The numbers

Phases7
Plans11
Commits130
Files88
Lines added13,599
Timeline2 days
Cloud API cost$0 (all local)

The stack

OpenClaw is a personal AI assistant you run on your own devices. It runs in Docker, handles Telegram natively (polling, message routing, access control), manages sub-agent spawning, and loads capabilities from skill files. A skill is a markdown file with a prompt and metadata describing what it can do. Drop one in the skills folder, it picks it up in under a second. No code, no builds, no deploys. The framework does the orchestration, the model does the thinking.

Qumio runs on a single OpenClaw container with a Telegram channel locked to one user. All model calls go through Ollama running a local Qwen model (qwen3.5:27b) on an RTX 5090. Google OAuth handles Gmail and Calendar access.

Design decisions

Telegram over a web app. I wanted something I'd actually open every day. Telegram is already on my phone.

All local processing. Every model call runs on Ollama. Email data gets PII-stripped by the local model before being formatted. No cloud API touches personal data.

Skills as prompts. Each capability is a separate text file. The AI model reads it and figures out execution at runtime. Iteration is editing a markdown file, not writing code.

Polling over webhooks. No public HTTPS endpoint needed. Polling just works for a single-user tool.

Filesystem for Obsidian. Direct file writes work when Obsidian is closed. Simpler than depending on a REST plugin. The daily notes are building up a structured archive of emails, calendar snapshots, and news summaries that could feed future projects.

How it was built

The entire project was planned and built with Claude Code using the GSD (Get Shit Done) workflow. Every phase went through the same cycle: discuss requirements, research the approach, generate a plan, execute with an agent, then verify the output.

Claude handled the planning artifacts, wrote the skill prompts, authored the Dockerfile, configured the OAuth flow, and iterated on prompt wording when the local model misbehaved. The GSD workflow kept everything tracked with phase directories, execution summaries, and milestone audits. When Phase 3's rewrite silently dropped a requirement, the milestone audit caught it.

I steered decisions (which model to use, what format the briefings should take, when to defer features) and tested each skill via Telegram. Claude did the rest. Two days, 130 commits.

v1.0 story (March 2026)

The problem

I was opening five apps every morning before I'd made coffee. Gmail, Google Calendar, a task manager, Obsidian, a news feed. I kept thinking: I already have Telegram open all day. What if I could just ask it for everything?

Finding OpenClaw

I looked at building on grammY first. Good library, sensible API. But once I had the bot responding, I still needed to write the Gmail integration, the Calendar integration, and figure out how the model would decide which one to call.

Then I found OpenClaw. Drop a skill file in the folder, it hot-reloads. No code, no deploys. Phase 1 was just: does the bot respond on Telegram? Once that worked, I added Gmail, then Calendar, each as its own skill.

The OAuth problem

Getting Google OAuth working locally took longer than everything else combined. The browser consent flow needs to redirect somewhere. When you're running in Docker on WSL2, "somewhere" is surprisingly hard to define. Small config change. Hours of debugging to find it.

What I learned

Skills are prompts, not code. Iteration is fast but debugging means staring at prompt wording instead of stack traces.

OAuth without a public endpoint is painful. The docs assume a public HTTPS endpoint. When you're building a local-only tool, nothing applies directly.

Get one thing working first. Phase 1 was just "does the bot respond?" Everything else came after.

Posts