Node.js SDK 是功能最丰富的实现。69 个测试,零运行时依赖。需要 Node.js ≥ 22。
安装
npm install @wechatbot/wechatbot
快速开始
import { WeChatBot } from '@wechatbot/wechatbot' const bot = new WeChatBot() await bot.login() bot.onMessage(async (msg) => { await bot.sendTyping(msg.userId) await bot.reply(msg, `Echo: ${msg.text}`) }) await bot.start()
配置
const bot = new WeChatBot({ storage: 'file', // 'file' | 'memory' | 自定义 Storage storageDir: '~/.wechatbot', logLevel: 'info', // 'debug' | 'info' | 'warn' | 'error' | 'silent' loginCallbacks: { onQrUrl: (url) => renderQrCode(url), onScanned: () => console.log('已扫码!'), onExpired: () => console.log('已过期...'), }, })
发送消息 — reply() 和 send()
两个方法处理所有发送需求。reply() 回复收到的消息(自动 context_token、自动取消输入状态);send() 按用户 ID 发送。
两者接受相同的 SendContent 类型:
// 文本(字符串简写) await bot.reply(msg, '你好!') // 文本(对象) await bot.reply(msg, { text: '你好!' }) // 图片 + 可选标题 await bot.reply(msg, { image: pngBuffer, caption: '截图' }) // 视频 + 可选标题 await bot.reply(msg, { video: mp4Buffer, caption: '看看这个' }) // 文件 — 按扩展名自动路由: // .png/.jpg/.gif/.webp → 作为图片发送 // .mp4/.mov/.webm → 作为视频发送 // 其他 → 作为文件附件发送 await bot.reply(msg, { file: data, fileName: 'report.pdf' }) await bot.reply(msg, { file: data, fileName: 'photo.png' }) // → 图片! // 从 URL 发送 — 自动下载 + 自动检测类型 await bot.reply(msg, { url: 'https://example.com/photo.jpg' }) await bot.reply(msg, { url: 'https://picsum.photos/400/300', caption: '随机图片!' }) // send() 用法相同,只是用 userId 代替 message await bot.send(userId, '你好!') await bot.send(userId, { image: buffer, caption: '嗨!' })
下载媒体
一个方法下载消息中的任何媒体类型:
bot.onMessage(async (msg) => { const media = await bot.download(msg) if (!media) return // 消息中没有媒体 console.log(media.type) // 'image' | 'file' | 'video' | 'voice' console.log(media.data) // Buffer console.log(media.fileName) // 'report.pdf'(文件) console.log(media.format) // 'wav' | 'silk'(语音) // 保存到磁盘 await writeFile(`/tmp/${media.fileName ?? 'download'}`, media.data) // 回传 if (media.type === 'image') { await bot.reply(msg, { image: media.data, caption: '收到你的图片!' }) } })
优先级:图片 > 文件 > 视频 > 语音。语音自动从 SILK 转码为 WAV(需安装 silk-wasm)。
中间件
Express/Koa 风格的可组合中间件管道,在消息处理器之前运行。
import { WeChatBot, loggingMiddleware, rateLimitMiddleware, typeFilterMiddleware, filterMiddleware, } from '@wechatbot/wechatbot' const bot = new WeChatBot() bot.use(loggingMiddleware(bot.logger)) // 记录每条消息 bot.use(rateLimitMiddleware({ maxMessages: 10, windowMs: 60_000 })) bot.use(typeFilterMiddleware('text', 'image')) // 仅处理文本和图片 bot.use(filterMiddleware(/^\/\w+/)) // 仅处理命令 // 自定义中间件 bot.use(async (ctx, next) => { const start = Date.now() await next() console.log(`处理耗时 ${Date.now() - start}ms`) })
可插拔存储
const bot1 = new WeChatBot({ storage: 'file' }) // 文件存储(默认) const bot2 = new WeChatBot({ storage: 'memory' }) // 内存存储 const bot3 = new WeChatBot({ storage: new RedisStorage() }) // 自定义
事件
bot.on('login', (creds) => console.log(`已登录: ${creds.accountId}`)) bot.on('session:expired', () => console.log('会话过期')) bot.on('session:restored', (creds) => console.log('已恢复')) bot.on('error', (err) => console.error(err))
进阶:MessageBuilder
对于复杂的多项消息,直接使用构建器:
const payload = bot.createMessage(userId) .text("这是你的报告:") .file({ media: cdnRef, fileName: 'report.pdf', size: 542188 }) .build() await bot.sendRaw(payload)
其他进阶方法:bot.upload(opts) 仅上传到 CDN 不发送,bot.downloadRaw(media, aeskey?) 直接访问 CDN 引用。
API 参考
核心方法
| 方法 | 描述 | |
|---|---|---|
| new WeChatBot(opts?) | 创建实例 | |
| bot.login(opts?) | 二维码登录(已有凭证则跳过) | |
| bot.start() | 启动长轮询 | |
| bot.run(opts?) | login() + start() 合一 | |
| bot.stop() | 优雅停止 | |
| bot.onMessage(handler) | 注册消息处理器 | |
| bot.reply(msg, content) | 回复 — 文本、图片、视频、文件或 URL | |
| bot.send(userId, content) | 发送给用户 — 相同内容类型 | |
| bot.download(msg) | 下载消息中的任何媒体 | |
| bot.sendTyping(userId) | 显示"正在输入" | |
| bot.stopTyping(userId) | 取消输入指示 | |
| bot.use(middleware) | 添加中间件 | |
| bot.sendRaw(payload) | 发送 MessageBuilder 预构建消息 | |
| bot.upload(opts) | 仅上传到 CDN | |
| bot.downloadRaw(media) | 从原始 CDN 引用下载 | |
| bot.createMessage(userId) | 创建 MessageBuilder |