居然只用 20 多行代码就可以实现微信聊天机器人 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
461229187
V2EX    程序员

居然只用 20 多行代码就可以实现微信聊天机器人

  •  1
     
  •   461229187
    codexu 2024-02-01 08:31:32 +08:00 11266 次点击
    这是一个创建于 672 天前的主题,其中的信息可能已经有所发展或是发生改变。

    用了一年多 chatGPT 和白嫖了 vscode 的 copilot ,现在感觉已经离不开了,所以也想把这么好用的东西推荐给自己的家人和朋友。但是由于网络的限制,想让他们体验到聊天机器人的神奇是很困难的。当然现在百度阿里等巨头都已经发布了他们的产品,但需要下载相应的 app ,还要登录等一些列操作,稍微繁琐一点都会让他们失去兴趣。所以我打算开发一个微信聊天机器人,他们只需要加微信好友即可体验到。

    在编写代码前,先要对以下几个东西做一些了解,简单且好用。

    GPT API

    在国内访问 chatGPT 是比较麻烦的,搞不好还容易封号。所以这里我推荐一下国内可用的一个接口,GPT-API-free,看名字就知道这是个免费的,虽然免费,但是有调用频率的限制,60 请求/小时/IP&Key ,可以通过 github 领取。理论上自己用的话免费的就可以,如果想调用 GPT4 ,每天也可以使用 3 次。

    如果你访问频率高,可以购买付费服务,如果 gpt3.5 的话,我预测 30 块用一年应该没什么问题,GPT4 的话就比较贵了。

    wechaty

    Wechaty 是一款用于构建聊天机器人的开源程序,他运行于 node(v16+) 环境,它提供了几乎微信所有操作接口,例如登录、接发消息、好友操作、备注、群组等等,这样我们就可以通过 Wechaty + GPT API 的组合实现微信聊天机器人了。

    对了,你最好再申请个微信号,不然封号就得不偿失了。我已经用了半个多月,没被封号。

    需要注意的是还需要了解一个库配合 wechaty 实现在命令行中扫码登录微信,qrcode-terminal ,他用法非常简单,无需去看文档。

    代码实现

    由于功能很简单,我也懒得去搞部署之类的东西,所以我直接在服务器上写的代码...

    安装依赖

    首先创建一个 node 项目,npm init

    安装依赖:

    npm install wechaty qrcode-terminal axios 

    代码不多,创建一个 index.js 即可,首先引入即将使用到的方法,并创建聊天机器人示例:

    import axios from 'axios'; import { ScanStatus, WechatyBuilder, log } from 'wechaty' import qrcodeTerminal from 'qrcode-terminal' const bot = WechatyBuilder.build({ name: 'codexu-chat-bot', // 名字随意 }) const sk = '' // 顺便把接口 sk 定义上 bot.start(); 

    如果你将代码放在 git 仓库,建议创建环境变量等方式去获取 sk ,保证安全,不要泄漏。

    扫码登录

    随后先实现扫码登录功能,bot 实例提供了很多事件监听,这里我们监听 scan 事件,它提供了两个参数,二维码和状态,这里我们需要对二维码做一下转换,并通过 qrcodeTerminal 将二维码展示在命令行中。

    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 }) // show qrcode on console } else { log.info('StarterBot', 'onScan: %s(%s)', ScanStatus[status], status) } } bot.on('scan', onScan) 

    与登录相关的,bot.on 还可以监听到 loginlogout 事件,请自行添加。

    处理聊天信息

    然后就是关键的处理聊天消息,这里我使用 axios 去调用接口,需要在 header 中传入 sk ,并按照接口文档传递模型和消息记录:

    async function onMessage(msg) { const text = msg.text() let cacheMessagesItem = cacheMessages.find(item => item.name === talker.name); const message = { role: "user", content: text } const data = { model: 'gpt-3.5-turbo-1106', messages: [message] } const result = await axios.post(`https://api.chatanywhere.com.cn/v1/chat/completions`, data, { headers: { Authorization: `Bearer ${sk}`, 'Content-Type': 'application/json' } }) const resultCOntent= result.data.choices[0].message.content; await msg.say(resultContent) } bot.on('message', onMessage) 

    然后通过 node index.js 运行即可,如果在服务器上推荐使用 pm2 去管理程序,不然报错可能就停止了。

    至此就已经实现了微信聊天机器人的基本功能,快去体验一下吧。

    优化

    通过 20 多行代码就实现了聊天机器人是不是很简单,但是它现在还傻傻的不太好用,我们可以对他进行一些优化。

    机器人人设

    当我把它介绍给亲人朋友时,神奇的是他们都会问这么几个问题:

    • 你是谁?
    • 你认识李旭吗?(我本人)

    但是 chatGPT 只能傻傻的回答他是什么语言大模型之类的,毫无新意,这样的话我们可以为他建立人设。

    image.png

    image.png

    可以看到调用 GPT 接口时,messages 参数是一个数组,它是连续聊天的关键,也就是说你把聊天记录都传进来,这样 GPT 就可以在回答时参考上下文来回答。

    所以我们只需要在每次调用接口时,告诉 GPT 它要去扮演李旭的机器人这个角色,并告诉他我是谁就可以了。

    const message = { role: "user", content: `本次对话你扮演的是李旭的机器人的角色,是微信的聊天助手,你的微信名是李旭的机器人,李旭是一个非常帅的人并且有才华的人,今年 18 岁。` } 

    同理,如果你想实现连续聊天,把聊天记录传到 messages 中即可,当然调用接口是按照字数收费,并且数据有最大限制,所以我们尽量传 10 条以内的聊天记录也就够了,这里大家自行实现列队功能吧。

    自动添加好友

    当我把机器人名片推给别人时,还需要手动去微信添加好友,这就很麻烦了,尤其是朋友再推给其他人时,还需要让我去同意添加,这样比较麻烦。

    幸运的是 wechaty 还提供了对添加好友的操作。

    bot.on('friendship', async friendship => { try { switch (friendship.type()) { case 2: await friendship.accept() break } } catch (e) { console.error(e) } }) 

    这样我们就实现了自动添加好友的功能。

    其他

    我目前可以想到的:

    • 年龄大的人比较爱发语音,并且眼神不好,语音的体验方式更适合,可以借助转录将语音转成文字,再将结果文字转换成语音发送给使用者。
    • GPT4 接口较贵,所以默认使用 GPT3 即可,加入判断,在聊天文字前输入 GPT4 ,再去调用 GPT4 模型,这样可以根据需要使用不同模型。
    • 可以做一些画图的功能或识别图像的功能。

    总结

    当我产生了做这个机器人的想法到实现,我都没有想到居然如此简单,看似复杂的功能,已经被 wechaty 做成了非常简单的操作。

    另外其他人在使用的时候,你是可以看到他们的聊天记录的,我建议你应该告诉使用者你可以看到他们的消息。

    我没跟我妈说能看到他的问题,我看到她在问失眠怎么办?哎...

    第 1 条附言    2024-02-01 14:12:35 +08:00
    记录一下,备用机几天没充电了,发现服务器掉了,报错
    Error: 状态同步超过 297.966s 未响应,5s 后尝试重启
    所以这个微信机器人还得长期手机端在线才行...
    46 条回复    2025-09-10 14:20:36 +08:00
    TenProX
        1
    TenProX  
       2024-02-01 08:34:01 +08:00 via iPhone
    支持大佬的作品!膜拜!
    sekiseki
        2
    sekiseki  
       2024-02-01 08:37:52 +08:00
    wechaty 两年前已经看过了,但是要扫码。还有更方便的。
    winglight2016
        3
    winglight2016  
       2024-02-01 08:52:44 +08:00
    感谢大佬无私分享!

    我之前也考虑做个类似的小工具,但是发现 github 上的几个微信库都非常陈旧,包括这个 wechaty ,lz 确定能兼容最新版的微信吗?
    461229187
        4
    461229187  
    OP
       2024-02-01 08:55:25 +08:00
    @sekiseki 还有高手?叫什么我去研究一下
    461229187
        5
    461229187  
    OP
       2024-02-01 08:55:57 +08:00
    @winglight2016 没深入研究,反正目前我这点功能足够用了,运行正常
    mybro
        6
    mybro  
       2024-02-01 09:06:04 +08:00
    敢用 wechaty 的都是勇士
    461229187
        7
    461229187  
    OP
       2024-02-01 09:08:42 +08:00
    @mybro 所以到底还有什么代替品
    heider
        8
    heider  
       2024-02-01 09:1:27 +08:00
    这个连续聊天的实现太傻了。。。
    lingeo
        9
    lingeo  
       2024-02-01 09:17:35 +08:00
    微信机器人还推荐[wcferry]( https://github.com/lich0821/WeChatFerry.git),目前已经已经支持到 3.9.2.23 ,作者人很好。
    lingeo
        10
    lingeo  
       2024-02-01 09:18:03 +08:00
    461229187
        11
    461229187  
    OP
       2024-02-01 09:26:19 +08:00
    @heider 我问了 GPT_API_free 客服,让我这么搞的,确实有点浪费,还有更好方式嘛?
    461229187
        12
    461229187  
    OP
       2024-02-01 09:26:54 +08:00
    @lingeo #9
    dabai0806
        13
    dabai0806  
       2024-02-01 09:27:03 +08:00
    好像都没有提供发送微信语音的接口
    461229187
        14
    461229187  
    OP
       2024-02-01 09:30:14 +08:00
    @dabai0806 只能发文本和文件,但是接收是可以语音的
    a86356
        15
    a86356  
       2024-02-01 09:33:39 +08:00
    这个不是一个 token 每个月 200 的那个吗? ipad 登录协议
    okura
        16
    okura  
       2024-02-01 09:39:45 +08:00 via Android
    这个我之前试过,好像对微信号有要求的
    461229187
        17
    461229187  
    OP
       2024-02-01 09:41:15 +08:00
    @okura 我办了个副卡,目前就加了 10 个人左右,暂时没啥问题
    zhusimaji
        18
    zhusimaji  
       2024-02-01 09:41:47 +08:00
    很危险,吃枣药丸
    461229187
        19
    461229187  
    OP
       2024-02-01 09:43:10 +08:00
    @zhusimaji 手机号花了 10 块,问题不大
    opengps
        20
    opengps  
       2024-02-01 09:55:10 +08:00
    同意添加好友哪里,你完全可以设置成不需要经过你同意,而不用开发一套功能出来
    461229187
        21
    461229187  
    OP
       2024-02-01 10:01:45 +08:00
    @opengps 凑字数,这样也可以更灵活,比如加个校验什么的,可以避免谁都可以加
    Alias4ck
        22
    Alias4ck  
       2024-02-01 10:16:54 +08:00
    微信机器人很危险 很容易被封号
    gniviliving
        23
    gniviliving  
       2024-02-01 10:17:43 +08:00
    @lingeo #10 这个只支持 windows 版本,而且微信版本也限制在 3.9.2.29 及以下
    chairuosen
        24
    chairuosen  
       2024-02-01 10:24:45 +08:00
    好了,知道你叫李旭了
    461229187
        25
    461229187  
    OP
       2024-02-01 10:28:02 +08:00   3
    @chairuosen 叫李旭的很多,如果你见到一个很帅的,那就是我了
    rick2c
        26
    rick2c  
       2024-02-01 10:42:23 +08:00
    难道只有我觉得很好用么,自己随便接了一个给小作坊做[微信群通知]( https://github.com/c-rick/nestjs-wechaty)方便还免费
    AsherTan
        27
    AsherTan  
       2024-02-01 10:50:43 +08:00
    @mybro 咋说?有漏洞吗?
    abersheeran
        28
    abersheeran  
       2024-02-01 10:52:38 +08:00
    所以为啥不直接用个人的微信公众号,除了不能在群里直接艾特使用之外,好像也没有少别的功能,而且更稳定,无需扫码登录或者担心微信给你干掉了。
    yufeng0681
        29
    yufeng0681  
       2024-02-01 10:55:12 +08:00
    正好在看一本书《我们为什么要睡觉》 ,里面提到 安眠药的本质是镇定脑部某区域, 不能让人进入深度睡眠,人无法进入到恢复模式。最后身体只会越来越差。
    要想解决失眠问题,不能依赖安眠药
    cat9life
        30
    cat9life  
       2024-02-01 10:57:19 +08:00
    wechaty 走的是 web 协议吗?不支持网页版微信的可以使用吗
    lingeo
        31
    lingeo  
       2024-02-01 10:58:00 +08:00
    @Alias4ck 导致封号的原因是机器人行为,并不是破解了什么。
    spediacn
        32
    spediacn  
       2024-02-01 12:19:45 +08:00 via iPhone
    的确,敢用 wechaty 的都是勇士
    hellojay
        33
    hellojay  
       2024-02-01 12:32:23 +08:00
    wechaty 的 padlocal 还是可以的,就是要收费每个月 200 。我用了好几年了没什么问题
    rekulas
        34
    rekulas  
       2024-02-01 12:35:27 +08:00
    我没记错的话 wechaty 免费版只能用老号登录 web 协议吧? 免费机器人那么多为何要推荐一个收费的
    Alias4ck
        35
    Alias4ck  
       2024-02-01 13:32:32 +08:00
    @lingeo 我说的就是这啊,微信生态就这样啊 所以慎用微信机器人我也没说破解吧
    izjing666
        36
    izjing666  
       2024-02-01 13:50:26 +08:00
    web 协议是怎么解决一直掉线的问题?
    coderpwh
        37
    coderpwh  
       2024-02-01 13:54:06 +08:00
    我是自己写了一个 xposed 的微信机器人,备用机挂着就好
    nunterr
        38
    nunterr  
       2024-02-01 14:02:09 +08:00
    挺好的东西,主要是用起来被微信封的概率太高,以至于不敢用
    v9JOFrNzq9Q9jyox
        39
    v9JOFrNzq9Q9jyox  
       2024-02-01 14:48:20 +08:00
    感谢无私分享!
    HanSonJ
        40
    HanSonJ  
       2024-02-01 15:32:38 +08:00
    461229187
        41
    461229187  
    OP
       2024-02-01 16:05:35 +08:00
    @nunterr 千万别用大号
    wzdsfl
        42
    wzdsfl  
       2024-02-01 16:45:23 +08:00
    作为使用 wechaty 一年+的过来人,我总结经验如下:
    1 、OP 给出的 wechaty 是基于 web 协议的,虽然可以加上 uos 来绕过微信 web 协议的阻拦,但是仍存在 [!较大!] 封号可能,并且存在一些问题:获取不到 wxid ,缺少一些 API (半年警告封号 2 次)
    2 、进阶:使用其他 provider ,如 padLocal 之类,个人如果有限制机器(win),可以用 https://github.com/wechaty/puppet-xp ,可以跑本地微信机器人,原理是利用 Hook 进行消息拦截和内存 call ,一般不会封号(稳定使用 1 年+)
    3 、再进阶:绕过框架,直接使用 dll 进行 hook 。好处是可以自定义框架,存在更高自由度,缺点是不同版本微信存在不同的功能,并且有的会收费。

    目前我在使用 https://github.com/ttttupup/wxhelper/tree/dev-3.9.5.81 进行类 wechaty 封装,并且项目开源免费,有使用需求的朋友可以关注这个项目
    RockShake
        43
    RockShake  
       2024-02-01 17:06:14 +08:00
    疫情期间用了这个 API 提醒群成员打卡,收集核酸情况,封了两个人的 Web 微信
    461229187
        44
    461229187  
    OP
       2024-02-01 18:39:39 +08:00
    @wzdsfl 感谢大佬指点
    winglight2016
        45
    winglight2016  
       2024-02-23 10:32:41 +08:00
    @461229187 #5 我试了一下 wechaty ,先用 docker 版,失败在扫描登录后 regular 代码出错,然后直接下载 wechaty/get-started 仓库运行,很奇怪的是,这次就没有二维码扫了

    lz 能不能介绍一下最基本的运行环境,可以扫描登录成功就行,谢谢
    SuQie
        46
    SuQie  
       84 天前
    @hellojay 老哥这个还有在用吗,官网登录不上去好像
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5807 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 32ms UTC 01:55 PVG 09:55 LAX 17:55 JFK 20:55
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86