接上篇(Kimi好用又便宜,不如用它做一个微信聊天机器人)我们实现了一个可以简单对话的微信机器人,但是由于微信的Web协议
被过度开发,导致使用Web协议
的微信机器人很容易被限制登录;
而为了解决这个问题,PC协议
应运而生,说的是协议,实际上是通过注入代码的方式去拦截微信客户端的一些操作,具体技术细节这里不多讲,咱们直接开始;
1. 安装 wechaty-puppet-xp
wechaty-puppet-xp
是一个基于PC协议
的微信机器人,我们可以通过它来实现一个稳定的微信机器人;
我们可以在github
上找到它的源码:wechaty-puppet-xp
也可以在官网上找到它的文档:wechaty-puppet-xp
但是文档并不是很全,不过没关系,wechaty
是通过不同的puppet
来实现不同的功能,只需要在初始化的时候指定puppet
,然后调用wechaty
的API
就可以了;
首先我们需要安装wechaty-puppet-xp
:
npm i wechaty-puppet-xp@next
然后初始化wechaty
:
/**
* Wechaty - Conversational RPA SDK for Chatbot Makers.
* - https://github.com/wechaty/wechaty
*/
import { WechatyBuilder, ScanStatus } from 'wechaty'
import qrTerm from 'qrcode-terminal'
+ import { PuppetXp } from 'wechaty-puppet-xp'
function onScan (qrcode, status) {
if (status === ScanStatus.Waiting || status === ScanStatus.Timeout) {
qrTerm.generate(qrcode, { small: true }) // show qrcode on console
const qrcodeImageUrl = [
'https://wechaty.js.org/qrcode/',
encodeURIComponent(qrcode),
].join('')
console.info('StarterBot', 'onScan: %s(%s) - %s', ScanStatus[status], status, qrcodeImageUrl)
} else {
console.info('StarterBot', 'onScan: %s(%s)', ScanStatus[status], status)
}
}
function onLogin (user) {
console.info('StarterBot', '%s login', user)
}
function onLogout (user) {
console.info('StarterBot', '%s logout', user)
}
async function onMessage (msg) {
console.info('StarterBot', msg.toString())
if (msg.text() === 'ding') {
await msg.say('dong')
}
}
+ const puppet = new PuppetXp()
+ const bot = WechatyBuilder.build({
+ puppet: puppet,
+ })
- const bot = WechatyBuilder.build({
- name: 'wechaty-puppet-wechat',
- /**
- * How to set Wechaty Puppet Provider:
- *
- * 1. Specify a `puppet` option when instantiating Wechaty. (like `{ puppet: 'wechaty-puppet-padlocal' }`, see below)
- * 1. Set the `WECHATY_PUPPET` environment variable to the puppet NPM module name. (like `wechaty-puppet-padlocal`)
- *
- * You can use the following providers:
- * - wechaty-puppet-wechat (no token required)
- * - wechaty-puppet-padlocal (token required)
- * - wechaty-puppet-service (token required, see: <https://wechaty.js.org/docs/puppet-services>)
- * - etc. see: <https://github.com/wechaty/wechaty-puppet/wiki/Directory>
- */
- // puppet: 'wechaty-puppet-wechat',
- })
bot.on('scan', onScan)
bot.on('login', onLogin)
bot.on('logout', onLogout)
bot.on('message', onMessage)
bot.start()
.then(() => console.info('StarterBot', 'Starter Bot Started.'))
.catch(e => console.error('StarterBot', e))
基于上篇文章的实例代码进行的修改,上篇文章可以看这里:示例代码
2. 运行
仅仅有代码其实还不足以运行我们的微信机器人,因为这个代码库很老了,所以新版本的微信是用不了的,需要下载指定版本的微信客户端;
客户端在github
上都有链接,这里我也发一下:WeChatSetup-3.9.2.23.exe
安装了之后会提示低版本的微信不让登录,这个时候就需要运行一个python
脚本去修改WeChatSetup.exe
的版本号,脚本代码如下:
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
from pymem import Pymem
ADDRS = [0x2FFEAF8, 0x3020E1C, 0x3021AEC, 0x303C4D8, 0x303FEF4, 0x3040FA4, 0x30416EC]
def fix_version(pm: Pymem):
WeChatWindll_base = 0
for m in list(pm.list_modules()):
path = m.filename
if path.endswith("WeChatWin.dll"):
WeChatWindll_base = m.lpBaseOfDll
break
for offset in ADDRS:
addr = WeChatWindll_base + offset
v = pm.read_uint(addr)
print(v)
if v == 0x63090A13 or v == 0: # 已经修复过了
continue
elif v != 0x63090217: # 不是 3.9.2.23 修复也没用
raise Exception("别修了,版本不对,修了也没啥用。")
pm.write_uint(addr, 0x63090A13)
print("好了,可以扫码登录了")
if __name__ == "__main__":
try:
pm = Pymem("WeChat.exe")
fix_version(pm)
except Exception as e:
print(f"{e},请确认微信程序已经打开!")
使用这个脚本之前需要安装pymem
:
pip install pymem
python 脚本需要在微信客户端打开的情况下运行,Python怎么安装不用我教了吧!!!
这个脚本好像是这个库的作者提供的,我是在微信公众号上查到的,具体的链接我现在也查不到了,在此感谢作者!
3. 差异
wechaty-puppet-xp
和 wechaty-puppet-wechat
有很多差异,具体来说基于Web协议
的微信机器人功能更加丰富,且稳定性比较好;
而基于PC协议
的微信机器人功能相对较少,且稳定性不如Web协议
的微信机器人,但是性能更好(相对的,因为还要运行一个微信客户端);
下面是XP
协议的功能列表:
具体也可参考代码库:wechaty-puppet-xp
对比Web协议
的功能来说其实是少了很多,但是功能基本上都齐全了,所以如果你的需求不是很高的话,可以使用PC协议
的微信机器人;
4. 优势与劣势
PC协议
的微信机器人主要的优势在于有固定的ID
,用户ID
和群组ID
,这是对比Web协议
的天然优势;
同时性能相对于Web协议
的微信机器人更好,具体原因是因为PC协议
的微信机器人内部操作比Web协议
的微信机器人更加简单,毕竟功能少;
这里我列举一些缺陷点,这些缺陷点在Web协议
的微信机器人中是不存在的,供大家参考:
- 有时候消息会发送失败
- 无法获取群组成员,只有在第一次登录的时候才能获取到,如果下次想要获取就需要重新登录
- 无法获取群成员的备注名
- 无法准确获取好友的昵称,在有备注的情况下会获取备注名(不是群聊的备注名)
- 无法准确获取好友列表和群聊列表
- 无法自动通过好友请求
- 判断是否是好友的接口不准确
- 不是跨平台的,只能在
Windows
上运行
大概就这么多吧,其实我的使用场景是不需要这么多功能的,所以功能对于我来说是够用的,我也没有进行更深度的探索。
注:这是一个开源的项目,如果你觉得功能不满足或者有更好的解决方案,可以自己去实现,这个库现在也不更新了,基于我的探索,这个库的底层使用了frida.re/,感兴趣的可以去了解一下。
现在也有比较新的基于
PC协议
的微信机器人,但是我看功能也并不是很多,感兴趣的可以去了解一下:WeChatFerry
5. 总结
这篇文章主要是讲解了wechaty-puppet-xp
的使用,以及它和wechaty-puppet-wechat
的区别,以及它的优势和劣势;
这个库的功能相对于wechaty-puppet-wechat
来说是少了很多,但是对于一些简单的需求来说是够用的,如果你的需求不是很高的话,可以使用PC协议
的微信机器人;