wechatbot
English

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
Node.js SDK — @wechatbot/wechatbot