推荐使用QQ 机器人开发框架Mirai-js来快速开发,文档地址:开发文档。
前言
在完成配置开源安卓QQ协议库Mirai后,便可使用已有开源项目来部署自己的QQ机器人,但自行开发显然更符合需求。借助mirai-api-http插件提供的接口,可以很方便的开发机器人,开发语言根据自己的意愿选择即可,这里以PHP为例。
配置Mirai-Api-Http插件
mirai-api-http插件将mirai-core-api的所有功能封装为http服务,提供的HTTP接口供所有语言使用mirai,从而大大的降低了开发门槛,使得开发QQ机器人更加容易和灵活。
关于mirai-api-http在Mirai生态中的作用可以看官方的Mirai生态介绍文档,文档详细介绍了Mirai的生态中各个框架和应用的关系,相信读完后会对Mirai生态有更为清晰的了解。
接下来配置mirai-api-http插件
如使用Mirai Console Loader启动mirai的话,可直接在mirai所在根目录执行
./mcl –update-package net.mamoe:mirai-api-http –channel stable –type plugin
注意!以上方法下载的mirai-api-http插件为最新版2.x,2.x的api有所改动,本文章仅适合1.x版本,需手动下载!!!
请在Releases页面使用1.x的最新版,下载mirai-api-http-v1.xx.x.mirai.jar放入’pulgins’文件夹内。
如果已经使用了以上方法下载了2.x版本,请输入以下命令卸载:
1
| .\mcl --remove-package net.mamoe:mirai-api-http
|
将1.x版本的’mirai-api-http’放入’pulgins’文件夹后输入./mcl
启动mirai,启动完成后会在”config/net.mamoe.mirai-api-http”目录下生成配置文件”setting.yml”,此时输入stop
停止mirai,编辑该配置文件
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| # CORS跨域域名配置,默认允许所有域名 cors: - '*' # 地址,一般不需要改 host: 0.0.0.0 # 使用端口 port: 8080 # 认证Key authKey: xxxxxxxxxx # 缓存大小 cacheSize: 4096 # 是否开启websocket enableWebsocket: false # 消息上报配置 report: # 总开关 enable: true # 群消息上报 groupMessage: report: true # 好友消息上报 friendMessage: report: true # 临时消息上报 tempMessage: report: true # 事件上报 eventMessage: report: true # 上报URL destinations: - 'https://xxx.xxx.xxx' # 上报时的额外Header extraHeaders: xxxxxx: xxxxxx
## 心跳(即每隔一段时间上报消息表明插件工作状态) heartbeat: # 总开关 enable: false # 启动延迟 delay: 10 # 心跳间隔 period: 15 # 心跳上报URL destinations: [] # 上报时的额外信息 extraBody: {} # 上报时的额外头 extraHeaders: {}
|
注释中已包含对参数的说明,更详细的说明参考官方文档(2021-08-14更新:该文档是2.x版本的,与1.x版本的插件的配置有差异,参考以上配置即可)。其中”authKey”是与mirai-api-http接口认证的重要参数,”消息上报”是实现与QQ机器人互动的重要功能,”上报URL”是当消息上报时的上报地址,注意开放相应端口,配置完成后保存文件并重启mirai。
PHP实现QQ机器人
完成mirai-api-http插件配置后就能使用其提供的接口,通过向指定接口发送特定请求便能实现想要的操作,具体参考接口的详细文档(2021-08-14更新:该文档是2.x版本的,与1.x版本的插件有差异)。
使用PHP开发首先需要能运行PHP的环境(以下代码需要PHP7以上),这里不多赘述。然后在Web服务器监听目录下新建文件Bot.class.php,编辑该文件
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
| <?php
namespace Mirai;
use Exception;
/** * Mirai QQ机器人 * @property string $_url MiraiHTTP接口地址 * @property string $_authKey Mirai认证Key * @property string $_sessionKey Mirai会话Key */ class Bot { private $_url; private $_authKey; private $_sessionKey;
/** * 构造函数 * @param string $url MiraiHTTP接口地址 * @param string $authKey Mirai认证Key */ function __construct(string $url, string $authKey) { $this->_url = $url; $this->_authKey = array('authKey' => $authKey); }
/** * cURL获取数据 * @param string $url 发送请求的链接 * @param int $ifPost 是否为post请求(1||0) * @param mixed $postFields post的数据 * @param string $cookie 发送请求携带的cookie * @param mixed $cookieFile cookie文件 * @param int $ifHeader 是否获取响应头信息(1||0) * @throws Exception 请求失败 * @return mixed 响应结果 */ public function httpRequest(string $url, int $ifPost = 0, $postFields = '', string $cookie = '', $cookieFile = '', int $ifHeader = 0) { // 模拟http请求header头 $header = array( "Connection: Keep-Alive", "Accept: text/html, application/xhtml+xml, */*", "Pragma: no-cache", "Accept-Language: zh-Hans-CN,zh-Hans;q=0.8,en-US;q=0.5,en;q=0.3", "User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)" );
// 初始化一个cURL会话 $ch = curl_init();
// 设置cURL传输选项 curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, $ifHeader); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); $ifPost && curl_setopt($ch, CURLOPT_POST, $ifPost); $ifPost && curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); $cookie && curl_setopt($ch, CURLOPT_COOKIE, $cookie); // 发送cookie变量 $cookieFile && curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieFile); // 发送cookie文件 $cookieFile && curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFile); // 写入cookie到文件 curl_setopt($ch, CURLOPT_TIMEOUT, 60); // 允许执行的最长秒数 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
// 执行cURL会话 $result = curl_exec($ch);
// 失败则抛出异常 if ($result === false) { throw new Exception('Sending request to ' . $url . ' failed!'); } // 关闭 cURL 会话 curl_close($ch);
// 释放$ch unset($ch);
return $result; }
/** * 进行认证 * @throws Exception 认证失败 * @return bool */ public function auth(): bool { $url = $this->_url . '/auth'; $postData = json_encode($this->_authKey); $response = json_decode($this->httpRequest($url, 1, $postData)); if ($response !== false && $response->code === 0) { $this->_sessionKey = $response->session; return true; } else { throw new Exception('Mirai authentication failed!'); } }
/** * 校验Session * @param int $qq Session将要绑定的Bot的qq号 * @throws Exception 校验Session失败 * @return bool */ public function verify(int $qq): bool { $url = $this->_url . '/verify'; $postData = json_encode( array( 'sessionKey' => $this->_sessionKey, 'qq' => $qq ) ); $response = json_decode($this->httpRequest($url, 1, $postData)); if ($response !== false && $response->code === 0) { return true; } else { throw new Exception('Validation session failed!' . 'The qq is ' . $qq . '.'); } }
/** * 释放Session * @param int $qq 与该Session绑定Bot的QQ号码 * @throws Exception 释放Session失败 * @return bool */ public function release(int $qq): bool { $url = $this->_url . '/release'; $postData = json_encode( array( 'sessionKey' => $this->_sessionKey, 'qq' => $qq ) ); $response = json_decode($this->httpRequest($url, 1, $postData)); if ($response !== false && $response->code === 0) { return true; } else { throw new Exception('Failed to release session! The qq is ' . $qq . '!'); } }
/** * 发送好友消息 * @param int $qq 发送消息目标好友的QQ号 * @param array $messageChain 消息链,消息对象构成的数组 * @param int $quote 回复消息的messageId * @throws Exception 发送好友消息失败 * @return int messageId 可引用进行回复 */ public function sendFriendMessage(int $qq, array $messageChain, $quote = null): int { $url = $this->_url . '/sendFriendMessage'; $postData = json_encode( array( 'sessionKey' => $this->_sessionKey, 'target' => $qq, 'quote' => $quote, 'messageChain' => $messageChain ) ); $response = json_decode($this->httpRequest($url, 1, $postData)); if ($response !== false && $response->code === 0) { return $response->messageId; } else { throw new Exception('Failed to send friend message to qq:' . $qq . '!'); } } }
|
该类的方法实现了mirai-api-http所提供功能的一部分,包括认证身份、校验Session、释放Session和发送好友消息。其中属性”_authKey”便是插件配置文件中的”authKey”,重要参数和功能已在注释中说明,编辑完成后保存文件。
在相同目录下新建文件index.php,编辑该文件
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 29 30 31 32 33 34 35 36 37 38 39 40
| <?php
namespace Mirai;
use Exception;
// 包含bot类 include_once("./Bot.class.php");
// 实例化一个bot $bot = new Bot('MiraiHTTPAPI地址', 'Mirai认证Key');
// 机器人QQ $botQQ = xxxxxxxxxx; // 消息链 $messageChain = array( array( 'type' => 'Plain', 'text' => 'HelloWorld!' ) ); // 发送消息的目标QQ $targetQQ = xxxxxxxxx;
try { // 进行认证 $bot->auth(); // 校验Session $bot->verify($botQQ); // 发送该消息 $bot->sendFriendMessage($targetQQ, $messageChain); // 释放Session $bot->release($botQQ); } catch (Exception $e) { // 输出错误信息 echo $e->getMessage().' At file:'.$e->getFile().' on line:'.$e->getLine().'.'; // 发生异常时记录日志 error_log($e->getMessage() . ' At file:' . $e->getFile() . ' on line:' . $e->getLine() . '.'); }
|
以上代码实例化了一个Bot并向指定QQ好友发送了消息”HelloWorld!”,其中重要参数已在注释中说明。替换其中的“接口地址、认证Key、机器人QQ、目标QQ“,然后访问一次该文件,即可向指定QQ好友发送消息”HelloWorld!”。
完成以上实例就已经可以根据自己的需求开发QQ机器人了,仔细阅读API文档根据需求开发即可(2021-08-14更新:该文档是2.x版本的,与1.x版本的插件有差异)。
聊天机器人实例
这是一个QQ(智能)聊天机器人的实例,为了控制文章篇幅,实例转到地址:QQ聊天机器人实例
相关资料
基于Mirai的QQ机器人方案
开发 mirai QQ机器人起步教程
mirai-api-http文档参考
Mirai 生态中各个框架和应用的关系
最后
新手上路,如有错误请多指教。