claw-gateway 是一个“单飞书机器人入口 -> 多 OpenClaw 实例”的网关服务。
目标是让用户只和一个飞书机器人交互,由网关按用户映射把请求转发到对应实例。
- 单机器人接入:飞书侧只暴露一个机器人应用入口。
- 固定路由:按
open_id -> instance_id/instance_url做 1:1 映射。 - 异步任务:事件入队,worker 异步处理,支持重试和死信。
- 幂等去重:飞书重复投递不会重复处理。
- 消息类型:支持
text / markdown / post / interactive_card / file / image回传飞书。 - 文件链路:支持飞书文件/图片下载后转发到 OpenClaw;支持 OpenClaw 回传附件再上传飞书。
- WebSocket 上游:当
instance_url为ws://或wss://时,自动使用 WS 调用并支持设备身份签名握手。 - 管理面:提供
/admin/mappingsAPI 和/ui/管理页面。
app/main.py:应用入口app/api/:HTTP API(飞书事件、回调、管理、健康检查)app/clients/:飞书与 OpenClaw 客户端app/services/:路由、分发、任务处理、消息校验app/workers/worker.py:异步消费进程app/ui/:管理前端tests/:测试k8s/:Kubernetes 清单
cp .env.example .env
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload新开终端启动 worker:
source .venv/bin/activate
python -m app.workers.workercp .env.docker.example .env.docker
docker compose up --build -d
docker compose ps
curl http://localhost:18000/healthz管理台地址:
http://localhost:18000/ui/
停止服务:
docker compose down默认端口:
- Gateway:
18000 - Postgres:
15432 - Redis:
16379
可通过 .env.docker 覆盖:
GATEWAY_PORTPOSTGRES_PORTREDIS_PORT
- 回调地址:
{GATEWAY_PUBLIC_BASE_URL}/feishu/events - 需要在环境变量中配置:
FEISHU_APP_IDFEISHU_APP_SECRETFEISHU_VERIFY_TOKENFEISHU_ENCRYPT_KEY(建议开启)
- 回调地址:
{GATEWAY_PUBLIC_BASE_URL}/gateway/openclaw/callback - 建议配置回调签名密钥:
OPENCLAW_CALLBACK_SECRET
curl -X POST http://localhost:18000/admin/mappings \
-H "Content-Type: application/json" \
-d '{
"open_id":"ou_test_user",
"instance_id":"inst_001",
"instance_url":"ws://openclaw.internal:37707/307jao",
"status":"ACTIVE",
"gateway_token":"your_gateway_token"
}'查询映射:
curl http://localhost:18000/admin/mappings/ou_test_user分页查询:
curl "http://localhost:18000/admin/mappings?limit=50&offset=0"POST /feishu/events- 支持
url_verification - 支持
im.message.receive_v1与card.action.trigger
POST /gateway/openclaw/callbackmultipart/form-data- 必填 part:
payload(JSON) - 附件 part:使用
attachment_id命名
payload 示例:
{
"task_id": "task_x",
"open_id": "ou_x",
"chat_id": "oc_x",
"messages": [
{"type": "text", "text": "done"},
{"type": "post", "content": {"zh_cn": {"title": "t", "content": []}}},
{"type": "interactive_card", "content": {"config": {}, "elements": []}},
{"type": "file", "attachment_id": "result_pdf", "file_name": "result.pdf", "mime_type": "application/pdf"},
{"type": "image", "attachment_id": "plot_png", "file_name": "plot.png", "mime_type": "image/png"}
],
"metadata": {}
}USE_REDIS_QUEUE:生产建议trueDATABASE_URL:数据库连接串REDIS_URL:队列与缓存GATEWAY_PUBLIC_BASE_URL:飞书/OpenClaw 回调可访问公网地址DEFAULT_MESSAGE_MAX_BYTES:附件大小上限ALLOWED_MIME_TYPES:允许的 MIME 白名单OPENCLAW_STATE_DIR:WS 设备身份与 token 持久化目录OPENCLAW_WS_REQUESTED_SCOPES:默认operator.read,operator.write
- WS 上游最小实现下,仅支持图片附件(
image/*)透传;非图片文件走 WS 会失败。 - Markdown 渲染依赖飞书消息能力,复杂语法会降级;网关会优先发卡片 markdown,失败后回退
post。 - 当前映射模型为
1 用户 : 1 实例,不支持会话级多实例选择。 gateway_token仅在写入时接收,查询接口不会返回明文;若 token 权限不足,任务会失败并返回task_id。- 若未配置
FEISHU_ENCRYPT_KEY或OPENCLAW_CALLBACK_SECRET,对应签名校验会退化为关闭状态。
- 不要提交真实凭据(
.env、.env.docker、云厂商密钥、生产 token)。 - 仅提交示例模板(如
.env.example、.env.docker.example)。 - 映射中的
gateway_token应使用最小权限,并定期轮换。 - 建议在 CI 增加 secret 扫描(例如 gitleaks/trufflehog)。
python scripts/seed_mappings.py mappings.csv http://localhost:18000CSV 表头:
open_id,instance_id,instance_url,status,gateway_token
k8s/ 目录包含:
configmap.yamlsecret.yamldeployment.yamlservice.yamlhpa.yaml