本篇文章记录一下自己在编写QQ机器人的时候所遇到的一些问题和核心功能的实现。

QQ机器人RabbitBot采用python编写,由于是个人学习使用,故目前不会开源完整代码,只会放出核心代码供学习参考。

使用的go-cqhttp项目:https://github.com/Mrs4s/go-cqhttp

go-cqhttp是基于 Mirai 以及 MiraiGo 的 cqhttp golang 原生实现。
RabbitBot在读取、发送QQ信息时采用的是HTTP API和反向HTTP POST接口。

在这里也安利一波大佬同学Yang_99写的已经开源在github上的Yes酱,这么好的东西还不赶紧来star+fork
github项目地址:https://github.com/Yang9999999/Go-CQHTTP-YesBot
使用方法:

http://www.yang99.top/index.php/archives/18/

http://www.dtmao.cc/news_show_649533.shtml

初期配置

go-cqhttp的安装和完整配置可自行查看文档,这里描述一下关键部分。

配置文件:

{
uin: 0
password: 0
encrypt_password: false
password_encrypted: ""
enable_db: false
access_token: ""
relogin: {
enabled: true
relogin_delay: 3
max_relogin_times: 0
}
_rate_limit: {
enabled: false
frequency: 1
bucket_size: 1
}
ignore_invalid_cqcode: false
force_fragmented: true
fix_url: false
proxy_rewrite: ""
heartbeat_interval: -1
http_config: {
enabled: true
host: 0.0.0.0
port: 5700
timeout: 0
post_urls:
{
"127.0.0.1:5710":secret
}
}
ws_config: {
enabled: false
host: 0.0.0.0
port: 6700
}
ws_reverse_servers: [
{
enabled: false
reverse_url: ws://you_websocket_universal.server
reverse_api_url: ws://you_websocket_api.server
reverse_event_url: ws://you_websocket_event.server
reverse_reconnect_interval: 3000
}
]
post_message_format: string
use_sso_address: false
debug: false
log_level: ""
web_ui: null
}

其中uin为机器人QQ号
password为密码
enable_db为是否使用数据库,由于个人学习使用,这里并不开启数据库功能
heartbeat_interval为心跳间隔时间,默认开启,值小于0则关闭。
http_config进行http接口设置,post_urls设置上传接收端口
ws_configws_reverse_servers是Websocket的正向和反向接口,由于RabbitBot采用http接口,故这里也全部设置了false

RabbitBot开启后的显示结果:

信息发送和接收

RabbitBot利用python的socket库来进行数据的发送和接收,socket库的使用方法请自行学习。

5700为go-cqhttp默认端口,设置http post上报器端口为5710。

常用的HTTP API:
发送私聊信息:/send_private_msg
发送群聊信息:/send_group_msg

服务端接收信息配置:

ListenSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ListenSocket.bind(('127.0.0.1', 5710))
ListenSocket.listen(100) HttpResponseHeader = '''HTTP/1.1 200 OK
Content-Type: text/html
''' #定位有效信息
def request_to_json(msg):
for i in range(len(msg)):
if msg[i]=="{" and msg[-1]=="}":
return json.loads(msg[i:])
return None #需要循环执行,返回值为json格式
def rev_msg():# json or None
conn, Address = ListenSocket.accept()
Request = conn.recv(1024).decode(encoding='utf-8')
#print(Request)
rev_json=request_to_json(Request)
#print(rev_json)
conn.sendall((HttpResponseHeader).encode(encoding='utf-8'))
conn.close()
return rev_json

接收到的群聊信息格式:

{‘anonymous’: None, ‘font’: 0, ‘group_id’: ×××××, ‘message’: ‘爱你’, ‘message_id’: 1425567994, ‘message_seq’: 2170, ‘message_type’: ‘group’, ‘post_type’: ‘message’, ‘raw_message’: ‘爱你’, ‘self_id’: ×××××, ‘sender’: {‘age’: 0, ‘area’: ‘’, ‘card’: ‘’, ‘level’: ‘’, ‘nickname’: ‘七月’, ‘role’: ‘owner’, ‘sex’: ‘unknown’, ‘title’: ‘’, ‘user_id’: ×××××}, ‘sub_type’: ‘normal’, ‘time’: 1611721421, ‘user_id’: ×××××}

group_id为群号,user_id为发送者QQ号,message为接收到的信息,message_id为信息编号,随机生成,message_type为信息类型。

接收到的私聊信息格式:

{‘font’: 0, ‘message’: ‘[CQ:face,id=107]’, ‘message_id’: -730420846, ‘message_type’: ‘private’, ‘post_type’: ‘message’, ‘raw_message’: ‘[CQ:face,id=107]’, ‘self_id’: ×××××, ‘sender’: {‘age’: 0, ‘nickname’: ‘七月’, ‘sex’: ‘unknown’, ‘user_id’: ×××××}, ‘sub_type’: ‘friend’, ‘time’: 1611726456, ‘user_id’: ×××××}

user_id为通话者QQ号,message为接收到的信息,**’[CQ:face,id=107]’**为表情数据,message_id为信息编号,随机生成,message_type为信息类型。

客户端发送信息配置:

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

#从客户端发送给服务端
def client_to_conn():
label = get_message_type()
number = get_number()
msg = get_raw_message()
if flag == 0:
msg = txt_msg(get_raw_message())
if label == 'group':
payload = "GET /send_group_msg?group_id=" + str(number) + "&message=" + msg + " HTTP/1.1\r\nHost: 127.0.0.1:5700\r\nConnection: close\r\n\r\n"
elif label == 'private':
payload = "GET /send_private_msg?user_id=" + str(number) + "&message=××××" + " HTTP/1.1\r\nHost: 127.0.0.1:5700\r\nConnection: close\r\n\r\n"
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1',5700))
client.send(payload.encode("utf-8"))
client.close()

信息处理

RabbitBot的学习信息保存至一个txt文档中,个人学习问题不大,但做成项目的话不建议这么使用。

获取信息和处理信息的一些函数:

#获取信息类型 群聊/私聊 group/private
def get_message_type():
return all_message['message_type'] #获取群号/私聊qq号
def get_number():
if get_message_type() == 'group':
return all_message['group_id']
elif get_message_type() == 'private':
return all_message['user_id']
else:
print('出错啦!找不到群号/QQ号')
exit()
# 获取信息发送者的QQ号
def get_user_id():
return all_message['user_id'] #获取发送的信息
def get_raw_message():
return all_message['raw_message'] #查找txt文本数据库
def txt_msg(msg):
fp = open("/机器人/txt.txt", "r",encoding='utf-8')
while 1:
s = fp.readline()
if not s:
fp.close()
if flag == 2:
return
return error()
s = s.strip('\n')
s1 = s.split(' ')[0]
s2 = s.split(' ')[1]
if '[CQ:at,qq=×××××] ' + s1 == msg:
fp.close()
return s2

发送信息的一些函数:

#帮助界面
def help_interface():
number = get_number()
payload = "GET /send_group_msg?group_id=" + str(number) + "&message=学习方式:%0a私聊rabbit酱,发送学习信息。%0a学习格式:%27学习%27%20%2b%20发送信息%20%2b%20回复信息,以空格分开%0a例:学习%20我爱你%20我也爱你" + " HTTP/1.1\r\nHost: 127.0.0.1:5700\r\nConnection: close\r\n\r\n"
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1',5700))
client.send(payload.encode("utf-8"))
client.close() #错误
def error():
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1',5700))
rand = random.randint(1,4)
number = get_number()
if rand == 1:
msg = "我听不懂你在说什么哦"
elif rand == 2:
msg = "我好笨,听不懂呜呜呜"
elif rand == 3:
msg = "啊?发生了什么"
elif rand == 4:
msg = "干啥呢干啥呢"
payload = "GET /send_group_msg?group_id=" + str(number) + "&message=" + msg + " HTTP/1.1\r\nHost: 127.0.0.1:5700\r\nConnection: close\r\n\r\n"
client.send(payload.encode("utf-8"))
client.close() #发送猫猫图
,图片保存在本地
def send_cat_pic():
global flag
flag = 1
cat_list = os.listdir("/data/catpic")
all_message['raw_message'] = "[CQ:image,file=file:///data/catpic/"+ random.choice(cat_list)+"]"
client_to_conn() #发送setu,图片从API内获取
def send_setu_pic():
apikey = '×××××××××××××××'
req_url="https://api.lolicon.app/setu/"
params = {"apikey":apikey}
res=requests.get(req_url,params=params)
setu_url=res.json()['data'][0]['url']
all_message['raw_message'] ="[CQ:image,file="+setu_url+"]"
client_to_conn()

私聊机器人学习数据:

#调教机器人
#这块代码也有点bug,需要后期调整。
def training_message():
s = get_raw_message()
if s.split(' ')[0] != '学习':
return
s2 = s.split(' ')[1]
s3 = s.split(' ')[2]
s = s2 + ' ' + s3
fp = open("/机器人/txt.txt", "a",encoding='utf-8')
fp.write('\n')
fp.write(s)
fp.close()
client_to_conn()

获取数据的第一时间判断信息内容:

#首次判断信息内容
def first_judgement():
if get_message_type() == 'private':
training_message()
if get_raw_message() == '[CQ:at,qq=×××××××××] help':
help_interface()
return
if get_raw_message() == '[CQ:at,qq=×××××××××] setu':
send_setu()
return
elif get_raw_message() == '[CQ:at,qq=×××××××××] 猫猫图':
send_cat_pic()
return
elif len(get_raw_message()) < 20: #即使不@,也有15%概率回复信息
rand = random.randint(1,20)
if rand <= 3:
global flag
flag = 2
all_message['raw_message'] = '[CQ:at,qq=×××××××××] ' + all_message['raw_message']
client_to_conn()
else:
return
elif get_raw_message()[0:20] != '[CQ:at,qq=×××××××××]':
return
client_to_conn()

循环部分:

#flag为全局变量
#flag = 0 正常
#flag = 1 数据不通过数据库
#flag = 2 退出
#使用try、except语句保证程序不会因部分错误退出。
while 1:
global flag
flag = 0
all_message = rev_msg()
#print(all_message)
try:
first_judgement()
except:
continue

示例



支持收发文本、图片、表情等等。

利用api获取setu。

最终项目可搭载在服务器上不间断运行,目前只实现了基本功能,还有许多功能有待开发,欢迎大佬们来找我一起交流学习。

基于go-cqhttp实现QQ机器人的更多相关文章

  1. 基于WebQQ3.0协议写一个QQ机器人

    最近公司需要做个qq机器人获取qq好友列表,并且能够自动向选定的qq好友定时发送消息.没有头绪,硬着头皮上 甘甜的心情瞬间变得苦涩了 哇 多捞吆 1.WEBQQ3.0登陆协议 进入WEBQQ, htt ...

  2. 体验 QQ机器人C# SDK 1.X 特性总结

    主要特性 依赖注入 框架本身采用 Autofac 作为依赖注入框架.进行插件开发时,必然会使用到该框架.建议开发者阅读官方文档熟悉其用法.https://autofac.readthedocs.io/ ...

  3. 使用C# 开始第一个QQ机器人

    本示例将会使用”嘤鹉学舌”这个小插件的实现来演示如何使用Newbe.Mahua实现第一个机器人插件. 插件功能 自动将发送者的消息回发给发送人,嘤鹉(Parrot,其实是说嘤嘤嘤怪)学舌. 开发环境要 ...

  4. python实现qq机器人qqbot

    title: python实现qq机器人qqbot tags: python date: 2018-6-1 10:19:00 --- 以下内容为转载 一.介绍 qqbot 是一个用 python 实现 ...

  5. NoneBot+酷Q,打造QQ机器人

    NoneBot 是一个基于 酷Q 的 Python 异步 QQ 机器人框架,它会对 QQ 机器人收到的消息进行解析和处理,并以插件化的形式,分发给消息所对应的命令处理器和自然语言处理器,来完成具体的功 ...

  6. Ubuntu16.04安装QQ机器人

    Ubuntu安装QQ机器人 看了看现在QQ机器人似乎只有酷Q机器人有Docker可以在linux上运行了 那就k开始装酷Q机器人,资源占用也不是很大,大概占用180M内存吧 安装酷Q HTTP 首先安 ...

  7. Python+mirai开发QQ机器人起步教程(2021.9.9测试有效)

    参考:开发 mirai QQ机器人起步教程_叹之-CSDN博客_mirai python 本篇文章参考了以上博客,并对其中的失效内容和版本匹配问题进行了补充修改,实测能够成功运行.部分步骤的运行截图见 ...

  8. 实现QQ机器人报警

    如题,废话不说,直接上代码.首先是登录QQ的小脚本 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 ...

  9. Python3实现QQ机器人自动爬取百度文库的搜索结果并发送给好友(主要是爬虫)

    一.效果如下: 二.运行环境: win10系统:python3:PyCharm 三.QQ机器人用的是qqbot模块 用pip安装命令是: pip install qqbot (前提需要有request ...

随机推荐

  1. DataTable添加checkbox实现表格数据全选,单选(点选)

    Datatables是一款jquery表格插件.它是一个高度灵活的工具,可以将任何HTML表格添加高级的交互功能. 分页,即时搜索和排序 几乎支持任何数据源:DOM, javascript, Ajax ...

  2. webform中Repeater中调用后台方法

    前台 <%#RoleNameSpan(Eval("RoleName").ToString())%> 后台 /// <summary> /// 角色名称过长处 ...

  3. Blogs实现顶部的欢迎信息

    简单,就直接上代码: <div style="text-align: center; font-size:20px; margin-bottom:0px; margin-top:0px ...

  4. CentOS 8 安装Nginx

    安装命令: dnf install nginx -y 这就安装完成了 ,对你没看错一个命令就已经把nginx安装好了,不信你通过 nginx -V 命令查看. 常用操作: 1.nginx配置文件目录 ...

  5. Vue 面试题总结

    1. Vue 框架的优点是什么? (1)轻量级框架:只关注视图层,大小只有几十Kb:     (2)简单易学:文档通顺清晰,语法简单:     (3)数据双向绑定,数据视图结构分离,仅需操作数据即可完 ...

  6. 通过关闭线程底层资源关闭类似synchronized及IO阻塞的情况

    public class IoBlocked implements Runnable { private InputStream in; public IoBlocked(InputStream in ...

  7. 【转载】VUE的背景图引入

    我现在的项目要将登录页面的背景引一图片做为背景图片,按原jsp中的写法,发现无法找到背景图片,最后从网上查资料,采用上面的写法,成功显示出背景图片,参考网址 https://blog.csdn.net ...

  8. 数据仓库组件:Hive环境搭建和基础用法

    本文源码:GitHub || GitEE 一.Hive基础简介 1.基础描述 Hive是基于Hadoop的一个数据仓库工具,用来进行数据提取.转化.加载,是一个可以对Hadoop中的大规模存储的数据进 ...

  9. 【机制】JavaScript的原型、原型链、继承

    1.原型和原型链的概念 js在创建一个对象时,比如叫 obj,都会给他偷偷的加上一个引用,这个引用指向的是一个对象,比如叫 yuanxing, 这个对象可以给引用它的对象提供属性共享,比如:yuanx ...

  10. 短信平台开发,G客短信系统功能介绍

    G客短信群发平台功能介绍 支持HTTP 接口 .CMPP SMPP等 这里只有基本功能介绍 联系微信:290615413 QQ:290615413 一:客户端功能 1:首页仪表盘 首页包含 2:发送短 ...