基于炸毛框架实现QQ机器人消息推送

基于炸毛框架实现QQ机器人消息推送

实现功能

主要实现类似于Qmsg或酷推这样的QQ消息同送功能,通过请求接口发送getpost请求,让机器人给指定的QQ发送消息,效果如下

上图中打马赛克部分就是QQ机器人的发送对象的QQ号,通过浏览器发送get请求之后,请求参数msg的值就会发送到指定的QQ号: 值得一提的是,不仅可以发送字符串内容,还可以发送CQ码,已实现的CQ码如下:

CQ 码 功能
[CQ:face] [QQ 表情]
[CQ:record] [语音]
[CQ:video] [短视频]
[CQ:at] [@某人]
[CQ:share] [链接分享]
[CQ:music] [音乐分享] [音乐自定义分享]
[CQ:reply] [回复]
[CQ:forward] [合并转发]
[CQ:node] [合并转发节点]
[CQ:xml] [XML 消息]
[CQ:json] [JSON 消息]

介绍

炸毛框架使用PHP编写,采用Swoole扩展为基础,主要面向API服务,聊天机器人(CQHTTP 对接),包含websockethttp 等监听和请求库,用户代码采用模块化处理,使用注解可以方便地编写各类功能。

框架主要用途为 HTTP 服务器,机器人搭建框架。尤其对于 QQ 机器人消息处理较为方便和全面,提供了众多会话机制和内部调用机制,可以以各种方式设计你自己的模块。

炸毛框架文档:https://docs-v2.zhamao.xin/

准备工作

部署环境

以下分享我的部署环境,不一定要和我一模一样

  • 服务器CentOs操作系统, LNMP环境
  • PHP版本为PHP-8.0

部署流程

  1. 安装PHP
  2. 安装 Swoolembstring 等需要的PHP扩展
  3. Composer拉取框架并运行
  4. 下载运行go-cqhttp插件
  5. 编写消息推送代码
  6. 调试运行

开始

安装PHP和swoole扩展

参考:炸毛框架官方文档

Debian、Ubuntu(一句话安装php和swoole)

apt-get update && apt-get install -y software-properties-common && \
add-apt-repository ppa:ondrej/php -y && \
apt-get update && \
apt-get install php php-dev php-mbstring gcc make openssl \
php-mbstring php-json php-curl php-mysql -y && \
apt-get install wget composer -y && \
wget https://github.com/swoole/swoole-src/archive/v4.5.0.tar.gz && \
tar -zxvf v4.5.0.tar.gz && \
cd swoole-src-4.5.0/ && \
phpize && ./configure --enable-openssl --enable-mysqlnd && make -j2 && make install && \
(echo "extension=swoole.so" >> $(php -i | grep "Loaded Configuration File" | awk '{print $5}'))

CentOS(需要 >= 7) 安装

rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
yum makecache fast
yum install php72w-devel.x86_64 php72w-mbstring.x86_64 php72w-pear.noarch gcc gcc-c++ openssl-devel -y
# 方法1: PECL 安装 Swoole
(sudo) pecl install swoole
# 方法2: 源码编译安装 Swoole (使用最新版,把版本号替换为最新版即可)
wget https://github.com/swoole/swoole-src/archive/v4.5.9.tar.gz
tar -zxvf v4.5.9.tar.gz
cd swoole-src-4.5.9
phpize
./configure --enable-openssl
make -j2
make install
# 添加 extension 到 php.ini 文件,这行是自动找到位置并写入到最后一行的命令
echo "extension=swoole.so" >> $(php -i | grep "Loaded Configuration File" | awk '{print $5}')

#其他发行版可自行 Google 或 Bing 查询安装方法

安装框架

composer create-project zhamao/framework-starter zhamao-app
cd zhamao-app/ # 这个是你可以自己定义的名称
vendor/bin/start server # 启动框架

启动后你会看到和下方类似的初始化内容,表明启动成功了:

[root@VM-8-15-centos bot]# vendor/bin/start server
host: 0.0.0.0       |   port: 20001
log_level: 2        |   version: 2.1.3
config: global.php  |   working_dir: /QQbot/bot
 ______
|__  / |__   __ _ _ __ ___   __ _  ___
  / /| '_ \ / _` | '_ ` _ \ / _` |/ _ \
 / /_| | | | (_| | | | | | | (_| | (_) |
/____|_| |_|\__,_|_| |_| |_|\__,_|\___/

[19:02:54] [I] Worker #0 启动中
[19:02:54] [S] Worker #0 已启动

安装机器人客户端

机器人客户端和框架相互独立的,只要选用机器人客户端是OneBot标准的,就可以和炸毛框架进行无缝对接。这里选用 go-cqhttp 。首先下载 go-cqhttp 对应平台的release文件,双击 exe 文件或者使用 ./go-cqhttp 启动,然后会生成默认配置文件并修改默认配置。 在默认的配置文件config.hjson中修改以下项,其他的默认不动:

"uin": 你的QQ号,
"password": "你的密码",
"ws_reverse_servers": [
    {
      "enabled": true,
      "reverse_url": "ws://127.0.0.1:20001/",
      "reverse_api_url": "",
      "reverse_event_url": "",
      "reverse_reconnect_interval": 3000
    }
  ],

填写的QQ号是你用来做机器人的QQ号,建议申请小号来用。其中 ws://127.0.0.1:20001/ 中的 127.0.0.1 和 20001 分别对应炸毛框架配置的 HOSTPORT。 更改完配置文件之后再次运行go-cqhttp,然后让你验证登录,跟着流程验证登录完成之后,就会成功登录机器人QQ:

登录成功之后,所在的控制台(如果正在运行的话)应该会输出类似下面的内容:

[15:26:34] [I] [#2] 机器人 你的QQ号 已连接!

表明机器人已成功连接到炸毛框架了!现在转到框架的模块源代码部分,目录是 src/Module/Example,文件是 Hello.php,这是默认的模块事例。里面有很多机器人的事例用法。这里不多介绍,详情请参考炸毛官方文档。

编写消息推送模块

目前机器人已经正确连接到框架,现在我们只需要编写消息推送模块,来实现通过发起post或get请求来实现QQ消息推送了。 接下来在/bot/src/Module目录下新建一个文件夹QQsend,并在该文件夹下新建一个Send.php文件,并在里面写入以下代码:

<?php

namespace Module\QQsend;

use ZM\Annotation\CQ\CQCommand;
use ZM\Annotation\CQ\CQMessage;
use ZM\Annotation\CQ\CQRequest;
use ZM\Annotation\Http\RequestMapping;
use ZM\API\CQ;
use ZM\API\ZMRobot;
use ZM\Console\Console;

/**
 * Class Send
 * @package Module\QQsend
 * @since 2.0
 */
class Send
{
    /**
     * 消息推送服务
     * @RequestMapping("/send/{qq}"),@RequestMapping(method={"GET","POST"})
     */
    public function send($param) {
        $bot = ZMRobot::get("你的机器人QQ号");
        $qq = $param["qq"];
        $method = ctx()->getRequest()->server['request_method'];
        $info = ctx()->getRequest();
        $return_info = [];
        $return_info['fd'] = $info->fd;

        $return_info['method'] = $info->server['request_method'];
        $return_info['method'] = $info->server['request_method'];
        $return_info['qq'] = $param["qq"];

        $return_info['time'] = $info->server['request_time'];
        if($method == "GET"){
            $bot->sendPrivateMsg($param["qq"],ctx()->getRequest()->get['msg'],true);
            $return_info['msg'] = ctx()->getRequest()->get['msg'];
            return json_encode($return_info);
        }else if($method == "POST"){
            $bot->sendPrivateMsg($param["qq"],ctx()->getRequest()->post['msg'],true);
            $return_info['msg'] = ctx()->getRequest()->post['msg'];
            return json_encode($return_info);
        }else{
            $bot->sendPrivateMsg($param["qq"],'错误!',true);
            return json_encode($return_info);
        }
    }
}

其中@RequestMapping("/send/{qq}")是定义的路由和参数,其中参数qq是机器人推送消息的目前QQ,此时保存文件并重启框架,现在按照以下格式发起请求,就会实现QQ消息推送服务了:

http://你的ip:20001/send/目标qq号/?msg=要发送的内容

post请求的话,以python为例:

import requests

url = "http://你的ip:20001/send/目标qq号/"
payload = {
    "msg":"要发送的内容"
}
res = requests.post(url,data=payload)

最后,你还可以绑定自己的域名并设置反代去掉后面跟着的端口号,这样就美观多了。

最后

这里只是做了一个简单的功能,更多玩法请参考官方文档。利用这个推送功能,可是实现很多有趣的玩法,比如说定时任务提醒,网站评论提醒,文章点赞提醒。 因为疫情原因,每天在学校都要进行健康打卡,上报自己的当天情况。但是每天在学校打卡提交的信息都是一模一样的,然后我写了个自动打卡程序,挂在服务器上运行,每天自动打卡,并用上了这个QQ推送功能,每天打卡后都会给我们推送当天的打卡情况: