把微信公众号接到无界(Bncr),如何部署无界(Bncr)请看本教程 无界部署教程 ,用户在公众号里发消息后,根据系统设定自动回复。
- 适配器文件:
wxMP.js,见最底部。 - 部署位置:
BncrData/Adapter/wxMP.js(Adapter 根目录,二级目录不会被加载) - 回调地址:
http(s)://你的域名/api/bot/wxMP - 版本:2.0.0(针对官方 1.0.3 的四处实质缺陷做了修复,见文末对比表)
一、先说最关心的问题:凭据获取入口搬迁
AppSecret / EncodingAESKey / Token ,3个必要的凭证。
微信把这块入口迁移到了「微信开发者平台」。
官方文档现在的原文是:
可在「微信开发者平台 - 我的业务 - 公众号 - 消息与事件推送」处进行配置。
即,填写服务器地址(URL)、Token 和 EncodingAESKey……
而旧路径「设置与开发 → 开发接口管理」自 2025-12-01 起开始迁移到微信开发者平台。
(部分账号在旧后台仍能看到残留下的入口,但新账号/已迁移账号就只剩跳转提示了。)
三样东西分别在哪拿
| 凭据 | 位置 | 备注 |
|---|---|---|
| AppID | 微信开发者平台 → 我的业务与服务 → 公众号 → 接口管理 / 开发配置 | 直接可见 |
| AppSecret | 同上 | ⚠️ 只在生成/重置时显示一次,需管理员手机验证码。忘了就只能「重置」,重置后旧值立刻失效 |
| Token | 微信开发者平台 → 我的业务 → 公众号 → 消息与事件推送 | 由你自己填写(3–32 字符),不是微信发你的。所以是「你先定一个,再填进适配器」 |
| EncodingAESKey | 同上 | 点「随机生成」,43 位。选「安全模式」必填 |
| 消息加解密方式 | 同上 | 明文 / 兼容 / 安全,三选一 |
一句话:Token 是你自己定的;EncodingAESKey 是随机生成的;AppSecret 只在重置时露一次脸。
这三样都不在「基本配置」那个老页面里了。
二、开工前的三个硬前提
账号类型
- 未认证订阅号:可以接入,但只能被动回复——用户发一句、你回一句,必须在 5 秒内应答;没有客服消息接口。
- 认证订阅号 / 服务号:多一个有「客服消息」权限(48 小时内可主动推送),本适配器已支持(
Bridge.sendCustomText/push)。 - 注意:公众号一旦启用服务器配置,后台自带的自动回复和自定义菜单会失效,后续都由代码接管。
一个公网可达的地址
- 微信要求回调 URL 是
http://(80 端口)或https://(443 端口),不支持自定义端口。 无界默认监听
9090,所以必须做一层反向代理或端口映射:- 有域名(推荐):Nginx/Caddy 把
https://your.domain/api/bot/wxMP反代到http://127.0.0.1:9090/api/bot/wxMP - 没域名:用
http://你的公网IP/api/bot/wxMP(微信允许 IP,但不推荐)
- 有域名(推荐):Nginx/Caddy 把
- 域名建议上 HTTPS,否则部分场景会被拦。
- 微信要求回调 URL 是
无界能被打通
- 回调地址必须能从公网访问到无界;无界响应地址校验要在 1 秒内(GET 校验是纯计算,本适配器是秒回)。
- 用到 access_token 的功能(图片/语音回复、客服消息)才需要把无界的出口公网 IP 加进公众号的 IP 白名单。纯文本被动回复不需要白名单。
三、部署步骤
1. 放文件
BncrData/
└── Adapter/
└── wxMP.js ← 本项目 adapters/wxMP.js 直接复制过来如果你的Adapter/里已经有官方那份wxMP.js,直接覆盖。两者@name都是wxMP,
同时存在会因同名适配器冲突而出问题。
2. 重启无界
适配器没有热重载,改完必须完整重启 Bncr 进程(不是热加载插件):
docker restart bncr3. 依赖
不需要手动 npm i。 本适配器只依赖 Node 内置的 crypto、fs;axios 是可选依赖,适配器启动时会通过 sysMethod.testModule(['axios'], {install:true}) 自动装。
装不上也不影响纯文本被动回复(只是图片/语音回复和客服消息推送不可用)。
对比:官方那份必须手动 npm i got form-data express-xml-bodyparser。4. 填配置
进入无界 Web 后台 → 配置 → 适配器 → wxMP,逐项填:
| 配置项 | 填什么 |
|---|---|
| 是否开启适配器 | 开 |
| AppID | 公众号 AppID |
| AppSecret | 公众号 AppSecret(可留空,仅影响图片/语音回复与客服消息) |
| Token | 你自己定的那个字符串,必须与微信后台完全一致(区分大小写) |
| EncodingAESKey (43位) | 微信后台生成的 43 位密钥;只用明文模式可留空 |
| 等待插件回复秒数 | 默认 4(微信限 5 秒,别填满) |
| 合并多条回复 | 默认开:返利助手回多条时合并成一条发出 |
| 拉取消息指令 | 默认「拉取消息」 |
| 关注欢迎语 | 用户关注时自动回的内容 |
| 非文本消息提示 | 用户发图片/语音时的提示语 |
| 单条回复最大字节数 | 默认 1800,超出部分转入拉取队列 |
| 本机地址 | 默认 http://127.0.0.1:9090,用于把 /public/xxx.jpg 拼成完整 URL |
5. 开服务器配置(顺序很重要)
先在无界里把配置填好并重启,再去微信后台点保存,否则微信发来的校验请求没人应答。
微信开发者平台 → 我的业务 → 公众号 → 消息与事件推送:
- URL:
https://your.domain/api/bot/wxMP - Token:与你填进适配器的一致
- EncodingAESKey:点随机生成,复制到适配器配置里
消息加解密方式:
- 建议第一次先选「明文模式」 —— 只用 Token 校验,链路最短,最容易跑通
- 跑通后再改「安全模式」并在适配器里填 EncodingAESKey(本适配器支持真实的 AES 收发)
点保存 → 微信会往 URL 发 GET 校验
- 成功:后台显示配置成功,无界控制台出现
[wxMP] URL 校验通过 - 失败:控制台会打印
[wxMP] URL 校验失败:Token 与微信后台不一致?
- 成功:后台显示配置成功,无界控制台出现
6. 设管理员(可选)
在已授权的平台对机器人发:
set wxMP admin 你的openidopenid 从无界控制台日志里拿:用户给公众号发消息时会打印[wxMP] 收到公众号消息 <oXXXX...>:...
四、宝塔面板反代实操(把 9090 暴露成 443)
微信只认 80(http) 或 443(https),且 URL 里不能带端口号。无界跑在 9090,所以必须做反代。
下面以「宝塔 Linux 面板 + Nginx」为例,全程约 5 分钟。
第 0 步:先确认无界本机可达(关键,别跳过)
curl -s http://127.0.0.1:9090/api/bot/wxMP应该看到这句:这是 Bncr wxMP 适配器接口(微信公众号)。GET 用于微信服务器校验,POST 用于接收消息。
- 看到了 → 继续下一步。
看不到 / Connection refused → 先解决无界本身:
- 确认容器起了:
docker ps | grep bncr - 确认端口映射了:启动命令里要有
-p 9090:9090(或--network=host) - 没映射的话重建容器补上,否则反代怎么配都是 502。
- 确认容器起了:
第 1 步:域名解析
到域名商处加一条 A 记录,例如 wx.你的域名.com → 服务器公网 IP。
没有域名也能做:直接用http://公网IP/api/bot/wxMP(80 端口)。
但下面第 2 步「添加站点」时把域名填成公网 IP 即可,其余步骤一样。
第 2 步:宝塔建站(纯静态即可)
网站 → 添加站点:
| 项 | 填什么 |
|---|---|
| 域名 | wx.你的域名.com |
| 根目录 | 默认就行(反代用不到目录内容) |
| FTP / 数据库 / PHP | 全部「不创建」 |
| 网站类型 | 建议选 纯静态 |
这一步的作用只是给宝塔一个挂 nginx 配置的地方并让它能签 SSL 证书,站点里不需要放任何文件。
第 3 步:申请 SSL(强烈建议,但不是必须)
站点 → 设置 → SSL → Let's Encrypt → 勾选域名 → 申请。
- 成功后打开 「强制 HTTPS」。
- ⚠️ Let's Encrypt 走 HTTP-01 验证,需要 80 端口能被公网访问。若 80 被占用或套了 CDN,
改用 DNS 验证。 - 想先用 http 跑通也完全可以(微信同样接受 80 端口 http),跑通后再上 https。二选一,
不要两个都配一半。
第 4 步:加反向代理
方案 A:手写配置(推荐,精确可控)
站点 → 设置 → 配置文件,在 server { ... } 里(#SSL-START 之后任意位置)加入:
# ===== wxMP 微信公众号适配器 =====
location ^~ /api/bot/wxMP {
proxy_pass http://127.0.0.1:9090;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Connection "";
proxy_connect_timeout 5s;
proxy_send_timeout 10s;
proxy_read_timeout 10s;
proxy_buffering off;
}保存(宝塔会自动 reload;没生效就点一下「重载配置」)。
三个必须理解的点,配错了必失败:
location ^~ /api/bot/wxMP结尾不加斜杠。
微信请求的路径就是/api/bot/wxMP(不带尾斜杠)。如果写成location /api/bot/wxMP/,
这条最常见的请求匹配不上,会落到静态站点 → 404。^~表示命中后不再尝试正则 location,避免被别的规则抢走。proxy_pass http://127.0.0.1:9090;结尾也绝对不能加/。- 不加
/:原样透传路径 → 无界收到/api/bot/wxMP✅ - 加了
/:nginx 会把location匹配的那段替换成/,无界收到/→ 404 ❌
- 不加
- 不要加任何
rewrite。 微信的signature / timestamp / nonce / echostr全在 query 上,
保持原样透传最稳。
方案 B:可视化反代(更简单,但有个坑)
站点 → 反向代理 → 添加反向代理:
| 项 | 填什么 |
|---|---|
| 代理名称 | wxMP |
| 代理目录 | /api/bot/wxMP |
| 目标 URL | http://127.0.0.1:9090 |
| 发送域名 | $host |
| 缓存 | 关闭 |
⚠️ 宝塔很可能在「代理目录」后面自动补一个尾斜杠,生成location /api/bot/wxMP/ { ... } —— 于是又踩上面第 1 个坑。
所以保存后一定要点「配置文件」确认一眼:如果生成的是带斜杠的版本,手动改成location ^~ /api/bot/wxMP {(或额外补一条 location = /api/bot/wxMP { proxy_pass http://127.0.0.1:9090; })。
结论:会看 nginx 配置就用方案 A;用方案 B 就务必回头确认尾斜杠。
第 5 步:验证(三层,逐层排查)
# ① 无界本机
curl -s http://127.0.0.1:9090/api/bot/wxMP
# ② 经过 nginx
curl -s https://wx.你的域名.com/api/bot/wxMP
# ③ 看响应头,确认真的到了 nginx(能看到 Content-Type: text/xml 就是适配器回的)
curl -si https://wx.你的域名.com/api/bot/wxMP | head -8最直观的方式是直接用浏览器打开 https://wx.你的域名.com/api/bot/wxMP:
- 看到「这是 Bncr wxMP 适配器接口(微信公众号)…」→ ✅ 反代通了
- 看到宝塔默认页 / 404 / 502 → ❌ 对照下面的表排查
三层都通之后,再回微信后台点保存,然后看无界控制台有没有:[wxMP] URL 校验通过
第 6 步:宝塔/中间层特有的坑
| 现象 | 原因 | 处理 |
|---|---|---|
curl 域名能通,但微信提示校验失败 | 宝塔「Nginx 防火墙」/「堡塔云WAF」把 signature、echostr 这种长十六进制参数当成攻击拦了 | 防火墙里给 /api/bot/wxMP 加 URL 白名单,或先临时关掉防火墙验证 |
| 502 Bad Gateway | 无界没起 / 9090 未监听 / docker 没映射端口 | 回到第 0 步 curl http://127.0.0.1:9090 自查 |
| 404 | 反代 location 没命中(十有八九是尾斜杠)或配置没重载 | 按方案 A 手写;保存后点「重载配置」 |
| 校验偶发失败、时好时坏 | 反代开了缓冲或超时太短,无界来不及在 1 秒内应答 | 加 proxy_buffering off;、proxy_read_timeout 10s; |
| 套了 CDN / 云加速后失败 | 中间层改写 Content-Type、不转发原始 body,或缓存了 GET 校验结果 | 给该子域名关闭缓存与内容改写,或让它直接回源 |
| 浏览器能打开、微信却连不上 | 域名解析了但只有 IPv6 记录,或服务器只放行了 IPv6 | 确认 A 记录(IPv4)存在 |
| 域名必须备案吗 | 用国内服务器 + 80/443 域名访问,通常需要已备案域名,未备案可能被拦 | 用已备案域名,或改用非大陆服务器 |
关于安全
不要为了图省事把 9090 直接暴露到公网(微信也不接受 9090)。9090 是无界面板端口,
暴露出去等于把管理后台交出去。正确的做法就是本文这套:只开 443,让 nginx 转发。
八、接口速查
| 用途 | 方法 |
|---|---|
| 微信服务器校验 | GET /api/bot/wxMP?signature=×tamp=&nonce=&echostr= |
| 接收消息与事件 | POST /api/bot/wxMP(明文或加密 XML) |
| 浏览器自检 | 直接 GET /api/bot/wxMP,会返回接口说明 |
| 插件侧主动发消息 | sysMethod.push({ platform:'wxMP', userId, msg }) |
| 插件侧扩展能力 | sender.Bridge.getAccessToken() / sender.Bridge.sendCustomText(openid, text) / sender.Bridge.status() |
| 撤回消息 | 不支持(公众号无此能力),delMsg 恒返回 false |
评论 (0)