python+go-cqhttp搭建QQ机器人

最近项目上了活动,流量比较大,运营需要时刻监控流量来控制活动内容,本来想开发一个微信机器人,然而github上微信机器人的开源项目都对微信版本有要求,可移植性差(没跑起来),转而开发QQ机器人。

I.基于go-cqhttp

1. 配置

go-cqhttp官方文档
使用版本:v1.0.0-rc1
根据官方文档修改config.yml,第一次运行go-cqhttp会自动创建。
做一个简单的自动回复消息的机器人只需要考虑如下地方:

account: # 账号相关
  uin: 123456 # QQ账号
  password: 123123 # 密码为空时使用扫码登录

servers:
  # HTTP 通信设置
  - http:
  	host: 127.0.0.1 # 服务端监听地址
  	port: 5700      # 服务端监听端口
  	……
  	post: # 反向HTTP POST地址列表
  		- url: http://127.0.0.1:5701/ # 地址

反向post地址和端口号按需修改。

2. 启动go-cqhttp:

windows系统下直接运行go-cqhttp.bat即可。
linux系统下使用nohup ./go-cqhttp & 命令执行后台运行。

II.功能实现

消息发送的host:port取决于config.yml中配置的服务端监听地址和服务端监听端口。

1.定时任务主动推送消息

一个简单的示例:

# coding = utf-8
import os
import json
import Model_mysql as mySql
import httpx

def start():
    project_array = load_config("db_config.json")  # 自定义获取数据库列表的方法
    contact_array = load_config("contact.json")  # 自定义获取联系人列表的方法
    data = load_data(project_array )  # 自定义从数据库获取数据的方法
    for data_obj in data :
      for contact_obj in contact_array:
         host = "http://127.0.0.1:5700/send_private_msg?user_id=%s&message=%s" % (contact_obj, data_obj)
         httpx.get(host)  # 将每份数据发送给每个联系人

start()

2.自动回复(接受并处理指令)

go-cqhttp如果在config.yml中配置了反向HTTP POST地址,就会在收到消息时把消息post到指定地址,我们可以通过socket来接收消息并处理。下面是一个简单的例子:

import socket
import json
import threading
import requests


def do(conn):
    try:
    	# socket持续监听,无需断开连接
    	# 低性能主机长时间保持长连接会导致CPU占用居高不下
    	# 比如我的J4125运行6小时以后CPU占用率会到90%
    	# 解决办法:在config.yml中关闭心跳,socket.recv()方法默认阻塞,没有消息的时候死循环会阻塞减少CPU占用
        while True:
            # 设置获取的字节串最大长度
            b: bytes = conn.recv(1024 * 10)
            buf = b.decode("utf-8")
            if len(buf) != 0:
                # 接收数据,格式化http的报文
                http_data = receive_data(buf)
                # 返回响应,如果不返回响应 go-cqhttp会一直报错
                # [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.
                conn.sendall(bytes(response_success(), encoding="utf-8"))
                # 处理数据
                if data and data != "":
                    handle_data(data)
    except Exception as e:
        print(e)
    conn.close()


def response_success():
    return "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n{result:success}\r\n"


def receive_data(raw: str):
    try:
        # 正则表达式匹配报文内容
        data_re = re.search(r"{(.|\s)*}", raw, re.S)
        if data_re:
            data_str = str(data_re.group())
            return data_str
    except Exception as e:
        print(e)
        print("错误位置:%s" % e.__traceback__.tb_lineno)


def handle_data(data):
    if data_str.find("heartbeat") != -1:
        # 心跳
        pass
    else:
    	# 自定义机器人指令逻辑
    	pass
	


print("Server is starting")
port = 5701 # 
max_connection = 5
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('127.0.0.1', port))  # 配置socket,绑定IP地址和端口号,同config.yml中配置的反向HTTP POST地址和端口
sock.listen(max_connection)  # 设置最大允许连接数,各连接和server的通信遵循FIFO原则
print("Server is listening port %s , with max connection %s" % (port, max_connection))
while True:
    connection, address = sock.accept()
    # 获得一个连接,然后开始循环处理这个连接发送的信息
    # 使用多线程处理
    threading.Thread(target=do, args=[connection, ]).start()

运行这个python无限循环监听socket即可。

附:添加到系统计划任务

由于需要每小时都推送一次消息,在python代码里面写一个休眠1小时执行1次的循环实在是不优雅,把定时循环的功能交给系统就行了。

1. windows

右键此电脑-管理-任务计划程序-任务计划程序库,就在任务计划程序库中创建任务。
任务计划程序库界面右边选择创建任务
在这里插入图片描述
名称和描述随便填写即可。
在这里插入图片描述

触发器里面选择新建,我这个任务需要每天每小时触发,所以设置里面选择每天,开始时间设置为下一次需要触发的时间,比如说现在时间是21:10,下次应该是22:00,那么开始时间就写22:00,我曾经试过开始时间在当前时间以前,然后勾选上如果过了计划开始时间,立即启动任务,然而任务并没有启动╮(╯▽╰)╭

在这里插入图片描述
操作里面也选择新建,设置中程序或者脚本要选择python的启动器,就是python安装目录下的那个python.exe文件,添加参数填入要运行的py文件绝对路径(如果你的Python脚本中使用了相对路径,那么需要把这个Python脚本所在目录填到起始于,不然运行python脚本时会找不到相对路径的文件。)。然后点确定保存退出即可。

2. Linux

使用crontab添加计划任务即可。
具体可以参考我的另一篇文章:服务器设置定时任务使用python爬取网页

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值