Go to file
anonsaber 0e10591534 docs(design): §8.1 BotError 目标形态代码块加消歧注释
Q5 一致处理:代码块内补一行「// 目标形态(teloxide 未引入)」,与上方免责互证,消除重构后唯一例外。
2026-09-27 20:49:53 +08:00
.github/workflows feat: initial MessageWeave release 2026-09-25 09:14:04 +08:00
cloudflare-worker chore(worker): rename proxy to lb and ignore build cache 2026-09-27 12:52:55 +08:00
docs docs(design): §8.1 BotError 目标形态代码块加消歧注释 2026-09-27 20:49:53 +08:00
src feat(notify): unify /ready not-ready 503 into the error envelope 2026-09-27 13:11:29 +08:00
web feat(web): add SPA i18n with browser-language detection (zh/en, default en) 2026-09-27 12:53:36 +08:00
.dockerignore feat: initial MessageWeave release 2026-09-25 09:14:04 +08:00
.env.example refactor: rename project to MessageWeave 2026-09-25 10:29:18 +08:00
.gitignore chore(worker): rename proxy to lb and ignore build cache 2026-09-27 12:52:55 +08:00
AGENTS.md docs: 重构文档体系 — README 瘦身中英对等 + 新增 reference.md 权威事实表 2026-09-27 18:55:38 +08:00
Cargo.lock fix(redis): install explicit rustls crypto provider 2026-09-25 18:02:21 +08:00
Cargo.toml fix(redis): install explicit rustls crypto provider 2026-09-25 18:02:21 +08:00
Dockerfile chore(worker): rename proxy to lb and ignore build cache 2026-09-27 12:52:55 +08:00
README.md docs: 重构文档体系 — README 瘦身中英对等 + 新增 reference.md 权威事实表 2026-09-27 18:55:38 +08:00
README.zh-CN.md docs: 重构文档体系 — README 瘦身中英对等 + 新增 reference.md 权威事实表 2026-09-27 18:55:38 +08:00
hoststack.yaml docs(hoststack): add native Rust deployment config 2026-09-25 18:51:36 +08:00

README.md

MessageWeave

中文文档 / Chinese documentation → README.zh-CN.md

One Telegram bot per mailbox. New mail arrives as metadata; the original is always fetched read-only from your own JMAP server.

1. What it is

MessageWeave sits between a JMAP mail server (for example Stalwart) and a Telegram bot.

  • Inbound. A JMAP push subscription tells the service that a message changed. Nothing is polled at rest.
  • Outbound. Each event becomes a short, metadata-only Telegram notification: sender, subject, timestamp. Mail bodies are never sent to Telegram.
  • On demand. When you ask, the service reads the original through a fresh JMAP read call. Nothing is cached in between.
  • Optionally summarised. If you explicitly opt in, an OpenAI-compatible LLM returns a short summary. Requests, responses and attachment bytes are never persisted.

State is an architectural boundary here, not a preference.

  • Redis is the only state store. No database, no embedded store, no second store.
  • The process writes nothing to disk. No log files, no data files, no local volume.
  • No long-lived connections. No SSE, no WebSocket, no long polling.
  • Logs go to stdout only. The platform's collector owns log storage and retention.
  • What it is not. It is not a mail client, not a proxy, and not a relay. It forwards metadata to one bot; it does not read arbitrary URLs, open tunnels, or broker traffic.

2. 5-minute setup

Requires a reachable Redis 7 instance and a JMAP session plus a Telegram bot token.

cp .env.example .env           # fill REDIS_URL and CONFIG_ENCRYPTION_KEY
docker build -t messageweave:latest .
docker run --env-file .env -p 8080:8080 messageweave:latest

Then open http://localhost:8080 in a browser. The first-boot SPA calls POST /api/bootstrap, stores the business secrets in Redis, and creates the admin session. From that point the browser configures the service through Redis — no environment variable is read or written again for business configuration.

For local builds without Docker: cargo build --locked produces the message-weave binary.

If the service answers requests but does nothing useful, check the logs for a startup warning: a missing required variable does not crash the process. It serves a read-only setup router over in-memory state instead. See §3.

3. Configuration entry points

Three layers. They are not interchangeable.

Boot-time environment — 2 required, 2 optional.

Variable Required Default
REDIS_URL yes —
CONFIG_ENCRYPTION_KEY yes —
PORT no 8080
RUN_MODE no webhook

RUN_MODE accepts webhook or reconcile. .env.example ships only the two required variables; the rest are documented defaults.

Business configuration — Redis, written by the browser. POST /api/bootstrap is the one-shot trust bootstrap; PUT /api/business-config hot- reloads individual settings within about one second. The process never reads business secrets from the environment in normal operation.

Health. GET /healthz returns 200 unconditionally — it is liveness, not readiness. GET /ready returns 503 until configuration and Redis are available. Probe /ready, not /healthz, when deciding whether to route traffic.

4. Security boundary, in one sentence

All state lives in Redis; the process reads only two environment variables and writes nothing to disk.

One corollary matters for setup: the bootstrap one-shot token is the password component of REDIS_URL. The Redis ACL credential is therefore both the application connection credential and the trust root for bootstrap — keep it private and rotate it as one value.

5. Where to read more

Document What it answers
docs/design.md Why the system is shaped this way: data flow, JMAP semantics, Redis streams, AI consent rules
docs/deployment.md How to deploy: Dockerfile, secrets, Redis hosting, webhook/push/reconcile routing, multi-instance load balancing
docs/reference.md Single source of truth for verifiable facts — Redis keys and TTLs, error codes, routes, environment layers, budgets
docs/roadmap.md Gaps, blockers and the next phase
AGENTS.md Contribution rules, hard boundaries, the stable-ID index for cross-document references

Facts that matter are traceable. If two documents disagree, docs/reference.md wins.