| 主机 | 角色 |
| --- | --- |
| 本地桌面 | Claude Code 终端 + 微信消息轮询 |
| VPS | 回调服务 + deepseek-vision 代理 + nginx |
| 企微后台 | 消息回调 URL 配置 + 微信插件 |
二、前置准备
| 资源 | 说明 | 获取方式 |
| --- | --- | --- |
| 企业微信账号 | 需管理员权限 | work.weixin.qq.com 注册 |
| Linux VPS | 1 核 1G 即可 | 任意云厂商 |
| 域名 | 需公网可达,有 SSL 更佳 | 任意域名商 |
| DeepSeek API Key | 文本对话 | platform.deepseek.com |
| DashScope API Key | 图片识图(免费额度够用) | dashscope.aliyun.com |
| Docker | VPS 上需预装 | curl -fsSL https://get.docker.com | sh |
三、本地配置
3.1 目录结构
~/.claude/
├── .mcp.json # MCP 服务器配置
├── settings.json # 钩子配置
├── cache/
│ └── task-session.json # 任务状态缓存
└── test/wework-bot/
├── server.js # 本地 MCP 服务器(可选,提供 wework_* 工具)
├── wework-client.js # 企微 API 客户端
├── config.json # 配置
├── config.legacy.json # 企微凭证 ⚠️ 需 gitignore
├── server-vps.mjs # VPS 回调服务(核心)
├── wework-poll.sh # 轮询脚本
├── task-status.sh # 手工任务状态同步
├── sync-task-status.py # Stop 钩子自动同步
└── .gitignore
3.2 MCP 配置 (~/.claude/.mcp.json)
{
"mcpServers": {
"wework": {
"type": "stdio",
"command": "node",
"args": ["<你的路径>/test/wework-bot/server.js"],
"env": {
"WEWORK_CONFIG": "<你的路径>/test/wework-bot/config.json",
"WEWORK_LOG_DIR": "<你的路径>/test/wework-bot/logs"
}
}
}
}
⚠️ .mcp.json 必须放在 Claude Code 实际读取的配置目录下。部分环境(如 Windows 软链接目录)可能导致路径不被识别,确认 settings.json 所在目录即为正确位置。
3.3 钩子配置
在 settings.json 中添加:
SessionStart:启动微信轮询
{
"hooks": {
"SessionStart": [{
"matcher": "",
"hooks": [{
"type": "command",
"command": "bash <你的路径>/test/wework-bot/wework-poll.sh",
"async": true
}]
}]
}
}
Stop:自动同步任务状态到 VPS
{
"hooks": {
"Stop": [{
"matcher": "",
"hooks": [{
"type": "command",
"command": "python <你的路径>/test/wework-bot/sync-task-status.py"
}]
}]
}
}
四、VPS 部署
4.1 VPS 目录规划
/opt/
├── wecom-callback/ # 回调服务
│ ├── server.mjs # 主服务(Node.js)
│ ├── config.json # 凭证 + autoReply 配置 ⚠️ 600 权限
│ ├── merge-tasks.py # 任务合并脚本
│ ├── task-status.json # 任务状态数据
│ ├── events.log # 运行日志
│ └── inbox.jsonl # 消息收件箱
│
└── deepseek-vision/ # LLM 代理
├── .env # 环境变量 ⚠️ 600 权限
└── ...
4.2 回调服务 (server.mjs)
核心功能:
解密企微回调消息
文本消息 → 自动调 AI 回复(带对话记忆 20 轮)
图片消息 → 下载 → 调 deepseek-vision 代理识图 → AI 回复
检测"任务/进度"关键词 → 注入 task-status.json → AI 回答
提供 /inbox 相关 API(供本地轮询使用)
服务绑定 127.0.0.1:18909,不直接对外暴露。
完整代码见附录 A。
4.3 deepseek-vision 代理
基于开源项目 ErlichLiu/deepseek-vision 部署,为纯文本 LLM API 补齐视觉理解能力。
部署步骤:
cd /opt
git clone https://github.com/ErlichLiu/deepseek-vision.git
cd deepseek-vision
# ⚠️ 修复 Dockerfile 缺少 README.md 的问题
sed -i 's/^COPY pyproject.toml .\/$/COPY pyproject.toml README.md .\//' Dockerfile
创建 .env(权限 600):
# 必填
ADMIN_PASSWORD=<你自己设的密码>
MASTER_API_KEY=<客户端访问本代理的 Key>
DEEPSEEK_API_KEY=<你的 DeepSeek Key>
# 视觉识别(去 dashscope.aliyun.com 申请免费 Key)
VISION_API_KEY=<你的 DashScope Key>
# 高级
DEEPSEEK_BASE_URL=https://api.deepseek.com/anthropic
PORT=8000
构建并启动:
docker build -t deepseek-vision .
docker run -d --name deepseek-vision --restart unless-stopped \
--env-file /opt/deepseek-vision/.env \
-p 127.0.0.1:8000:8000 deepseek-vision
⚠️ 修改 .env 后必须 docker rm -f deepseek-vision 再 docker run,单纯的 docker restart 不会重读 .env。
4.4 nginx 配置
server {
listen 80;
server_name your.domain.com;
# 企微回调 — 必须公网可达
location / {
proxy_pass http://127.0.0.1:18909;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 收件箱/回复/聊天管理 API — 仅本地访问
location /inbox {
allow 127.0.0.1;
deny all;
proxy_pass http://127.0.0.1:18909;
}
location /reply {
allow 127.0.0.1;
deny all;
proxy_pass http://127.0.0.1:18909;
}
location /chat {
allow 127.0.0.1;
deny all;
proxy_pass http://127.0.0.1:18909;
}
}
五、企微后台配置
5.1 创建应用
1. 登录 企业微信管理后台
2. 应用管理 → 创建应用 → 记录 AgentID 和 Secret
3. 记下 企业 ID (corpId):在「我的企业」→「企业信息」页底部
5.2 API 接收消息
应用详情 → 接收消息 → 设置 API 接收:
| 字段 | 说明 |
| --- | --- |
| URL | http://your.domain.com/ |
| Token | 随机字符串(自己生成,记下来) |
| EncodingAESKey | 随机 43 位(后台可自动生成) |
三项填写后与 VPS 回调服务 config.json 保持一致即可。保存时企微会发起 URL 验证,服务正常返回即通过。
5.3 微信插件(关键步骤)
路径:管理后台 → 我的企业 → 微信插件(⚠️ 不在应用管理里)
关键设置:
✅ 勾选「允许成员在微信插件中接收和回复聊天消息」
❌ 不要勾选「成员使用微信插件时需要使用企业微信客户端」
生成邀请二维码(有效期 7 天),发给微信好友扫码即可在微信里对话
六、VPS 回调服务配置 (config.json)
{
"token": "<你的 Token>",
"encodingAESKey": "<你的 EncodingAESKey>",
"corpId": "<你的企业 ID>",
"secret": "<你的应用 Secret>",
"agentId": "<你的 AgentID>",
"autoReply": {
"enabled": true,
"proxyUrl": "http://127.0.0.1:8000/v1/messages",
"proxyKey": "<MASTER_API_KEY>",
"model": "deepseek-v4-flash",
"apiKey": "<你的 DeepSeek Key>",
"systemPrompt": "你的 System Prompt,定义 AI 的人设和回复风格"
}
}
七、任务状态同步机制
原理
Claude Code 会话结束
→ Stop 钩子触发
→ sync-task-status.py 读取本地 cache/task-session.json
→ SSH stdin 管道 → VPS merge-tasks.py(按任务名 upsert)
→ task-status.json 原子写入
→ 微信问"进度"时自动注入 AI 上下文
手工同步
bash task-status.sh --add "任务名" "详情"
bash task-status.sh --done "任务名"
bash task-status.sh --list
bash task-status.sh --clear
八、安全措施清单
| 检查项 | 措施 |
| --- | --- |
| VPS 配置文件 | chmod 600 config.json .env |
| 收件箱 API | nginx allow 127.0.0.1; deny all; |
| 密钥文件 | 加入 .gitignore(config.legacy.json, .mcp.json, .env) |
| Docker 容器 | 非 root 用户运行 |
| 回调服务 | 仅绑定 127.0.0.1,不对外监听 |
| API Key 存放 | 单一配置文件,不硬编码在代码中 |
注意
Claude Code 的 ~/.claude/projects/ 目录下的 transcript .jsonl 文件会包含会话中出现的 API Key
~/.claude/file-history/ 有文件历史版本,同样可能含 Key
这些是 Claude Code 内部日志,用于会话恢复和审计,建议定期清理旧会话
九、常见问题 & 踩坑记录
9.1 启动/部署相关
| 问题 | 原因 | 解决 |
| --- | --- | --- |
| MCP 工具未加载 | .mcp.json 不在正确配置目录 | 确认目录与 settings.json 同路径 |
| Docker 容器启动后识图不工作 | docker restart 不重读 .env | docker rm -f 后重新 docker run |
| DashScope 视觉 API 400 错误 | 测试图片分辨率过小(<10×10) | 使用真实尺寸图片测试 |
Python -c 在 ssh 里语法错误 | 多行脚本被 shell 截断 | 改为 VPS 驻留脚本 + stdin 传数据 |
Dockerfile 构建失败 README.md missing | 上游 bug | COPY pyproject.toml → COPY pyproject.toml README.md |
9.2 功能相关
| 问题 | 原因 | 解决 |
| --- | --- | --- |
| 微信插件入口找不到 | 在应用管理里找 | 正确路径:我的企业 → 微信插件 |
| 识图返回"无法查看" | 用了不支持 vision 的 API 端点 | 用 deepseek-vision 代理自动分流 |
| task-status.json 被清空 | Shell echo '$var' 遇单引号截断 JSON | 改用 stdin 管道传数据 |
| 撤回消息无效 | 微信插件端不支持 API 撤回 | 企微客户端的消息可撤回,微信侧不行 |