基于MiraiBot的开发(自定义回复图片)

MiraiBot 简介

不写了

功能差异

这部分属于前篇自定义消息中的拓展开发,自定义回复图片内容。之前是回复的消息都是简单的文本消息,可以从单个MessageChain中获取到完成的key和value属性,同时在发送消息的时候可以直接发送简单文本。
而自定义图片的区别的在于,文本消息和图片消息在两个顺序的MessageChain中,并且在发送消息的时候需要去构建的Image类型的消息。难点构建一个完整的Image消息。

功能实现

修改mgs的获取方式

前篇中我们使用了message.contentToString()来简单的获取文本消息,在Message.kt的源码中写出了方法的介绍转为接近官方格式的字符串, 即 "内容".也就是说转化之后的msg,在接受到每一张图片都是“图片”文本字符。为了获取到详细的图片的信息,我们这里需要使用message.toString()来取得最原始的消息信息。Message中包含了MessageMetadata 消息元数据 和 MessageContent 含内容的消息。这里我们暂时不用消息元数据,需要过滤掉。获得完整的含内容的消息。

message01

1
2
3
4
5
6
var messageContent = ""
for (i in 1..message.size - 1)
{
messageContent += message[i].toString()
}
val msg = messageContent

回复自定义图片内容

按照2.15.0-M1版本来看,储存到数据库的图片消息应该是“[mirai:image:{BD4394DD-E387-7E36-E0CD-E24F4A0403E1}.jpg, width=453, height=560, size=112256, type=JPG, isEmoji=false]”这个内容。
若是普通的jpg或者png格式的静态图片,使用图片ID,通过Image.fromId(“{BD4394DD-E387-7E36-E0CD-E24F4A0403E1}.jpg”),即可以构造简单的图片消息;
但是在测试的时候,发现动态的gif图片,Image.fromId() 构建后发送,图片就不动了。所有使用另一种图片的构建方式:InternalImageProtocol.instance.createImage()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@OptIn(MiraiInternalApi::class) //方法上添加注解,IDEA会提示

//done 实现回复自定义图片
if (customizeMessage.contains("mirai:image"))
{
//构建图片 原数据[mirai:image:{BD4394DD-E387-7E36-E0CD-E24F4A0403E1}.jpg, width=453, height=560, size=112256, type=JPG, isEmoji=false]
//解析过程有点抽象,建议封装
val map: MutableMap<String,String> = mutableMapOf()
val split = customizeMessage.split(", ".toRegex())
map["imageId"] = split[0].substring(13,split[0].length)
Arrays.stream(split.dropLastWhile { it.isEmpty() }.toTypedArray())
.filter { kv: String -> kv.contains("=") }
.map { kv: String -> kv.split("=".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() }
.forEach{ array: Array<String> -> map[array[0]] = array[1] }
val image = InternalImageProtocol.instance.createImage(map["imageId"].toString(),map["size"].toString().toLong(),ImageType.match(map["type"].toString()),map["width"].toString().toInt(),map["height"].toString().toInt(),false)
this.group.sendMessage(image)
}
else {
this.group.sendMessage(customizeMessage)
}

若是简单的发送静态图片,可以试试下面比较简单方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
//done 实现回复自定义图片
if (customizeMessage.contains("mirai:image"))
{
//构建图片 原数据[mirai:image:{BD4394DD-E387-7E36-E0CD-E24F4A0403E1}.jpg, width=453, height=560, size=112256, type=JPG, isEmoji=false]
//只需要获取到图片ID
val map: MutableMap<String,String> = mutableMapOf()
val split = customizeMessage.split(", ".toRegex())
val image = Image.fromId(split[0].substring(13,split[0].length))
this.group.sendMessage(image)
}
else {
this.group.sendMessage(customizeMessage)
}

结语

把之前挖的肯填上了,用户的权限和积分系统还在摸鱼,摸不出来啊,总觉得写法很笨拙,也没有这方面经验,恼火。总想着用注解来写。