博客和更新地址:PHP开发基于Mirai的QQ机器人
在完成配置开源安卓QQ协议库Mirai后,便可使用已有开源项目来部署自己的QQ机器人,但自行开发显然更符合需求。借助mirai-api-http插件提供的接口,可以很方便的开发机器人,开发语言根据自己的意愿选择即可,这里以PHP为例。
mirai-api-http插件将mirai-core-api的所有功能封装为http服务,提供的HTTP接口供所有语言使用mirai,从而大大的降低了开发门槛,使得开发QQ机器人更加容易和灵活。
关于mirai-api-http在Mirai生态中的作用可以看官方的Mirai生态介绍文档,文档详细介绍了Mirai的生态中各个框架和应用的关系,相信读完后会对Mirai生态有更为清晰的了解。
如使用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版本,请输入以下命令卸载:
.\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,编辑该配置文件
# 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: {}
注释中已包含对参数的说明,更详细的说明参考官方文档。其中"authKey"是与mirai-api-http接口认证的重要参数,"消息上报"是实现与QQ机器人互动的重要功能,"上报URL"是当消息上报时的上报地址,注意开放相应端口,配置完成后保存文件并重启mirai。
完成mirai-api-http插件配置后就能使用其提供的接口,通过向指定接口发送特定请求便能实现想要的操作,具体参考接口的详细文档。
使用PHP开发首先需要能运行PHP的环境(以下代码需要PHP7以上),这里不多赘述。然后在Web服务器监听目录下新建文件Bot.class.php,编辑该文件
_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,编辑该文件
'Plain',
'text' => 'HelloWorld!'
)
);
// 发送消息的目标QQ
$targetQQ = xxxxxxxxx;
try {
// 进行认证
$bot->auth();
// 校验Session
$bot->verify($botQQ);
// 发送该消息
$bot->sendFriendMessage($targetQQ, $message_chain);
// 释放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文档根据需求开发即可。
这是一个QQ(智能)聊天机器人的实例,为了控制文章篇幅,实例转到地址:QQ聊天机器人实例
基于Mirai的QQ机器人方案
开发 mirai QQ机器人起步教程
mirai-api-http文档参考
Mirai 生态中各个框架和应用的关系
新手上路,如有错误请多指教。