wechaty 基于 PC 协议的免费微信机器人

219 阅读6分钟

上篇(Kimi好用又便宜,不如用它做一个微信聊天机器人)我们实现了一个可以简单对话的微信机器人,但是由于微信的Web协议被过度开发,导致使用Web协议的微信机器人很容易被限制登录;

而为了解决这个问题,PC协议应运而生,说的是协议,实际上是通过注入代码的方式去拦截微信客户端的一些操作,具体技术细节这里不多讲,咱们直接开始;

1. 安装 wechaty-puppet-xp

wechaty-puppet-xp 是一个基于PC协议的微信机器人,我们可以通过它来实现一个稳定的微信机器人;

我们可以在github上找到它的源码:wechaty-puppet-xp

也可以在官网上找到它的文档:wechaty-puppet-xp

但是文档并不是很全,不过没关系,wechaty是通过不同的puppet来实现不同的功能,只需要在初始化的时候指定puppet,然后调用wechatyAPI就可以了;

首先我们需要安装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-xpwechaty-puppet-wechat 有很多差异,具体来说基于Web协议的微信机器人功能更加丰富,且稳定性比较好;

而基于PC协议的微信机器人功能相对较少,且稳定性不如Web协议的微信机器人,但是性能更好(相对的,因为还要运行一个微信客户端);

下面是XP协议的功能列表:

image.png

具体也可参考代码库:wechaty-puppet-xp

对比Web协议的功能来说其实是少了很多,但是功能基本上都齐全了,所以如果你的需求不是很高的话,可以使用PC协议的微信机器人;

4. 优势与劣势

PC协议的微信机器人主要的优势在于有固定的ID用户ID群组ID,这是对比Web协议的天然优势;

同时性能相对于Web协议的微信机器人更好,具体原因是因为PC协议的微信机器人内部操作比Web协议的微信机器人更加简单,毕竟功能少;

这里我列举一些缺陷点,这些缺陷点在Web协议的微信机器人中是不存在的,供大家参考:

  1. 有时候消息会发送失败
  2. 无法获取群组成员,只有在第一次登录的时候才能获取到,如果下次想要获取就需要重新登录
  3. 无法获取群成员的备注名
  4. 无法准确获取好友的昵称,在有备注的情况下会获取备注名(不是群聊的备注名)
  5. 无法准确获取好友列表和群聊列表
  6. 无法自动通过好友请求
  7. 判断是否是好友的接口不准确
  8. 不是跨平台的,只能在Windows上运行

大概就这么多吧,其实我的使用场景是不需要这么多功能的,所以功能对于我来说是够用的,我也没有进行更深度的探索。

注:这是一个开源的项目,如果你觉得功能不满足或者有更好的解决方案,可以自己去实现,这个库现在也不更新了,基于我的探索,这个库的底层使用了frida.re/,感兴趣的可以去了解一下。

现在也有比较新的基于PC协议的微信机器人,但是我看功能也并不是很多,感兴趣的可以去了解一下:WeChatFerry

5. 总结

这篇文章主要是讲解了wechaty-puppet-xp的使用,以及它和wechaty-puppet-wechat的区别,以及它的优势和劣势;

这个库的功能相对于wechaty-puppet-wechat来说是少了很多,但是对于一些简单的需求来说是够用的,如果你的需求不是很高的话,可以使用PC协议的微信机器人;