使用go-cqhttp搭建qq机器人

Azazel-gh3 / 2023-05-13 / 原文

使用go-cqhttp搭建qq机器人--python处理消息

1.环境部署

  • 本次使用windows测试部署
  • 下载地址:https://github.com/Mrs4s/go-cqhttp/releases

  • 下载后解压,会有三个文件,点击运行exe

  • 生成bat文件,再运行

  • 运行bat,填入0,然后生成配置文件config.yml;填入qq号和密码(不过填入密码,一直登陆失败,最后还是选择扫码登陆)

  • 取消倒数三四排的代码注释,开启监听端口api,方便后续操作

  • 打开device.json文件,修改protocol的值为2,否则一直登陆失败

  • 最后再次点击bat文件运行,扫码登陆;显示如下就表示登陆成功以及cqhttp接管qq成功

2.python代码

  • receive.py文件负责监听socket(端口要和上面配置文件中的端口一致),接收由cqhttp传来的消息;

    import socket
    import json
    
    ListenSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    ListenSocket.bind(('127.0.0.1', 5701))
    ListenSocket.listen(100)
    HttpResponseHeader = '''HTTP/1.1 200 OK\r\n
    Content-Type: text/html\r\n\r\n
    '''
    
    
    def request_to_json(msg):
        for i in range(len(msg)):
            if msg[i] == "{" and msg[-1] == "\n":
                return json.loads(msg[i:])
        return None
    
    
    # 需要循环执行,返回值为json格式
    def rev_msg():  # json or None
        Client, Address = ListenSocket.accept()
        Request = Client.recv(1024).decode(encoding='utf-8')
        rev_json = request_to_json(Request)
        Client.sendall((HttpResponseHeader).encode(encoding='utf-8'))
        Client.close()
        return rev_json
    
    
  • send_msg.py;python后端处理消息后返回的消息由该文件发出

    import socket
    
    port = 5700
    
    
    def send_msg(resp_dict):
        client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
        ip = '127.0.0.1'
        client.connect((ip, port))
    
        msg_type = resp_dict['msg_type']  # 回复类型(群聊/私聊)
        number = resp_dict['number']  # 回复账号(群号/好友号)
        msg = resp_dict['msg']  # 要回复的消息
    
        # 将字符中的特殊字符进行url编码
        msg = msg.replace(" ", "%20")
        msg = msg.replace("\n", "%0a")
    
        if msg_type == 'group':
            payload = "GET /send_group_msg?group_id=" + str(
                number) + "&message=" + msg + " HTTP/1.1\r\nHost:" + ip + f":{port}\r\nConnection: close\r\n\r\n"
        elif msg_type == 'private':
            payload = "GET /send_private_msg?user_id=" + str(
                number) + "&message=" + msg + " HTTP/1.1\r\nHost:" + ip + f":{port}\r\nConnection: close\r\n\r\n"
        print("发送" + payload)
        client.send(payload.encode("utf-8"))
        client.close()
        return 0
    
  • bot.py最关键的文件,负责写一些逻辑,像接收到什么消息返回特点的消息

    import re
    
    from receive import rev_msg
    from send_msg import send_msg
    import socket
    import requests
    import random
    import urllib.request, json
    import other_api
    
    while True:
        try:
            rev = rev_msg()
            print(rev)
            if rev == None:
                continue
        except:
            continue
    
        if rev["post_type"] == "message":
            if rev["message_type"] == "private":  # 私聊
    
                if '在吗' in rev['raw_message']:
                    qq = rev['sender']['user_id']  # 获取消息发出者的qq号
                    send_msg({'msg_type': 'private', 'number': qq, 'msg': '我在'})  # 发送
    
    
    
            elif rev["message_type"] == "group":  # 群聊
                group = rev['group_id']
                if '在吗' in rev['raw_message']:
                    qq = rev['sender']['user_id']
                    send_msg({'msg_type': 'group', 'number': group, 'msg': '你好'})
            else:
                continue
        else:  # rev["post_type"]=="meta_event":
            continue
    
    
  • 记得将所有py文件放在同一目录,最后运行bot.py文件

  • 测试效果:

  • 一些测试代码:

    •                 elif '热搜' in rev['raw_message']:
                          qq = rev['sender']['user_id']
                          result = other_api.rs()
                          result_rs = ''
                          for i in range(15):
                              t = str(i + 1) + ":" + result[i] + "\n"
                              result_rs = result_rs + t
                          send_msg({'msg_type': 'group', 'number': group,
                                    'msg': result_rs})
      
      def rs():  # 微博热搜
          header = {
              "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/112.0",
              "Accept": "*/*",
              "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
              "Accept-Encoding": "gzip, deflate",
          }
          url = "https://tophub.today/n/KqndgxeLl9"
          res = requests.get(url, headers=header)
          selector = etree.HTML(res.text)
          result = []
          for i in range(30):
              t = selector.xpath(f"/html/body/div[1]/div[2]/div[2]/div[1]/div[2]/div/div[1]/table/tbody/tr[{i + 1}]/td[2]/a")
              result.append(t[0].text)
              # print(i+1, t[0].text)
          return result
      
      

      当@机器人并输入热搜时,会展示15天热搜新闻:

  • 搭建成功,后面就靠自己DIY了;

    • 免费API:ALAPI
    • 官方文档:https://docs.go-cqhttp.org/(有一些其他有趣的接口,可以尝试下)