ByteNoteByteNote

字节笔记本

2026年8月29日

用开源 REST API 发 WhatsApp 消息

API中转
¥120

官方 WhatsApp Business API 要审账号、买会话、模板消息还得过审。只想给内部工具推一条状态,这套流程就显得重。Felipe Douglas 开源的 felipeDS91/whatsapp-api 走另一条路:用 whatsapp-web.js 挂上网页版会话,外面再包一层 JWT 鉴权的 REST,记录先入 MySQL 队列,再由独立进程处理。

仓库是 MIT 许可,作者写明只适合学习。它不是官方接口。群发、营销、冷启动客户都可能让号被限制,垃圾信息本身也违法。面向真实用户的生产通道,还是走 WhatsApp Cloud API

它怎么拆成两块

服务拆成两个常驻程序。

环境变量管节奏。

轮询间隔、两条之间的随机停顿、国家区号前缀、登录超时,都在.env 文件里。默认区号是巴西。国内号码要改成 86,否则会话键对不上。

本地先跑起来

bash
git clone https://github.com/felipeDS91/whatsapp-api.git
cd whatsapp-api
yarn
cp .env.example .env
yarn typeorm migration:run
yarn dev:server

依赖是 Node 14 以上、Yarn、一台 MySQL。仓库 README 用 Docker 起 5.7。装完依赖后建业务用户,不要直接拿 root 对外。

把环境示例拷成正式文件。至少改 JWT 签名、库地址和账号密码。监听端口看 PORT 或 APP_PORT。跑完迁移后再启动两个进程。

种子数据里有默认管理员账号,用户名是 admin,密码写在 README。本地能登录之后马上改掉。根目录还有 Insomnia 集合,导入就能点接口。

先登录再绑号

除了登录接口,其余路由都要带 JWT。用户名和密码贴到 /sessions,返回 token 和过期时间。后续请求放 Authorization Bearer。

管理员接口 /tokens 用来登记号码。请求体只收本地号,服务端会拼上国家区号。响应是一张 PNG,终端里也会打一份。用手机 App 对齐即可,流程跟网页版一样。

会话文件落在本机,下次重启一般不用重来。解绑走 DELETE /tokens/:phone。GET /tokens 能看已登记的号。/users 用来加普通调用方。

队列接口

源码路由是 /messages,README 写成了单数。POST 只负责入队,真正处理是另一个进程的事。JSON 字段有 from、to、message,可选 image 和 schedule_date。

from 必须是 10 或 11 位本地号,对应已登记的会话。to 是 10 到 22 位。message 不能为空。image 要能通过 Base64 校验。schedule_date 是 ISO 时间,不能早于当前。JSON 上限 15MB。

GET /messages 可按 status 翻页。还在等待中的记录可以 DELETE 掉;已处理过的删不了。入队成功只代表写进了表,不要当成对方已读。工作进程默认五秒扫一次,再加上随机停顿。

请求体大致是这个形状:

json
{
  "from": "13800138000",
  "to": "13900139000",
  "message": "build 1842 passed"
}

号码格式要先对齐国家区号。from 按本地号校验,区号是服务端拼的。写成带国家码的长号,会报 Invalid number from。

别拿它当生产通道

底层是浏览器里的网页版会话。页面改版、会话掉线、短时间频繁调用,都可能让登记失效或号被限制。仓库本身也说了:学习用,别拿去群发。

面向真实用户的通知,用官方 Cloud API:要模板、要商户号,但账号在 Meta 规则里,出问题至少有文档。这个项目适合搞清楚网页会话、队列和 JWT 怎么拆,或者给自己的构建状态推一条。对外客服、验证码、订单通知,别走这条。

默认管理员口令、空的 APP_SECRET、把浏览器会话目录暴露到公网,这三件事比接口好不好用更危险。先把这几个收住,再考虑要不要让别的服务来调它。

分享: