前序
前端筱园也在近期创建了一个微信交流群,为了让群更有氛围感,更好的管理群就想着添加一个机器人,我的要求也不高,主要就以下几个功能:
- 有新人进群,自动@新人发送欢迎语
- 触发一些关键词时自动回复
- 每日统计群数据:进群离群人数、活跃人数、消息数量等
- 回答一些简单的问题,完成一些简单的对话
于是就在网上去搜寻了一波,发现有个专门提供微信机器人的平台,看起来挺符合我的需求,虽然要付费,但是还是购买了一个试试。
欢迎加入前端筱园交流群:https://www.dengzhanyong.com/article/2bb73319-ccd4-4b90-b0e4-bedd595e9ec6
开始还挺满意的,想要的那些功能都有,但是这个智能对话功能属实有点鸡肋,放几张图大家就能感受到了。
果然是:已读,乱回。
然后就萌生了自己去开发一个微信机器人替换掉他的想法,说干就干,第二天就找到了一个用于开发微信机器人的开源项目Wechaty,上手非常简单,现在想想自己当时还花钱去买,真的是大怨种。
Wechaty
Wechaty是一个开源的微信机器人SDK,它允许开发者通过编程创建自动化的微信聊天机器人。
Wechaty的工作原理基于微信的网页版接口,它通过模拟人类用户的行为来实现自动回复消息、管理好友和群聊等功能。由于微信官方并没有提供官方的机器人API,Wechaty的出现为广大开发者提供了一种可能性,使他们能够根据自己的需求开发微信机器人。
仅需要6行代码,你就可以创建一个机器人:
const { WechatyBuilder }= require('wechaty');
const wechaty = WechatyBuilder.build() // get a Wechaty instance
wechaty
.on('scan', (qrcode, status) => console.log(`Scan QR Code to login: ${status}\nhttps://wechaty.js.org/qrcode/${encodeURIComponent(qrcode)}`))
.on('login', user => console.log(`User ${user} logged in`))
.on('message', message => console.log(`Message: ${message}`))
wechaty.start()
- scan: 启动后展示登录二维码
- login:扫码登录后触发的事件
- message: 接收到消息时触发
除了以上3个最基础的事件之前,还提供了更多的事件监听:
要实现丰富灵活的功能,Wechaty 有几个重要的对象来完成一系列的操作:
- Contact(联系人):获取联系人的基本信息、发送消息给联系人、检查是否是好友等
- Message(消息):获取消息类型、获取消息信息、回复消息等
- Room(群聊):创建群聊、发送群消息、获取群信息、查询群成员、监控入群离群等
- Friendship(好友关系):添加联系人、删除联系人、好友验证、管理好友等
npm地址:https://www.npmjs.com/package/wechaty
下面就来开发几个简单的应用场景。
自动加群
场景:向机器人发送群聊名称,自动加入群聊
const { WechatyBuilder } = require("wechaty");
const bot = WechatyBuilder.build({
name: "我的机器人", // 名字随意
});
bot.on("scan", onScan);
为了更方便扫码,使用 qrcodeTerminal 把二维码输出到控制台中。
const qrcodeTerminal = require("qrcode-terminal");
const { ScanStatus, log } = require("wechaty");
function onScan(qrcode, status) {
if (status === ScanStatus.Waiting || status === ScanStatus.Timeout) {
const qrcodeImageUrl = [
"https://wechaty.js.org/qrcode/",
encodeURIComponent(qrcode),
].join("");
log.info(
"StarterBot",
"onScan: %s(%s) - %s",
ScanStatus[status],
status,
qrcodeImageUrl
);
// 在控制台中显示二维码
qrcodeTerminal.generate(qrcode, { small: true });
} else {
log.info("StarterBot", "onScan: %s(%s)", ScanStatus[status], status);
}
}
绑定 message 事件监听,对接收到的消息进行处理
async function dispatchFriendFilterByMsgType(that, msg) {
try {
const type = msg.type(); // 消息类型
const talker = msg.talker();
// 是否是公众号消息
const isOfficial = talker.type() === that.Contact.Type.Official;
switch (type) {
case that.Message.Type.Text:
const content = msg.text();
log.info(
`发消息人${await talker.name()}:发了一个文本:${content}`
);
// 不是公众号消息
if (!isOfficial) {
reply = await getContactTextReply(that, talker, content);
if (reply) {
talker.say(reply);
}
}
break;
case that.Message.Type.Emoticon:
log.info(`发消息人${await talker.name()}:发了一个表情`);
break;
case that.Message.Type.Image:
log.info(`发消息人${await talker.name()}:发了一个图片`);
break;
case that.Message.Type.Url:
log.info(`发消息人${await talker.name()}:发了一个链接`);
break;
case that.Message.Type.Video:
log.info(`发消息人${await talker.name()}:发了一个视频`);
break;
case that.Message.Type.Audio:
log.info(`发消息人${await talker.name()}:发了一个音频`);
break;
case that.Message.Type.Recalled:
log.info(`抓到 ${await talker.name()} 撤回了一条消息`);
break;
default:
break;
}
} catch (error) {
log.error(error);
}
}
处理文本消息,确认发送的群名是否存在,如果存在则需要判断此人是否已在群聊中,不在的话就拉入群聊。
async function getContactTextReply(that, talker, msg) {
const room = await findRoom(that, msg);
if (!room) return "没有该群聊";
const inRoom = await room.member({ name: talker.name() });
await room.add(talker);
return inRoom ? "你已在群聊中" : "我即将拉你入群";
}
有人进群后自动发送欢迎语
bot.on("room-join", onRoomJoin);
async function onRoomJoin(room, inviteeList, inviter) {
const nameList = inviteeList.map((member) => member.name()).join(", ");
room.say(`欢迎${nameList}加入了群聊!`);
}
消息群发
场景:作为一个运营管理人员,需要经常把推送消息发送到各个群聊中,但微信本身的转发每次只能转发给一个联系人或群聊。
机器人需求:指定的管理员向机器人发送的消息,自动转发到指定的要转发的群中。
const talker = msg.talker();
// 管理员ID列表
const adminIds = ["管理员1", "管理员2"];
if (adminIds.includes(talker.id)) {
// 需要转发的群
const sendRooms = ["交流群1", "交流群2"];
// 获取所有的群列表
const rooms = await that.Room.findAll();
rooms.forEach(async (room) => {
// 获取群名称
const roomTopic = await room.topic();
// 转发消息到群中
sendRooms.includes(roomTopic) && (await room.say(msg));
});
}
群聊名称有可能被修改,为了确保不会漏发,最好使用群聊ID来做判断。
你能想到的很多场景都可以轻松实现,比如说:
- 接入第三方AI开放接口实现智能对话
- 开发成小助手机器人,每日定时提醒待办事项
- 群内消息出现广告或敏感词汇时自动提醒,群聊数据统计
写在最后
欢迎访问我的个人网站:www.dengzhanyong.com
欢迎加入前端筱园交流群:https://www.dengzhanyong.com/article/2bb73319-ccd4-4b90-b0e4-bedd595e9ec6
关注我的公众号【前端筱园】,不错过每一篇推送
