使用gocqhttp搭建QQ机器

序言

gocqhttp基于 Mirai 以及 MiraiGo 的 OneBot Golang 原生实现(此句照搬文档
个人使用(不知道是不是只能使用)Python语言进行编写,仅供教程,不做完全分享
官方文档地址
github项目地址

安装环境

Python语言环境配置下载Python
勾选Add python.exe to PATH
要勾选Add python.exe to PATH
点击Next

勾选Add Python to environment variables
Install
安装完毕后Win + R打开运行输入cmd
键入Python

如上图所示即为安装成功

配置项目

下载go-cqhttp.exe后,双击运行,无视弹窗内容直接确定(因为要用运行exe生成bat启动exe才是正确启动),三次确定后出现go-cqhttp.bat双击运行

配置config.yml客户端信息

选择HTTP通信提示退出,打开config.yml
账号密码可不配置,拉到最下面

修改为以下内容

//可将从server部分完全替换
servers:
  # 添加方式,同一连接方式添加多个,具体配置说明查看文档
  #- http: # http 通信
  #- ws:   # 正向 Websocket
  #- ws-reverse: # 反向 Websocket
  #- pprof: #性能分析服务器

  - http: # HTTP 通信设置
      address: 0.0.0.0:5700 # HTTP监听地址
      timeout: 5      # 反向 HTTP 超时时间, 单位秒,<5 时将被忽略
      long-polling:   # 长轮询拓展
        enabled: false       # 是否开启
        max-queue-size: 2000 # 消息队列大小,0 表示不限制队列大小,谨慎使用
      middlewares:
        <<: *default # 引用默认中间件
      post:           # 反向HTTP POST地址列表
      #- url: ''                # 地址
      #  secret: ''             # 密钥
      #  max-retries: 3         # 最大重试,0 时禁用
      #  retries-interval: 1500 # 重试时间,单位毫秒,0 时立即
      url: http://127.0.0.1:5701/ # 地址
      secret: ''                  # 密钥
      max-retries: 10             # 最大重试,0 时禁用
      retries-interval: 1000      # 重试时间,单位毫秒,0 时立即

这里要特别注意的是,http配置address与下方post的url端口不能相同(可以修改)
保存后运行bat尝试登录

[2023-01-07 00:23:26] [INFO]: 当前版本:v1.0.0-rc4
[2023-01-07 00:23:26] [INFO]: 将使用 device.json 内的设备信息运行Bot.
[2023-01-07 00:23:26] [INFO]: Bot将在5秒后登录并开始信息处理, 按 Ctrl+C 取消.
[2023-01-07 00:23:31] [INFO]: 开始尝试登录同步消息...
[2023-01-07 00:23:31] [INFO]: 使用协议: Android Phone
[2023-01-07 00:23:32] [INFO]: Protocol -&gt; connect to server: 36.155.206.145:8080
[2023-01-07 00:23:32] [WARNING]: Protocol -&gt; device lock is disable. http api may fail.
[2023-01-07 00:23:35] [INFO]: 收到服务器地址更新通知, 将在下一次重连时应用.
[2023-01-07 00:23:35] [INFO]: 登录成功 欢迎使用: acao
[2023-01-07 00:23:35] [INFO]: 开始加载好友列表...
[2023-01-07 00:23:35] [INFO]: 共加载 23 个好友.
[2023-01-07 00:23:35] [INFO]: 开始加载列表...
[2023-01-07 00:23:36] [INFO]: 共加载 7 个群.
[2023-01-07 00:23:36] [INFO]: 资源初始化完成, 开始处理信息.
[2023-01-07 00:23:36] [INFO]: アトリは、高性能ですから!
[2023-01-07 00:23:36] [INFO]: HTTP POST上报器已启动: http://127.0.0.1:5701/
[2023-01-07 00:23:36] [INFO]: 正在检查更新.
[2023-01-07 00:23:36] [INFO]: CQ HTTP 服务器已启动: [::]:5700
[2023-01-07 00:23:48] [INFO]: 检查更新完成. 当前已运行最新版本.
[2023-01-07 00:23:48] [INFO]: 开始诊断网络情况
[2023-01-07 00:23:51] [INFO]: 网络诊断完成. 未发现问题
[2023-01-07 00:23:58] [WARNING]: 上报 Event 数据到 http://127.0.0.1:5701/ 失败: Post "http://127.0.0.1:5701/": dial tcp 127.0.0.1:5701: connectex: No connection could be made because the target machine actively refused it. 将进行第 1 次重试
[2023-01-07 00:24:02] [WARNING]: 上报 Event 数据到 http://127.0.0.1:5701/ 失败: Post "http://127.0.0.1:5701/": dial tcp 127.0.0.1:5701: connectex: No connection could be made because the target machine actively refused it. 将进行第 2 次重试

这里上报出现了许多错误,是正常现象,因为我们没有监听程序,没地方上报
我们接下来写完监听程序就不会这样了
注:第七行的[WARNING]: Protocol -&gt; device lock is disable. http api may fail.属于正常现象,不需要问题(不影响

config.yml 中,还可以设置在线状态,参考在线状态

配置device.json账号信息

{
	"display": "MIRAI.619943.001",
	"product": "mirai",
	"device": "mirai",
	"board": "mirai",
	"model": "mirai",
	"finger_print": "mamoe/mirai/mirai:10/MIRAI.200122.001/0642953:user/release-keys",
	"boot_id": "8cfd480f-5acb-cb0f-0462-9dd269b378c3",
	"proc_version": "Linux version 3.0.31-MJXB114B (android-build@xxx.xxx.xxx.xxx.com)",
	"protocol": 1,
	"imei": "121268379926671",
	"brand": "mamoe",
	"bootloader": "unknown",
	"base_band": "",
	"version": {
		"incremental": "5891938",
		"release": "10",
		"codename": "REL",
		"sdk": 29
	},
	"sim_info": "T-Mobile",
	"os_type": "android",
	"mac_address": "00:50:56:C0:00:08",
	"ip_address": [10, 0, 1, 3],
	"wifi_bssid": "00:50:56:C0:00:08",
	"wifi_ssid": "u003cunknown ssidu003e",
	"imsi_md5": "90b7592b208260238577eb697e1f426b",
	"android_id": "49ebbf42888f6b36",
	"apn": "wifi",
	"vendor_name": "MIUI",
	"vendor_os_name": "mirai"
}

这是格式化过的!!!不是你的出了问题!!!
主要注意的是Protocol,这是你的登录状态默认5位ipad协议这里我改用了Android协议

Android协议:登录状态显示,前面config.yml设置的,但是手机端无法再登录Bot的QQ
ipad协议优点:运行Bot后可在手机端登录,但是登录状态显示WiFi在线-2G

值得一提的是,在config.yml的38行,有一个是否上报自身消息,也就是所谓的自触发,以及40行的是否移除replay自带at效果,根据自身需要打开False是关闭,True打开

消息监听

消息上报内容

也就是我们要从go-cqhttp那里接收上报的消息
先来了解一下监听上报的消息格式内容(普通消息

{
	'post_type': 'message',
	'message_type': 'group',
	'time': 1672415467,
	'self_id': 3054770279,
	'sub_type': 'normal',
	'font': 0,
	'group_id': 594875964,
	'user_id': 423866219,
	'message_id': -731133797,
	'sender': {
		'age': 0,
		'area': '',
		'card': '',
		'level': '',
		'nickname': '福建第一深情',
		'role': 'owner',
		'sex': 'unknown',
		'title': '',
		'user_id': 423866219
	},
	'anonymous': None,
	'message': '6',
	'message_seq': 4452,
	'raw_message': '6'
}

这是一条消息(当然也是格式化之后的)
其中post_type我们接收到的消息类型,即message
message_type是指我们接收到的是group(群聊消息)或是private(私聊消息)
group_id为群号,user_id为QQ号,self_id为Bot本身的QQ号

我们开始写一个监听程序

监听程序

我们用的是Python的pip库中的FlaskWin+R打开运行输入cmd点击确定,先更新一下pip

C:Userafanm> python -m pip install --upgrade pip

更新完成后再安装Flask

C:Userafanm> pip install flask

flask替换成其它,再安装requests

打开一个.py文件随意命名(我这里main.py
监听如下

from flask import Flask,request
import afan
app = Flask(__name__)

@app.route('/', methods=["POST"])
def post_data():
    data = request.get_json()
    print(data)
    if data['post_type'] == 'message':
        
        message = data['message']
        print(message)
        afan.messagex()
    elif data['post_type'] == 'notice':
        pass
    else:
        print("忽略上报")

    return "OK"


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5701)

导入初始化Flask,我们将request得到的数据赋值给data,意思就是data这个变量就是我们收到上报的消息,并调用我们写在afan.py的回复,这里的port就是我们刚刚post设置的端口

插入)go-cqhttp运行的原理

go-cqhttp客户端将我们电脑配置成为微型服务器,开放了5700和5701端口进行通讯,通过访问我们自己电脑上的API接口进行发送,所以即使没有程序,我们访问接口依旧可以运行
例如发送消息接口终结点send_msg,在运行客户端后,网址访问127.0.0.1/send_msg依旧可以发送消息(需要提交参数

消息回复

那么我们封装一个接口,直接调用就可以发送消息,不需要反复写API
由官方API文档,我们能了解到:
消息的终结点send_msg
需要参数为群号,消息内容,发送类型,我们以群消息为例

class API:
	@staticmethod
	def send(message):
		url = "http://127.0.0.1:5700/send_msg"#这里要加上http://,不然会报错
		data = request.get_json()#获取上报消息
		params = {
			"message_type":data['message_type'],
			"group_id":data['group_id'],
			"message":message
		}
		requests.get(url,params=params)

这样,当我们在后方词库调用该函数时,只需传入消息内容便可以发送了,私聊的话只需要判断消息来源进行微调即可

接下来,创建文件afan.py导入main.py以及一些其它库

我们前面写道,如果消息类型为message的话,调用afan.messagex(),导入afan后,定义一个函数messagex()
我的Bot名为阿草,我先写一个当我发送 阿草 时回复 阿草在哦 的词库

import requests
from flask import Flask,request
from main import API
def messagex():
	data = request.get_json()
	message = data['message']
	if "阿草" == message:
		API.send("阿草在哦")
	else:
		print("指令错误")#这里不是发送,是打印到我们后台监听程序

这样,当消息为阿草的时候,调用API发送阿草在哦

接下来我们只要运行main.py然后启动go-cq客户端就可以了

至于其它东西,我们只需要根据上报收到的消息进行设置就行了,上报消息内容,我们依然可以在文档的 Event上报查看
实现其它内容,只需要封装其它接口进行调用即可

注意:封装接口时调用的端口是5700,客户端监听5700,消息post上报到5701,再有main.py进行监听5701调用词库回复,可根据需要自行修改,不要运行afan.py词库文件,会造成端口冲突的,我们只需要运行main.py和go-cq客户端即可

代码整合

最后送上上面整合的监听以及回复代码
main.py

from flask import Flask,request
import requests
import afan

app = Flask(__name__)

class API:
	@staticmethod
	def send(message):
		url = "http://127.0.0.1:5700/send_msg"#这里要加上http://,不然会报错
		data = request.get_json()#获取上报消息
		params = {
			"message_type":data['message_type'],
			"group_id":data['group_id'],
			"message":message
		}
		requests.get(url,params=params)

@app.route('/', methods=["POST"])
def post_data():
    data = request.get_json()
    print(data)
    if data['post_type'] == 'message':
        
        message = data['message']
        print(message)
        afan.messagex()
    else:
        print("忽略消息")

    return "OK"


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5701)


afan.py

import requests
from flask import Flask,request
from main import API

def messagex():
	data = request.get_json()
	message = data['message']
	if "阿草" == message:
		API.send("阿草在哦")
	else:
		print("指令错误")#这里不是发送,是打印到我们后台监听程序

原文地址:https://blog.csdn.net/qq_64126275/article/details/128586651

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_11075.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注