OpenClaw 微信机器人搭建教程

Zane
13 min read
#OpenClaw#微信#机器人#AI
OpenClaw 微信机器人搭建教程

微信在国内的地位不需要多说。超过 13 亿月活用户,几乎所有商业沟通都发生在这里。如果你想把 AI 能力接入微信,OpenClaw 是目前最顺手的方案之一。

2026 年初这个话题在中文开发者圈子里热度很高。@frxiaobei 在 X 上发布了「微信直接支持 OpenClaw 教程」,@xiangxiang103 整理了详细的「OpenClaw 微信插件安装使用教程」,@jonnytang6 也在龙虾日记系列里记录了微信接入成功的完整流程。r/ai_chinese 上同期也出现了专门讨论 WeChat bridge 配置的高热度帖子。官方插件方面,腾讯提供了 @tencent-weixin/openclaw-weixin-cli 作为微信接入的标准工具包,本教程的代码方案也与该插件兼容。

本教程从架构原理讲起,带你一步步完成公众号接入、企业微信配置、消息处理逻辑,最后部署到阿里云 ECS。全程有 Node.js 代码示例,注释用中文写。

如果你还没安装 OpenClaw,先看这篇:OpenClaw 完全安装指南 2026


一、整体架构

OpenClaw 接入微信的方式有两条路:

路径 A:微信公众号(服务号/订阅号)

用户在公众号对话框发消息,消息通过微信服务器转发到你的 webhook,OpenClaw 处理后返回回复。整个链路是:

用户发消息 -> 微信服务器 -> 你的 webhook 服务器 -> OpenClaw API -> 回复

路径 B:企业微信机器人

企业微信群里 @机器人,消息通过 webhook 推送到你的服务,OpenClaw 处理后把结果发回群里。链路更简单:

群成员 @机器人 -> 企业微信 webhook -> OpenClaw API -> 发消息到群

两条路都要求你有一个公网可访问的服务器,并且支持 HTTPS。没有固定 IP 的本地开发阶段可以用 frp 或者 ngrok 做内网穿透临时测试,但正式上线建议直接用 ECS。


二、微信公众号接入

2.1 准备公众号

登录微信公众平台,进入「设置与开发」->「基本配置」。

你需要填写:

  • 服务器地址(URL):你的 webhook 地址,格式为 https://your-domain.com/wechat/webhook
  • 令牌(Token):自己随机填一个字符串,用于验证请求来源
  • 消息加解密密钥(EncodingAESKey):点「随机生成」即可
  • 消息加解密方式:建议选「安全模式」

保存之前,微信会向你填的 URL 发一个 GET 请求做验证。你的服务器要先跑起来。

2.2 搭建 webhook 服务器

// server.js
const express = require('express')
const crypto = require('crypto')
const xml2js = require('xml2js')

const app = express()

// 微信配置(从环境变量读取,不要硬编码)
const WECHAT_TOKEN = process.env.WECHAT_TOKEN
const WECHAT_APP_ID = process.env.WECHAT_APP_ID
const WECHAT_APP_SECRET = process.env.WECHAT_APP_SECRET

// 验证微信服务器请求
app.get('/wechat/webhook', (req, res) => {
  const { signature, timestamp, nonce, echostr } = req.query

  // 按微信要求排序后拼接再 SHA1 加密
  const str = [WECHAT_TOKEN, timestamp, nonce].sort().join('')
  const hash = crypto.createHash('sha1').update(str).digest('hex')

  if (hash === signature) {
    // 验证通过,返回 echostr
    res.send(echostr)
  } else {
    res.status(403).send('验证失败')
  }
})

// 接收用户消息
app.post('/wechat/webhook', express.text({ type: 'text/xml' }), async (req, res) => {
  const parser = new xml2js.Parser({ explicitArray: false })
  const body = await parser.parseStringPromise(req.body)
  const msg = body.xml

  // 只处理文本消息
  if (msg.MsgType !== 'text') {
    res.send('success')
    return
  }

  const userOpenId = msg.FromUserName
  const toUser = msg.ToUserName
  const userMessage = msg.Content

  // 调用 OpenClaw 处理消息
  const reply = await processWithOpenClaw(userMessage, userOpenId)

  // 按微信要求返回 XML 格式
  const replyXml = `
    <xml>
      <ToUserName><![CDATA[${userOpenId}]]></ToUserName>
      <FromUserName><![CDATA[${toUser}]]></FromUserName>
      <CreateTime>${Math.floor(Date.now() / 1000)}</CreateTime>
      <MsgType><![CDATA[text]]></MsgType>
      <Content><![CDATA[${reply}]]></Content>
    </xml>
  `

  res.set('Content-Type', 'text/xml')
  res.send(replyXml)
})

app.listen(3000, () => {
  console.log('微信 webhook 服务启动,端口 3000')
})

安装依赖:

npm install express xml2js

三、企业微信机器人配置

企业微信的接入比公众号简单很多,不需要服务号资质。

3.1 创建群机器人

在企业微信群里,点右上角「...」->「添加机器人」->「新创建一个机器人」,填写机器人名称,完成后会生成一个 webhook URL,格式类似:

https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

这个 URL 就是你往群里发消息的接口。

3.2 接收群消息

如果你需要接收群成员发的消息,还需要配置「群机器人接收消息」功能(需要企业管理员在后台开启)。配置方式和公众号类似,填写 webhook URL 和 Token。

// 企业微信机器人:往群里发消息
const axios = require('axios')

async function sendToWorkWeChat(webhookUrl, content) {
  const payload = {
    msgtype: 'text',
    text: {
      content: content
    }
  }

  const response = await axios.post(webhookUrl, payload, {
    headers: { 'Content-Type': 'application/json' }
  })

  return response.data
}

// 接收企业微信群消息的 webhook
app.post('/workwechat/webhook', express.json(), async (req, res) => {
  const event = req.body

  // 只处理文本消息类型
  if (event.MsgType !== 'text') {
    res.json({ errcode: 0 })
    return
  }

  const userMessage = event.Content
  const groupChatId = event.ChatId

  // 用 OpenClaw 处理
  const reply = await processWithOpenClaw(userMessage, groupChatId)

  // 发回群里
  await sendToWorkWeChat(process.env.WORK_WECHAT_WEBHOOK_URL, reply)

  res.json({ errcode: 0 })
})

四、OpenClaw 消息处理核心逻辑

4.1 连接 OpenClaw API

// openclaw-client.js
const axios = require('axios')

const OPENCLAW_BASE_URL = process.env.OPENCLAW_BASE_URL || 'http://localhost:11434'
const OPENCLAW_MODEL = process.env.OPENCLAW_MODEL || 'claude-3-5-sonnet'

// 单轮对话:不保留上下文
async function chatSingle(userMessage) {
  const response = await axios.post(`${OPENCLAW_BASE_URL}/v1/chat/completions`, {
    model: OPENCLAW_MODEL,
    messages: [
      {
        role: 'system',
        content: '你是一个友好的助手,请用简洁的中文回答问题。回答控制在 200 字以内,适合微信消息阅读。'
      },
      {
        role: 'user',
        content: userMessage
      }
    ],
    max_tokens: 500,
    temperature: 0.7
  }, {
    headers: {
      'Authorization': `Bearer ${process.env.OPENCLAW_API_KEY}`,
      'Content-Type': 'application/json'
    },
    // 超时设置:微信要求 5 秒内响应,OpenClaw 可能需要一些时间
    timeout: 4500
  })

  return response.data.choices[0].message.content
}

module.exports = { chatSingle }

4.2 整合到 webhook

const { chatSingle } = require('./openclaw-client')

// 处理消息的主函数
async function processWithOpenClaw(userMessage, userId) {
  try {
    const reply = await chatSingle(userMessage)
    return reply
  } catch (error) {
    // 超时或 API 错误时返回友好提示
    if (error.code === 'ECONNABORTED') {
      return '处理时间较长,请稍后再试。'
    }
    console.error('OpenClaw 调用失败:', error.message)
    return '抱歉,暂时无法处理您的请求,请稍后再试。'
  }
}

五、多轮对话与上下文管理

单轮问答已经够用了,但如果你想让机器人记住对话历史,需要加一个上下文存储层。

// context-store.js
// 简单的内存存储,生产环境建议换成 Redis
const contextMap = new Map()

// 每个用户最多保留 10 轮对话
const MAX_HISTORY = 10

function getContext(userId) {
  if (!contextMap.has(userId)) {
    contextMap.set(userId, [])
  }
  return contextMap.get(userId)
}

function addToContext(userId, role, content) {
  const history = getContext(userId)
  history.push({ role, content })

  // 超出限制时删除最早的一轮
  if (history.length > MAX_HISTORY * 2) {
    history.splice(0, 2)
  }
}

function clearContext(userId) {
  contextMap.delete(userId)
}

module.exports = { getContext, addToContext, clearContext }
// 带上下文的多轮对话
const { getContext, addToContext, clearContext } = require('./context-store')

async function chatWithContext(userMessage, userId) {
  // 支持用户主动清空对话
  if (userMessage.trim() === '清除记忆' || userMessage.trim() === '/clear') {
    clearContext(userId)
    return '好的,我已经忘记之前的对话了,可以重新开始。'
  }

  const history = getContext(userId)

  // 构建完整消息列表
  const messages = [
    {
      role: 'system',
      content: '你是一个友好的助手。用简洁的中文回答,适合微信消息阅读。如果用户想清除对话记录,告诉他们发送"清除记忆"即可。'
    },
    ...history,
    { role: 'user', content: userMessage }
  ]

  const response = await axios.post(`${OPENCLAW_BASE_URL}/v1/chat/completions`, {
    model: OPENCLAW_MODEL,
    messages,
    max_tokens: 500,
    temperature: 0.7
  }, {
    headers: {
      'Authorization': `Bearer ${process.env.OPENCLAW_API_KEY}`,
      'Content-Type': 'application/json'
    },
    timeout: 4500
  })

  const reply = response.data.choices[0].message.content

  // 把这轮对话存入上下文
  addToContext(userId, 'user', userMessage)
  addToContext(userId, 'assistant', reply)

  return reply
}

注意:内存存储在服务重启后会丢失,生产环境建议把 contextMap 替换为 Redis。


六、部署到阿里云 ECS

6.1 服务器要求

  • 系统:Ubuntu 22.04 LTS(推荐)
  • 配置:2 核 2GB 起,OpenClaw 本地运行的话建议 4 核 8GB
  • 带宽:1Mbps 够用,主要是延迟要低
  • 必须有公网 IP 和域名(微信要求 HTTPS)

6.2 配置 HTTPS

微信公众号的 webhook 地址必须是 HTTPS,自签证书不行。最简单的方式是用 Nginx + Let's Encrypt:

# 安装 Nginx 和 certbot
sudo apt update
sudo apt install nginx certbot python3-certbot-nginx

# 申请证书(把 your-domain.com 换成你的域名)
sudo certbot --nginx -d your-domain.com

配置 Nginx 反向代理到 Node.js 服务:

server {
    listen 443 ssl;
    server_name your-domain.com;

    # certbot 会自动填充 ssl 相关配置

    location /wechat/ {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

6.3 用 Docker 运行

在 ECS 上用 Docker 部署更方便管理:

# Dockerfile
FROM node:20-alpine

WORKDIR /app

COPY package*.json ./
RUN npm ci --production

COPY . .

EXPOSE 3000

CMD ["node", "server.js"]
# docker-compose.yml
version: '3.8'

services:
  wechat-bot:
    build: .
    ports:
      - "3000:3000"
    environment:
      - WECHAT_TOKEN=${WECHAT_TOKEN}
      - WECHAT_APP_ID=${WECHAT_APP_ID}
      - WECHAT_APP_SECRET=${WECHAT_APP_SECRET}
      - OPENCLAW_BASE_URL=${OPENCLAW_BASE_URL}
      - OPENCLAW_API_KEY=${OPENCLAW_API_KEY}
      - OPENCLAW_MODEL=${OPENCLAW_MODEL}
    restart: unless-stopped
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

启动:

docker-compose up -d

七、限流与错误处理

微信公众号有接口调用频率限制:普通接口每天调用上限 1000 次(订阅号),服务号更高。OpenClaw 自身也可能有并发限制,视你的部署方式而定。

7.1 简单限流

// rate-limiter.js
// 按用户 ID 做限流,每分钟最多 5 次请求
const requestCounts = new Map()
const RATE_LIMIT = 5
const WINDOW_MS = 60 * 1000

function isRateLimited(userId) {
  const now = Date.now()
  const userRecord = requestCounts.get(userId) || { count: 0, windowStart: now }

  // 超过时间窗口,重置计数
  if (now - userRecord.windowStart > WINDOW_MS) {
    requestCounts.set(userId, { count: 1, windowStart: now })
    return false
  }

  // 在时间窗口内,检查次数
  if (userRecord.count >= RATE_LIMIT) {
    return true
  }

  // 计数加一
  userRecord.count++
  requestCounts.set(userId, userRecord)
  return false
}

module.exports = { isRateLimited }
// 在消息处理中加入限流检查
const { isRateLimited } = require('./rate-limiter')

async function processWithOpenClaw(userMessage, userId) {
  if (isRateLimited(userId)) {
    return '你发送得太频繁了,请稍等一分钟再试。'
  }

  try {
    return await chatWithContext(userMessage, userId)
  } catch (error) {
    if (error.code === 'ECONNABORTED') {
      return '回答需要一点时间,请再发一次或稍后重试。'
    }
    console.error(`处理失败 [userId: ${userId}]:`, error.message)
    return '遇到了一点问题,请稍后再试。'
  }
}

7.2 微信 5 秒超时问题

微信要求服务器在 5 秒内响应,否则会重发消息并提示用户"该公众号暂时无法提供服务"。如果 OpenClaw 的响应时间可能超过 4 秒,有两个处理方案:

方案一:先回复"处理中",再异步推送结果

公众号不直接支持异步推送,需要用客服消息接口。这需要服务号资质,且需要先获取用户 access_token

方案二:降低模型复杂度

对实时性要求高的场景,选用响应更快的模型,比如 Claude 3 Haiku。在 .env 里配置:

OPENCLAW_MODEL=claude-3-haiku-20240307

八、安全注意事项

微信机器人会接收到真实用户的输入,安全不能忽视。主要的几点:

  1. 验证请求来源:每次收到微信请求,都要验证签名,防止伪造请求。上面的代码已经包含了 GET 验证,POST 请求同样要做。安装过程中踩坑的用户可以参考 @IndieDevHailey 整理的排查笔记,里面列出了中文社区常见的安装报错和解决方法。

  2. 不要在日志里打印用户消息内容:用户隐私,做好脱敏。

  3. API Key 放环境变量:不要写死在代码里,不要提交到 Git。

  4. 输入内容做基础过滤:防止用户通过消息内容做 prompt injection 攻击。

更详细的安全配置可以参考:OpenClaw 安全问题解决方案


九、常见问题

Q:公众号验证一直失败怎么办?

先确认服务器确实在跑,curl https://your-domain.com/wechat/webhook?signature=test&timestamp=123&nonce=456&echostr=hello 看看有没有响应。其次检查 Nginx 日志确认请求有没有到达 Node.js 服务。

Q:用户发消息没有收到回复?

查 Node.js 的控制台日志,看看消息有没有收到,OpenClaw API 有没有返回。最常见的原因是超时,调低 max_tokens 或换更快的模型。

Q:企业微信机器人能主动发消息吗?

可以,往那个 webhook URL 发 POST 请求即可,不需要用户先发消息触发。定时推送、告警通知都可以这么做。

Q:一个 OpenClaw 实例能同时服务多个微信账号吗?

可以。OpenClaw 的 API 是无状态的,多个 webhook 服务器指向同一个 OpenClaw 实例完全没问题,注意控制并发就好。


小结

OpenClaw 接入微信的核心链路并不复杂:webhook 接收消息,OpenClaw 处理,XML 或 JSON 格式返回。公众号适合面向 C 端用户,企业微信适合内部工具和团队协作。

部署方面,阿里云 ECS 加 Docker 是最稳的方案,域名和 HTTPS 是必须项。限流和错误处理做好,基本上就能稳定跑起来了。