之前的操作一直是通过官方网址直接提问,奈何这样的方式对于网上冲浪的水平有一定要求。笔者的女朋友又是一个问题宝宝,经常看到她在百度上搜索各种答案却不得其解,抓耳挠腮的样子。便萌生了接入微信聊天,方便向ChatGpt提问的想法。
项目部署基于大佬的源码,源码地址
一、简易版(微信个人账号)
ChatGpt机器人的工作原理是微信扫码登陆后,当触发某些关键词时,通过API调用ChatGPT的接口进行回复。
准备工作
- 注册一个ChatGpt账号,教程参考:ChatGPT保姆级教程,一分钟学会使用ChatGPT!
- 创建完账号则前往 API管理页面 创建一个 API Key 并保存下来,后面项目配置中会用到。
开始部署
基础版很简单,可以参考源码地址中的README.md文档进行部署。
这里推荐使用Railway进行部署,注册一个railway账号后即可一键部署。
部署过程中需要填入一些配置变量:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| # config.json文件内容示例 { "open_ai_api_key": "YOUR API KEY", # 填入上面创建的 OpenAI API KEY "model": "gpt-3.5-turbo", # 模型名称。当use_azure_chatgpt为true时,其名称为Azure上model deployment名称 "proxy": "127.0.0.1:7890", # 代理客户端的ip和端口 "single_chat_prefix": ["bot", "@bot"], # 私聊时文本需要包含该前缀才能触发机器人回复 "single_chat_reply_prefix": "[bot] ", # 私聊时自动回复的前缀,用于区分真人 "group_chat_prefix": ["@bot"], # 群聊时包含该前缀则会触发机器人回复 "group_name_white_list": ["ChatGPT测试群", "ChatGPT测试群2"], # 开启自动回复的群名称列表 "group_chat_in_one_session": ["ChatGPT测试群"], # 支持会话上下文共享的群名称 "image_create_prefix": ["画", "看", "找"], # 开启图片回复的前缀 "conversation_max_tokens": 1000, # 支持上下文记忆的最多字符数 "speech_recognition": false, # 是否开启语音识别 "group_speech_recognition": false, # 是否开启群组语音识别 "use_azure_chatgpt": false, # 是否使用Azure ChatGPT service代替openai ChatGPT service. 当设置为true时需要设置 open_ai_api_base,如 https: "character_desc": "你是ChatGPT, 一个由OpenAI训练的大型语言模型, 你旨在回答并解决人们的任何问题,并且可以使用多种语言与人交流。", # 人格描述 # 订阅消息,公众号和企业微信channel中请填写,当被订阅时会自动回复,可使用特殊占位符。目前支持的占位符有{trigger_prefix},在程序中它会自动替换成bot的触发词。 "subscribe_msg": "感谢您的关注!\n这里是ChatGPT,可以自由对话。\n支持语音对话。\n支持图片输出,画字开头的消息将按要求创作图片。\n支持角色扮演和文字冒险等丰富插件。\n输入{trigger_prefix}#help 查看详细指令。" }
|
最重要的就是open_ai_api_key,填入准备工作中的OpenAI API KEY。
其他的一些配置是触发机器人回复的前缀、开启自动回复的群聊名称等等。可以配置这些可根据实际使用需要修改配置。 我这里就是所有群聊都可以开启机器人:
配置完毕后直接进行部署,完成会生成一个二维码,通过微信扫描二维码登陆后(类似于网页版微信),即刻开启机器人回复。
私聊:
群聊:
至此,一个ChatGPT机器人就搭建完成了。
简易版存在的问题
- 因为微信机制的原因,微信扫码登陆会要求手机端必须在线,同时电脑端和网页端不可以同时登陆,所以日常工作需要电脑登陆微信的话会有不便,最好是单独准备一个备用机和备用微信。
- 这样就引发了另一个问题:经常掉线。经常登陆1-2天后,机器人就掉线了,且日志打印log out无其他异常信息。 个人猜测是因为微信网页端存在测活机制,如果一定时间内该微信账号没有活跃迹象,会强制登出。 需要重新部署服务后再次扫码登陆,有点影响使用体验。
- 个人微信登陆存在封号的风险(不过我使用过程中未收到帐号异常的提醒)
二、升级版(微信订阅号)
为了解决简易版的一系列问题,通过微信订阅号来实现。
实现原理:我们在关注公众号或订阅号的时候,经常发现我们输入某些关键词就会触发公众号的自动回复。这里的自动回复可以通过公众号配置,也可以通过服务器转发。即将用户的输入转发作为请求调用服务器的接口,将服务器接口的返回作为公众号的回复。
准备工作
- 一个拥有公网IP的服务器,或者本地启动服务后进行内网穿透,否则微信服务器无法将消息发送给我们的服务器。服务器的系统最好是ubuntu,不然会存在部分依赖无法安装的情况。
- 微信公众号,类型选择订阅号。
- 一个可以科学上网的订阅地址。
本人环境:
- 系统版本: Ubuntu 22.04 LTS
- python版本:python3.10
- pip版本:pip 22.0.2
微信公众平台-基本配置
公众号注册完后后需要进行如下配置
- appId:微信公众平台生成。
- appSecret:需要自己手动在微信公众平台生成,并做好保存。
- IP白名单:服务器的ip地址。
- 服务器地址:http:///wx, 根据自己实际ip地址替换。
- token:自定义。
- EncodingAESKey:手动在微信公众平台生成(消息加密方式为密文时候用到)。
服务器部署
- 登陆服务器,克隆代码
Text1
| git clone https://github.com/zhayujie/chatgpt-on-wechat
|
- 安装依赖
1 2 3 4 5 6
| cd chatgpt-on-wechat/
pip3 install -r requirements.txt
pip3 install -r requirements-optional.txt
|
- 安装python的web框架web.py和wechatpy
Text1 2
| pip3 install web.py pip3 install wechatpy
|
- 增加配置
新建config.json文件,并加入下面配置,配置的相关内容根据自己的微信公众平台和服务器信息填写。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| { "open_ai_api_key":"", "channel_type":"wechatmp", "wechatmp_token":"", "wechatmp_port":8080, "wechatmp_app_id":"", "wechatmp_app_secret":"", "wechatmp_aes_key":"", "single_chat_prefix":[ "" ], "single_chat_reply_prefix":"", "plugin_trigger_prefix":"&", "model":"gpt-3.5-turbo", "proxy":"127.0.0.1:7890", "group_chat_prefix":[ "@bot" ], "group_name_white_list":[ "ALL_GROUP" ], "group_chat_in_one_session":[ "ALL_GROUP" ], "image_create_prefix":[ "画", "看", "找" ], "conversation_max_tokens":1000, "speech_recognition":false, "group_speech_recognition":false, "use_azure_chatgpt":false, "character_desc":"你是ChatGPT, 一个由OpenAI训练的大型语言模型, 你旨在回答并解决人们的任何问题,并且可以使用多种语言与人交流。", "subscribe_msg":"感谢您的关注!\n这里是ChatGPT,可以自由对话。\n支持语音对话。\n支持图片输出,画字开头的消息将按要求创作图片。\n支持角色扮演和文字冒险等丰富插件。\n输入{trigger_prefix}#help 查看详细指令。" }
|
- open_ai_api_key:简易版中API Key
- channel_type:wechatmp或wechatmp_service, wechatmp是个人主体的微信订阅号,目前存在回复时间限制,每天的图片和声音回复次数也有限制。而wechatmp_service需要通过微信认证,不存在这些限制。
- wechatmp_token:微信公众平台的Token,这里填的需要和微信公众平台中填的一致,待会会有校验。
- wechatmp_port:微信公众平台的端口,需要端口转发到80或4430。
- wechatmp_app_id:微信公众平台的appID。
- wechatmp_app_secret:微信公众平台的appsecret。
- wechatmp_aes_key:微信公众平台的EncodingAESKey,加密模式需要。
- plugin_trigger_prefix: 推荐设置,在手机微信客户端中,$%^等符号与中文连在一起时会自动显示一段较大的间隔,用户体验不好。请不要使用管理员指令前缀”#”,这会造成未知问题。
- 运行启动web服务器
使用nohup命令在后台运行程序:
1 2
| touch nohup.out nohup python3 app.py & tail -f nohup.out
|
- 端口转发
服务启动的端口默认是8080端口,但是微信公众号的服务器配置只支持80/443端口,使用端口转发命令将80端口转发到8080端口。
Text1 2
| sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080 sudo iptables-restore < /etc/iptables/rules.v4
|
微信公众平台-服务器配置
- 提交服务器配置
提交服务器配置的时候会校验服务是否可用和token是否一致,服务不可用或者token不一样,会提示token验证失败。
- 启用服务器
启用服务器后,订阅号收到的消息将会被转发到服务器,可以在日志文件nohup.out中看到。
发送消息:
日志打印:
Text1 2 3 4
| [INFO][2023-05-15 16:41:03][chat_gpt_bot.py:49] - [CHATGPT] query=你好 [WARNING][2023-05-15 16:41:09][chat_gpt_bot.py:138] - [CHATGPT] APIConnectionError: Error communicating with OpenAI: HTTPSConnectionPool(host='api.openai.com', port=443): Max retries exceeded with url: /v1/chat/completions (Caused by ProxyError('Cannot connect to proxy.', NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x000001E7F7DF39A0>: Failed to establish a new connection: [WinError 10061] 由于目标计算机积极拒绝,无法连接。'))) [INFO][2023-05-15 16:41:10][wechat_channel.py:187] - [WX] sendMsg=Reply(type=ERROR, content=[ERROR] 我连接不到你的网络), receiver=@86f21b179a0a03c26d1e6d93105790236ff5451d144f4c5a6f5ac0a6902d48a0
|
配置代理转发
细心的朋友会发现,在上一步中,微信公众号返回了错误,日志中也打印了目标服务器无法连接的错误。
这一步是因为我们的服务器不能直接连接openai的接口,需要配置代理进行转发。
- 下载项目
Text1 2 3 4
| # 到上一级目录 cd .. # 下载项目 git clone https://github.com/wanhebin/clash-for-linux.git
|
- 修改订阅地址
Text1 2 3 4
| # 进入项目目录 cd clash-for-linux # 修改配置 vim .env
|
将CLASH_URL改为订阅地址。
3. 启动程序
Text1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| # 运行启动脚本 $ sudo bash start.sh
正在检测订阅地址... Clash订阅地址可访问! [ OK ]
正在下载Clash配置文件... 配置文件config.yaml下载成功! [ OK ]
正在启动Clash服务... 服务启动成功! [ OK ]
Clash Dashboard 访问地址:http://<ip>:9090/ui Secret:xxxxxxxxxxxxx
请执行以下命令加载环境变量: source /etc/profile.d/clash.sh
请执行以下命令开启系统代理: proxy_on
若要临时关闭系统代理,请执行: proxy_off
|
- 配置环境变量&开启代理
Text1 2
| $ source /etc/profile.d/clash.sh $ proxy_on
|
- 检查
Text1 2 3 4 5 6 7 8 9 10 11
| # 检查服务端口 netstat -tln | grep -E '9090|789.' tcp 0 0 127.0.0.1:9090 0.0.0.0:* LISTEN tcp6 0 0 :::7890 :::* LISTEN tcp6 0 0 :::7891 :::* LISTEN tcp6 0 0 :::7892 :::* LISTEN
# 检查环境变量 env | grep -E 'http_proxy|https_proxy' http_proxy=http://127.0.0.1:7890 https_proxy=http://127.0.0.1:7890
|
以上步鄹如果正常,说明服务clash程序启动成功。
- 再次进行订阅号消息测试
成功!