Files
echo-core/HANDOFF.md
MoltBot Service 80502b7931 stage-13: WhatsApp bridge with Baileys + Python adapter
Node.js bridge (bridge/whatsapp/): Baileys client with Express HTTP API
on localhost:8098 — QR code linking, message queue, reconnection logic.

Python adapter (src/adapters/whatsapp.py): polls bridge every 2s, routes
through router.py, separate whatsapp.owner/admins auth, security logging.

Integrated in main.py alongside Discord + Telegram via asyncio.gather.
CLI: echo whatsapp status/qr. 442 tests pass (32 new, zero failures).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 21:41:16 +00:00

5.7 KiB

Echo Core — Session Handoff

Data: 2026-02-13 Proiect: ~/echo-core/ (inlocuire completa OpenClaw) Plan complet: ~/.claude/plans/enumerated-noodling-floyd.md


Status curent: Stage 13 — COMPLET. Toate stages finalizate.

Stages completate (toate committed):

  • Stage 1 (f2973aa): Project Bootstrap — structura, git, venv, copiere fisiere din clawd
  • Stage 2 (010580b): Secrets Manager — keyring, CLI echo secrets set/list/test
  • Stage 3 (339866b): Claude CLI Wrapper — start/resume/clear sessions cu claude --resume
  • Stage 4 (6cd155b): Discord Bot Minimal — online, /ping, /channel add, /admin add, /setup
  • Stage 5 (a1a6ca9): Discord + Claude Chat — conversatii complete, typing indicator, message split
  • Stage 6 (5bdceff): Model Selection — /model opus/sonnet/haiku, default per canal
  • Stage 7 (09d3de0): CLI Tool — echo status/doctor/restart/logs/sessions/channel/send
  • Stage 8 (24a4d87): Cron Scheduler — APScheduler, /cron add/list/run/enable/disable
  • Stage 9 (0bc4b8c): Heartbeat — verificari periodice (email, calendar, kb index, git)
  • Stage 10 (0ecfa63): Memory Search — Ollama all-minilm embeddings + SQLite semantic search
  • Stage 10.5 (85c72e4): Rename secrets.py, enhanced /status, usage tracking
  • Stage 11 (d1bb67a): Security Hardening — prompt injection, invocation/security logging, extended doctor
  • Stage 12 (2d8e56d): Telegram Bot — python-telegram-bot, commands, inline keyboards, concurrent with Discord
  • Stage 13: WhatsApp Bridge — Baileys Node.js bridge + Python adapter, polling, CLI commands

Total teste: 442 PASS (zero failures)


Ce a fost implementat in Stage 13:

  1. bridge/whatsapp/ — Node.js WhatsApp bridge:

    • Baileys (@whiskeysockets/baileys) — lightweight, no Chromium
    • Express HTTP server on localhost:8098
    • Endpoints: GET /status, GET /qr, POST /send, GET /messages
    • QR code generation as base64 PNG for device linking
    • Session persistence in bridge/whatsapp/auth/
    • Reconnection with exponential backoff (max 5 attempts)
    • Message queue: incoming text messages queued, drained on poll
    • Graceful shutdown on SIGTERM/SIGINT
  2. src/adapters/whatsapp.py — Python WhatsApp adapter:

    • Polls Node.js bridge every 2s via httpx
    • Routes through existing router.py (same as Discord/Telegram)
    • Separate auth: whatsapp.owner + whatsapp.admins (phone numbers)
    • Private chat: admin-only (unauthorized logged to security.log)
    • Group chat: registered chats only (skipped for now)
    • Commands: /clear, /status handled inline
    • Other commands and messages routed to Claude via route_message
    • Message splitting at 4096 chars
    • Wait-for-bridge logic on startup (30 retries, 5s interval)
  3. main.py — Concurrent execution:

    • Discord + Telegram + WhatsApp in same event loop via asyncio.gather
    • WhatsApp optional: enabled via config.json whatsapp.enabled
    • No new secrets needed (bridge URL configured in config.json)
  4. config.json — New sections:

    • whatsapp: {enabled, bridge_url, owner, admins}
    • whatsapp_channels: {}
  5. cli.py — New commands:

    • echo whatsapp status — check bridge connection
    • echo whatsapp qr — show QR code instructions
  6. .gitignore — Added bridge/whatsapp/node_modules/ and auth/


Setup WhatsApp:

# 1. Install Node.js bridge dependencies:
cd ~/echo-core/bridge/whatsapp && npm install

# 2. Start the bridge:
node bridge/whatsapp/index.js
# → QR code will appear — scan with WhatsApp (Linked Devices)

# 3. Enable in config.json:
#   "whatsapp": {"enabled": true, "bridge_url": "http://127.0.0.1:8098", "owner": "PHONE", "admins": []}

# 4. Restart Echo Core:
echo restart

# 5. Send a message from WhatsApp to the linked number

Fisiere cheie:

Fisier Descriere
src/main.py Entry point — Discord + Telegram + WhatsApp + scheduler + heartbeat
src/claude_session.py Claude Code CLI wrapper cu --resume, injection protection
src/router.py Message routing (comanda vs Claude)
src/scheduler.py APScheduler cron jobs
src/heartbeat.py Verificari periodice
src/memory_search.py Semantic search — Ollama embeddings + SQLite
src/credential_store.py Credential broker (keyring)
src/config.py Config loader (config.json)
src/adapters/discord_bot.py Discord bot cu slash commands
src/adapters/telegram_bot.py Telegram bot cu commands + inline keyboards
src/adapters/whatsapp.py WhatsApp adapter — polls Node.js bridge
bridge/whatsapp/index.js Node.js WhatsApp bridge — Baileys + Express
cli.py CLI: echo status/doctor/restart/logs/secrets/cron/heartbeat/memory/whatsapp
config.json Runtime config (channels, telegram_channels, whatsapp, admins, models)

Decizii arhitecturale:

  • Claude invocation: Claude Code CLI cu --resume pentru sesiuni persistente
  • Credentials: keyring (nu plain text pe disk), subprocess isolation
  • Discord: slash commands (/), canale asociate dinamic
  • Telegram: commands + inline keyboards, @mention/reply in groups
  • WhatsApp: Baileys Node.js bridge + Python polling adapter, separate auth namespace
  • Cron: APScheduler, sesiuni izolate per job, --allowedTools per job
  • Heartbeat: verificari periodice, quiet hours (23-08), state tracking
  • Memory Search: Ollama all-minilm (384 dim), SQLite, cosine similarity
  • Security: prompt injection markers, separate security.log, extended doctor
  • Concurrency: Discord + Telegram + WhatsApp in same asyncio event loop via gather

Infrastructura: