Fam Zheng f646391f14 extract Output trait: decouple AI core from Telegram
- Add src/output.rs with Output trait and 3 implementations:
  TelegramOutput (streaming via draft/edit), GiteaOutput (comments),
  BufferOutput (for worker/tests)
- Refactor run_openai_with_tools and execute_tool to use &mut dyn Output
- Remove run_claude_streaming, invoke_claude_streaming, run_openai_streaming
  (dead code — only OpenAI-compatible backend is used now)
- Remove BackendConfig::Claude code path from handler
- stream.rs: 790 → 150 lines
2026-04-10 21:10:36 +01:00

NOC — Not OpenClaw

Telegram bot that bridges messages to local claude CLI sessions — chat with Claude directly from Telegram.

User → Telegram → noc bot → claude --resume → stream back → Telegram

~600 lines of Rust. One binary. One config file. Does the thing.

Why "Not OpenClaw"?

OpenClaw is an open-source AI agent framework with admirable ambitions. It supports 20+ messaging platforms, 35+ LLM providers, a hub-and-spoke gateway (Node.js), an agent runtime (separate language, naturally), a three-tier skills override system, built-in RAG pipelines, multi-agent routing, cron scheduling, browser automation, and voice wake-word detection. It has 400,000+ lines of code, 1,800+ open issues, and requires at least 1 GB of RAM to breathe. The official docs recommend a $600 Mac mini as a minimum viable host. Cold-start on a modest CPU: ~500 seconds. Security researchers have called it "a security nightmare dressed up as a daydream."

To be fair, if you need to orchestrate 47 Telegram bots across 12 LLM backends with a RAG pipeline and overnight autonomous tasks, OpenClaw is probably fine.

Most people just want to talk to Claude on their phone.

NOC is for those people.

How it works

  1. User sends a message to the bot
  2. First message must be the auth passphrase, otherwise the bot replies "not authenticated"
  3. Once authenticated, messages are piped to claude --resume <session_id> via stdin
  4. claude stdout is streamed back as the reply (message is edited live as tokens arrive)
  5. Files uploaded to the bot are forwarded to Claude; files Claude writes to the output dir are sent back
  6. Sessions are scoped per chat and refresh daily at a configurable hour (default: 5am)

Session IDs are deterministic — generated with UUIDv5 from (chat_id, date), format: noc-{chat_id}-{YYYYMMDD}.

Setup

cp config.example.yaml config.yaml
# fill in your values

Config

Key Description
tg.key Telegram bot token
auth.passphrase Passphrase required to authenticate each session
session.refresh_hour Hour (local time, 24h) when sessions reset (default: 5)

Deploy

Local

make deploy

Builds the release binary and installs a systemd --user service.

Remote (hera)

make deploy-hera

Builds locally, copies the binary and config to heradev, then starts the service there.

Logs

journalctl --user -u noc -f

Tech stack

Layer Technology
Language Rust (2021 edition)
Telegram teloxide 0.12
Async runtime tokio (full)
Config YAML + serde
Deployment systemd user service + Makefile

Roadmap

  • Streaming responses — edit message as output arrives
  • Markdown formatting — MarkdownV2 rendering
  • Timeout handling — kill claude if it hangs
  • Graceful shutdown on SIGTERM
  • /reset command — force new session without waiting for daily refresh
  • Rate limiting per chat
  • Voice message support — STT (whisper.cpp) → text → claude
  • Video/audio transcription
Description
NOC
Readme 784 KiB
Languages
Rust 99%
Makefile 1%