MessageChain
消息链, List<SingleMessage>
, 即 单个消息元素 的有序集合.
MessageChain 代表一条完整的聊天中的消息, 可包含 带内容的消息 MessageContent
和 不带内容的元数据 MessageMetadata
.
元素类型
MessageContent 如 纯文字, 图片, 语音, 是能被用户看到的内容.
MessageMetadata 是用来形容这条消息的状态的数据, 因此称为 元数据 (metadata). 元数据目前只分为 消息来源 MessageSource
和 引用回复 QuoteReply
.
MessageSource 存储这条消息的发送人, 接收人, 识别 ID (服务器提供), 发送时间等信息. MessageSource 是精确的. 凭 MessageSource 就可以在服务器上定位一条消息, 因此可以用来 撤回消息.
QuoteReply 是一个标记, 表示这条消息引用了另一条消息 (在官方客户端中可通过 "回复" 功能发起引用). QuoteReply.source 则指代那条被引用的消息. 由于 MessageSource 是精确的, 如果对 QuoteReply.source 使用 MessageSource.recall, 则可以撤回那条被引用的消息.
获得消息链
在消息事件中可以获得消息内容作为 MessageChain: MessageEvent.message
在主动发送消息时, 可使用如下方案.
在 Kotlin 构造消息链
获取不包含任何元素的消息链: EmptyMessageChain
messageChainOf: 类似 listOf, 将多个 Message 构造为 MessageChain:
val chain = messageChainOf(PlainText("..."), Image("..."), ...)
buildMessageChain: 使用 DSL 构建器.
val chain = buildMessageChain {
+"你想要的图片是:"
+Image("...")
}
Message.plus: 将两个消息相连成为一个消息链:
val chain = PlainText("Hello ") + PlainText("Mirai!") // chain: MessageChain
toMessageChain 将 Iterable, Array, Sequence, Iterator, Flow, Stream 转换为 MessageChain. 相关定义为:
public fun Sequence<Message>.toMessageChain(): MessageChain
public fun Iterable<Message>.toMessageChain(): MessageChain
public fun Iterator<Message>.toMessageChain(): MessageChain
public fun Stream<Message>.toMessageChain(): MessageChain
public fun Flow<Message>.toMessageChain(): MessageChain
public fun Array<Message>.toMessageChain(): MessageChain
Message.toMessageChain 将单个 Message 包装成一个单元素的 MessageChain
在 Java 构造消息链
MessageUtils.newChain
: 有多个重载, 相关定义如下:
public static MessageChain newChain(Message messages...)
public static MessageChain newChain(Iterable<Message> iterable)
public static MessageChain newChain(Iterator<Message> iterator)
public static MessageChain newChain(Stream<Message> stream)
public static MessageChain newChain(Message[] array)
Message.plus: 将两个消息相连成为一个消息链:
MessageChain chain = new PlainText("Hello ").plus(new PlainText("Mirai!"))
MessageChainBuilder builder = MessageChainBuilder.create();
builder.append(new PlainText("Hello "));
builder.append(new PlainText(" Mirai!"));
MessageChain chain = builder.build();
元素唯一性
部分消息类型如 语音, 小程序 在官方客户端限制中只允许单独存在于一条消息. 在创建 MessageChain 时这种限制会被体现.
当添加只允许单独存在的消息元素到一个消息链时, 已有的元素可能会被删除或替换. 详见 AbstractPolymorphicMessageKey 和 ConstrainSingle.
操作消息链
MessageChain 继承 List<SingleMessage>
. 可以以 List 的方式处理 MessageChain.
额外地, 若要获取一个 ConstrainSingle 的元素, 可以通过 ConstrainSingle.key:
val quote = chain[QuoteReply] // Kotlin
QuoteReply quote = chain.get(QuoteReply.Key) // Java
相关地还可以使用 MessageChain.contains 和 MessageChain.getOrFail
直接索引访问
MessageChain 实现接口 List, 可以通过索引 get(index)
来访问. 由于 MessageChain 是稳定的, 这种访问操作也是稳定的.
但在处理来自服务器的 MessageChain 时, 请尽量避免这种直接索引访问. 来自服务器的消息的组成有可能会变化, 可能会有新的 MessageMetadata 加入. 例如用户发送了两条内容相同的消息, 但其中一条带有引用回复而另一条没有, 则两条消息的索引可能有变化 (当然内容顺序不会改变, 只是 QuoteReply 的位置有可能会变化). 因此在使用直接索引访问时要格外注意兼容性, 故不推荐这种访问方案.
撤回和引用
要撤回消息, 查看 MessageSource
MessageChain.quote
MessageChain.recall
MessageChain.recallIn
Kotlin 扩展
属性委托
val at: At? by chain.orNull()
val at: At by chain.orElse { /* 返回一个 At */}
val at: At by chain
筛选得到 Sequence 与 List
序列化
kotlinx-serialization 序列化
使用 MessageChain.serializeToJsonString 将 MessageChain 序列化为 JSON String.
使用 MessageChain.deserializeFromJsonString 将 JSON String 反序列化为 MessageChain.
Mirai Code 序列化
详见 MiraiCode
使用 MessageChain.serializeToMiraiCode 将 MessageChain 序列化为 Mirai Code String.
使用 MessageChain.deserializeFromMiraiCode 将 Mirai Code String 反序列化为 MessageChain.
Types
Functions
当存在 ConstrainSingle.key 为 key 的 SingleMessage 实例时返回 true
.
判断内容是否与 another 相等.
判断内容是否与 another 相等即 this
与 another 的 contentToString 相等.
判断内容是否与 another 相等即 this
与 another 的 contentToString 相等. strict 为 true
时, 还会额外判断每个消息元素的类型, 顺序和属性. 如 Image 会判断 Image.imageId
转为最接近官方格式的字符串. 如 At(member) + "test"
将转为 "@群名片 test"
.
将 this
和 tail 连接.
转换为 mirai 码.
Properties
Inheritors
Extensions
消息内部 ids.
获取 Sequence<MessageContent>
相当于 this.asSequence().filterIsInstance<MessageContent>()
解析形如 "mirai:" 的 mirai 码, 即 CodableMessage.serializeToMiraiCode 返回的内容.
获取第一个 M 实例. 在不存在时返回 null
.
获取第一个 M 实例. 在不存在时抛出 NoSuchElementException.
获取第一个 M 实例. 在不存在时返回 null
.
获取第一个类型为 key 的 Message 实例, 在找不到此类型的元素时抛出 NoSuchElementException
提供一个类型的值的委托. 若不存在则会抛出异常 NoSuchElementException
消息 ids.
消息内部 ids.
获取 Sequence<MessageMetadata>
相当于 this.asSequence().filterIsInstance<MessageMetadata>()
引用这条消息. 仅从服务器接收的消息 (即来自 MessageEvent) 才可以通过这个方式被引用.
撤回这条消息. 可撤回自己 2 分钟内发出的消息, 和任意时间的群成员的消息.
在一段时间后撤回这条消息.
将 MessageChain 序列化为 JSON 字符串.
将 MessageChain 序列化为指定格式的字符串.
获取这条消息的 消息源.
消息时间.