# 消息处理工具类 - MessageUtil

类定义:\ZM\Utils\MessageUtil

2.3.0 版本起可用。

这里放置一些机器人聊天消息处理的便捷静态方法,例如下载图片等。

# 方法

# downloadCQImage()

下载用户消息中所带的所有图片,并返回文件路径。

定义:downloadCQImage($msg, $path = null)

参数 $msg 为带图片的用户消息,例如 你好啊!\n[CQ:image,file=a.jpg,url=https://zhamao.xin/file/hello.jpg]

参数 $path 为图片下载的路径,如果不填(默认 null)则指定为 zm_data/images/ 目录,且不存在会自动创建。

$r = MessageUtil::downloadCQImage("你好啊!\n[CQ:image,file=a.jpg,url=https://zhamao.xin/file/hello.jpg]");
/*
$r == [
    "/path-to/zhamao-framework/zm_data/images/a.jpg"
];
*/
1
2
3
4
5
6

如果返回的是空数组 [ ],则表明消息中没有图片。如果返回的是 false,则表明其中至少一张下载失败或路径有误。

# containsImage()

检查消息中是否含有图片。

定义:containsImage($msg)

返回:bool,你懂的,true 就是有,false 就没有。

MessageUtil::containsImage("[CQ:image,file=a.jpg,url=http://xxx]"); // true
MessageUtil::containsImage("[CQ:face,id=140] 咦,这是一条带表情的消息"); // false
1
2

# isAtMe()

检查消息中是否含有@bot的消息。

定义:isAtMe($msg, $me_id)

参数 $me_id 为Bot的QQ号。

返回:bool,true 就是有,false 就没有。

MessageUtil::isAtMe("[CQ:at,qq=123456]炸毛你好","123456"); // true
MessageUtil::isAtMe("[CQ:at,qq=123456789]另一个朋友你好","123456"); // false
1
2

# getImageCQFromLocal()

通过文件路径获取图片的发送 CQ 码。

定义:getImageCQFromLocal($file, $type = 0)

参数 $file 为图片的绝对路径。

返回:图片的 CQ 码,如 [CQ:image,file=xxxxx]

参数 $type

  • 0:以 base64 的方式发送图片,返回结果如 [CQ:image,file=base64://xxxxxx]
  • 1:以 file:// 本地文件的方式发送图片,返回结果如 [CQ:image,file=file:///path-to/images/a.jpg]
  • 2:返回图片的 http:// CQ 码(默认为 /images/ 路径就是文件对应所在的目录),如 [CQ:image,file=http://127.0.0.1:20001/images/a.jpg]

# splitCommand()

切割用户消息为数组形式(@CQCommand 就是使用此方式切割的)

定义:splitCommand($msg): array

返回:数组,切分后的。

为什么不直接使用 explode 呢

因为 explode() 只会简单粗暴的切割字符串,假设用户输入的消息中两个词中间有多个空格,则会有空的词出现。例如 你好 我是一个长空格。此函数会将多个空格当作一个空格来对待。

MessageUtil::splitCommand("你好 我是傻瓜\n我是傻瓜二号"); // ["你好","我是傻瓜","我是傻瓜二号"]
MessageUtil::splitCommand("我有   三个空格"); // ["我有","三个空格"]
1
2

# matchCommand()

匹配一条消息到 @CQCommand 规则的注解事件,返回要执行的类和函数位置。

定义:matchCommand($msg, $obj)

参数 $msg 为消息内容。

参数 $obj 为事件的对象,可使用 ctx()->getData() 获取原先的事件体(仅限 OneBot 消息类型事件中使用)

返回:\ZM\Entity\MatchObject 对象,含有匹配成功与否,匹配到的注解对象,匹配到的分割词等,见 []

# addShortCommand()

快速添加一条静态消息回复命令。

定义:addShortCommand($command, string $reply)

参数 $command 为问的内容,如 炸毛不聪明

参数 $reply 为回复的内容,如 其实还是很聪明的!

这个命令推荐在 @OnStart 注解下使用,可以用这个来做一个动态的词库,从文件加载后使用。

/**
 * @OnStart()
 */
public function onStart() {
    MessageUtil::addShortCommand("炸毛不聪明", "其实还是很聪明的!");
}
1
2
3
4
5
6
炸毛不聪明
其实还是很聪明的!

# strToArray()

string 类型的消息文本转换为 array 格式。

定义:strToArray($msg, bool $ignore_space = true, bool $trim_text = false)

参数 $msg 为带 OB/CQ 码的字符串消息,如 你好啊,[CQ:at,qq=123]

参数 $ignore_spacefalse 时,转换的数组内会包含空 text 段。

参数 $trim_texttrue 时,会自动去除 text 段消息头尾的换行符和空格。

这个命令转换的数组格式符合 OneBot 11/12 标准,但细节上可能会与不同 OneBot 实现有所差异。

$str = "你好啊,[CQ:at,qq=123]";
$arr = \ZM\Utils\MessageUtil::strToArray($str);
1
2

转换结果参考如下:

[
    {
        "type": "text",
        "data": {
            "text": "你好啊,"
        }
    },
    {
        "type": "at",
        "data": {
            "qq": "123"
        }
    }
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# arrayToStr()

array 格式的消息内容转换为字符串 + CQ 码的形式。

定义:arrayToStr(array $array)

// 我们使用上边的 $arr 作为传入值。
$new_str = \ZM\Utils\MessageUtil::arrayToStr($arr);
// 结果:"你好啊,[CQ:at,qq=123]"
1
2
3