- 即时通讯
- 后端
- AI 应用
【免费下载链接】wechatferry
-
wechatferry 提供了@wechatferry/plugins插件包,其中wechatyPluginRoomKick让 Wechaty 机器人获得群聊踢人能力:管理员在群里 @ 某人并发送BAN或KICK即可将其移出群聊,机器人还可按blackListMessage匹配器自动踢掉发送敏感内容的成员。读完本文,你将掌握该插件的完整安装、配置与使用方式,并能从源码层面理解"命令识别 → @ 成员解析 → 底层协议踢人"的完整调用链。
插件做什么
尽管微信本身支持踢人操作,但手动操作比较麻烦。room-kick 插件把这个动作自动化为两种模式(见 docs/plugins/room-kick.md):
- 命令式踢人:被配置为管理员(
admin)的用户在启用的群聊中 @ 一个或多个成员,并发送BAN(或KICK),机器人会先发一条警告消息,再把目标移出群聊; - 关键字匹配踢人:普通成员发送命中
blackListMessage匹配器的消息时,机器人自动警告并将其移出群聊。
该插件由 packages/plugins 包导出,包名@wechatferry/plugins,与safe-mode、room-mute、room-limit等插件共同发布。
安装与快速上手
安装
参考 docs/plugins/index.md,安装插件包的方式为:
# pnpm pnpm add -D @wechatferry/plugins # yarn yarn add -D @wechatferry/plugins # npm npm install -D @wechatferry/plugins基本用法
官方文档给出的最小示例如下(注意room与admin是必填项,blackListMessage可选):
import { WechatyBuilder } from 'wechaty' import { wechatyPluginRoomKick } from '@wechatferry/plugins' const bot = WechatyBuilder.build() bot .use(wechatyPluginRoomKick({ admin: [], room: [], // blackListMessage: [/fuck/i] })) bot.start()使用效果如下(摘自文档):
RoomName Admin: BAN @User Bot: @User 你违反了群规,管理员现将你移出群聊 System: 你将"User"移出了群聊除了BAN踢人外,设置的管理员还可以使用KICK来踢人。
选项说明
wechatyPluginRoomKick的配置类型为RoomKickOptions,定义在 room-kick.ts,完整字段如下:
| 选项 | 类型 | 必填 | 说明 |
|---|---|---|---|
room | matchers.RoomMatcherOptions | 是 | 启用踢人的群聊范围,支持字符串、正则或群名称列表等wechaty-plugin-contrib提供的匹配器写法;未命中的群完全不受插件影响 |
admin | matchers.ContactMatcherOptions | 是 | 管理员列表,只有管理员的BAN/KICK命令会被执行;管理员之间不能互踢 |
blackListMessage | matchers.MessageMatcherOptions | 否 | 黑名单消息匹配器(如正则/fuck/i),非管理员成员命中该匹配器的消息将触发自动踢人;不传则不启用关键字踢人 |
三个字段最终都会被wechaty-plugin-contrib的matchers.roomMatcher/contactMatcher/messageMatcher编译成谓词函数,因此既支持单个名称,也支持数组、正则等匹配器惯用写法。
两种踢人路径的判定逻辑
插件在 room-kick.ts 中通过defineWechatyPlugin定义(该工具函数见 utils.ts,作用仅是给工厂函数标注配置类型T),并注册bot.on('message')监听,判定流程为:
- 过滤自身消息:
message.self()为真直接返回,机器人自己的发言不会触发任何逻辑; - 过滤非群聊:
message.room()为空(单聊)直接返回; - 群范围过滤:
isManagedRoom(room)不命中配置的room匹配器则返回; - 管理员分支:
isAdmin(talker)命中时,要求消息是文本类型(types.Message.Text),且mentionList非空,再取mentionText()(即去掉 @ 之后的文本)与KICK/BAN做精确相等比较。满足后先调用talkAdminKickWarn发送你违反了群规,管理员现将你移出群聊 ✈️,bot.sleep(1000)等待 1 秒后,遍历mentionList逐个执行room.remove(member),其中对每个成员再做一次isAdmin检查——踢人列表里混入管理员会被静默跳过; - 关键字分支(
else if):非管理员的消息若命中isBlackListMessage,则发送你发表了不当言论,现将你移出群聊✈️ \n欢迎再次进来。,等待 1 秒后room.remove(talker)。
两条路径的提示语均由talkers.roomTalker生成(来自wechaty-plugin-contrib),会自动带上被 @ 成员的提及。
底层原理:从 mention 解析到 wcf 协议踢人
"谁被 @ 了"是怎么识别的
message.mentionList()的数据来自 wechatferry 的 puppet 实现。群聊文本消息的 XML 里带有<msgsource>的atuserlist字段,puppet 侧的 room-parser.ts 会把message.xml解析为 JSON,将逗号分隔的atuserlist切分成 wxid 数组并写入消息 payload 的mentionIdList,Wechaty 层的mentionList()便由此而来。
发送方向上也有对应的 mention 处理:puppet.ts 中的messageSendText支持@[mention:wxid]语法,由 mentionTextParser 解析出被 @ 的 wxid 列表并替换为显示名后发送。因此插件里roomTalker发出的警告消息确实会 @ 到被踢者本人。
踢人如何落到微信协议
room.remove(member)在 wechatferry puppet 中对应roomDel()(puppet.ts):
override async roomDel( roomId: string, contactId: string, ): Promise<void> { log.verbose('WechatferryPuppet', 'roomDel(%s, %s)', roomId, contactId) this.agent.removeChatRoomMembers(roomId, contactId) }agent 层的removeChatRoomMembers(agent.ts)把单个 wxid 归一化为数组后调用this.wcf.delRoomMembers;core 层的 client.ts 最终构造 protobuf 请求,函数号为wcf.Functions.FUNC_DEL_ROOM_MEMBERS,把wxids以逗号拼接(并去掉空格)发给 wcf 服务:
delRoomMembers(roomId: string, wxidList: string[]) { const req = new wcf.Request({ func: wcf.Functions.FUNC_DEL_ROOM_MEMBERS, m: new wcf.MemberMgmt({ roomid: roomId, wxids: wxidList.join(',').replaceAll(' ', ''), }), }) const { status } = this.send(req) return status }也就是说,room-kick 插件的room.remove()调用链是:Room.remove → WechatferryPuppet.roomDel → WechatferryAgent.removeChatRoomMembers → WcfClient.delRoomMembers → FUNC_DEL_ROOM_MEMBERS协议请求。
使用注意与限制
- 命令是精确匹配:源码中判断为
text === 'KICK' || text === 'BAN'(room-kick.ts),mentionText()返回的是去掉 @ 之后的文本,因此必须形如BAN @User;写成ban @user或BAN@User之外的变体不会生效; - 必须带 @:管理员分支要求
mentionList.length > 0,不带 @ 的BAN会被忽略,无法"踢最近发言者"; - 管理员不可被踢:命令分支内对每个被 @ 成员再次做
isAdmin判断,blackListMessage分支只作用于非管理员(else if结构),因此管理员发言命中黑名单也不会被自动踢出——从源码结构看,这是有意避免机器人误伤管理者的设计; - 警告与踢人之间有 1 秒延迟:
bot.sleep(1000)保证警告消息先于"移出群聊"的系统提示出现,群成员能看到因果; - 仅监听 message 事件:插件不处理图片、文件等消息类型的黑名单匹配(
matchers.messageMatcher对文本以外的消息按匹配器自身语义判定),BAN/KICK命令则只接受纯文本; - 群成员数量较多时注意执行节奏:
BAN多人时是串行 for 循环逐个room.remove,没有额外节流。
相关能力
同一个插件包内还有语义相近的wechatyPluginRoomMute(禁言/解封,见 room-mute.ts),它复用了相同的"管理员 @ + 命令"模式(MUTE/UNMUTE命令、unstorage 持久化封禁时长、禁言期内再发言自动移出群聊),可作为 room-kick 的进阶或组合方案:先禁言警告、违规再实踢。
小结
wechatyPluginRoomKick用不到 60 行代码实现了"命令式 + 关键字"双模式群管:room/admin/blackListMessage三个匹配器决定作用范围,BAN/KICK命令与黑名单匹配分别覆盖人工管理与自动执法两类场景,底层则复用 wechatferry puppet 的roomDel → wcf FUNC_DEL_ROOM_MEMBERS协议链路完成真正的移出群聊动作。所有实现均可在 packages/plugins/src/room-kick/room-kick.ts 中直接核对。
- 即时通讯
- 后端
- AI 应用
【免费下载链接】wechatferry
-
相关推荐
如何一键部署WeChatFerry微信机器人:GitHub Actions自动化构建完整指南
如何一键部署WeChatFerry微信机器人:GitHub Actions自动化构建完整指南 WeChatFerry是一款功能强大的微信逆向工具,通过GitHu
WeChatFerry微信机器人:5个技巧实现智能自动化交互
WeChatFerry微信机器人:5个技巧实现智能自动化交互 在数字化办公时代,微信已成为工作和生活中不可或缺的通讯工具。WeChatFerry作为一款功能强大
WeChatFerry:微信机器人自动化框架深度解析
WeChatFerry:微信机器人自动化框架深度解析 WeChatFerry是一个专业的微信机器人自动化框架,解决了微信官方API缺失带来的技术挑战。本文深度解
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考