2026-04-18

My Telegram bot is just a CLI with a different surface

Don't build a chatbot. Build a CLI that takes Telegram input and returns Telegram output.

#telegram#openclaw#cli#mobile

The framing that unlocked it

I built three chatbots before this one. All three failed. They tried to "have a conversation." That's the wrong frame.

The fourth one works because I stopped framing it as a bot. It's a CLI. The input surface is Telegram. The output surface is Telegram. The middle is shell scripts.

What it does

I send /brief from anywhere — I get the morning brief. /pipe returns the active pipeline. /spend returns today's API spend. /last5 returns the last 5 commits across all my repos.

Each command is a shell script in ~/openclaw-network/commands/. The Telegram bot reads inbound messages, matches against /^[a-z]+/ to pick a command, runs it, returns stdout.

That's it. No conversation state. No memory. No "the assistant remembers your preferences." Just commands.

What it costs

Total monthly cost: $0. The bot runs on the Mac that's already on. Telegram bot API is free.

API costs from agents the bot triggers: about $20/month. About 60% of the chief-of-staff briefing's monthly spend now comes from on-demand /brief requests instead of scheduled crons.

What broke

The first version had memory — it tried to "remember" what I asked yesterday. Hallucinated half of it. Confidently. Deleted the memory layer entirely. Better.

The second version had natural language input — it'd parse "what's my pipeline" or "show pipe" or "pipe please." Half the time it'd misroute. Now I require /pipe. Slash-prefix or it doesn't fire.

Strictness is a feature. The boundary makes the system reliable.

What you can steal

If you're building a chatbot:

  1. Don't. Build a CLI with a chat surface.
  2. Require slash commands. Don't try to parse natural language.
  3. No memory. Each command is stateless. State lives in your file system or your DB, not in the bot.
  4. Run the bot on a box that's already on. Don't add infra for the bot.

Total build time for mine: about 6 hours, including the part where I deleted the bad version and started over.