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 构造消息链

val chain = messageChainOf(PlainText("..."), Image("..."), ...)
val chain = buildMessageChain {
+"你想要的图片是:"
+Image("...")
}
val chain = PlainText("Hello ") + PlainText("Mirai!") // chain: 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

在 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)
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 时这种限制会被体现.

当添加只允许单独存在的消息元素到一个消息链时, 已有的元素可能会被删除或替换. 详见 AbstractPolymorphicMessageKeyConstrainSingle.

操作消息链

MessageChain 继承 List<SingleMessage>. 可以以 List 的方式处理 MessageChain.

额外地, 若要获取一个 ConstrainSingle 的元素, 可以通过 ConstrainSingle.key:

val quote = chain[QuoteReply] // Kotlin

QuoteReply quote = chain.get(QuoteReply.Key) // Java

相关地还可以使用 MessageChain.containsMessageChain.getOrFail

直接索引访问

MessageChain 实现接口 List, 可以通过索引 get(index) 来访问. 由于 MessageChain 是稳定的, 这种访问操作也是稳定的.

但在处理来自服务器的 MessageChain 时, 请尽量避免这种直接索引访问. 来自服务器的消息的组成有可能会变化, 可能会有新的 MessageMetadata 加入. 例如用户发送了两条内容相同的消息, 但其中一条带有引用回复而另一条没有, 则两条消息的索引可能有变化 (当然内容顺序不会改变, 只是 QuoteReply 的位置有可能会变化). 因此在使用直接索引访问时要格外注意兼容性, 故不推荐这种访问方案.

避免索引访问以提高性能

自 2.12 起, MessageChain 内部结构有性能优化. 该优化大幅降低元素数量多的 MessageChain 的连接的时间复杂度. 性能优化默认生效, 但若使用 get, subListListCollection 之外的方法时则会让该优化失效 (相比 2.12 以前不会丢失性能, 只是没有优化).

撤回和引用

要撤回消息, 查看 MessageSource

Kotlin 扩展

属性委托

val at: At? by chain.orNull()
val at: At by chain.orElse { /* 返回一个 At */}
val at: At by chain

筛选得到 SequenceList

序列化

kotlinx-serialization 序列化

Mirai Code 序列化

详见 MiraiCode

Inheritors

Types

Link copied to clipboard
object Companion
Link copied to clipboard
object Serializer : KSerializer<MessageChain>

MessageChain 作为 List<SingleMessage> 序列化. 使用 多态序列化.

Functions

Link copied to clipboard

this 中存在 M 的实例时返回 true.

Link copied to clipboard
Link copied to clipboard
abstract operator override fun contains(element: SingleMessage): Boolean

open operator fun <M : SingleMessage> contains(key: MessageKey<M>): Boolean

当存在 ConstrainSingle.keykeySingleMessage 实例时返回 true.

Link copied to clipboard
abstract override fun containsAll(elements: Collection<SingleMessage>): Boolean
Link copied to clipboard
open fun contentEquals(another: String, ignoreCase: Boolean = false): Boolean

判断内容是否与 another 相等.

open fun contentEquals(another: Message, ignoreCase: Boolean = false): Boolean

判断内容是否与 another 相等即 thisanothercontentToString 相等.

open fun contentEquals(another: Message, ignoreCase: Boolean = false, strict: Boolean = false): Boolean

判断内容是否与 another 相等即 thisanothercontentToString 相等.

Link copied to clipboard
Link copied to clipboard

获取 Sequence<MessageContent> 相当于 this.asSequence().filterIsInstance<MessageContent>()

Link copied to clipboard
abstract fun contentToString(): String

转为接近官方格式的字符串, 即 "内容". 如 At(member) + "test" 将转为 "@QQ test".

Link copied to clipboard

解析形如 "mirai:" 的 mirai 码, 即 CodableMessage.serializeToMiraiCode 返回的内容.

Link copied to clipboard

获取第一个 M 实例. 在不存在时返回 null.

Link copied to clipboard

获取第一个 M 实例. 在不存在时抛出 NoSuchElementException.

Link copied to clipboard

获取第一个 M 实例. 在不存在时返回 null.

Link copied to clipboard

thistail 连接.

Link copied to clipboard
abstract operator fun get(index: Int): SingleMessage

open operator fun <M : SingleMessage> get(key: MessageKey<M>): M?

获取第一个类型为 keyMessage 实例. 若不存在此实例, 返回 null.

Link copied to clipboard
inline fun <M : SingleMessage> MessageChain.getOrFail(key: MessageKey<M>, crossinline lazyMessage: (key: MessageKey<M>) -> String = { key.toString() }): M

获取第一个类型为 keyMessage 实例, 在找不到此类型的元素时抛出 NoSuchElementException

Link copied to clipboard
inline operator fun <T : SingleMessage> MessageChain.getValue(thisRef: Any?, property: KProperty<*>): T

提供一个类型的值的委托. 若不存在则会抛出异常 NoSuchElementException

Link copied to clipboard
abstract fun indexOf(element: SingleMessage): Int
Link copied to clipboard

当消息内容为空白时返回 true.

Link copied to clipboard

当消息内容为空时返回 true.

Link copied to clipboard
abstract override fun isEmpty(): Boolean
Link copied to clipboard
abstract operator override fun iterator(): Iterator<SingleMessage>
Link copied to clipboard
abstract fun lastIndexOf(element: SingleMessage): Int
Link copied to clipboard
Link copied to clipboard

获取 Sequence<MessageMetadata> 相当于 this.asSequence().filterIsInstance<MessageMetadata>()

Link copied to clipboard
inline fun <T : R, R : SingleMessage?> MessageChain.orElse(lazyDefault: () -> R): OrNullDelegate<R>

提供一个类型的 Message 的委托, 若不存在这个类型的 Message 则委托会提供 null

Link copied to clipboard

提供一个类型的 Message 的委托, 若不存在这个类型的 Message 则委托会提供 null

Link copied to clipboard
open operator fun plus(another: Array<out Message>): MessageChain

创建一个消息链, 将 another 连接到这个消息的尾部. 这不会改变本 Message, 而是会创建新的 MessageChain 实例. 返回的 MessageChain 实例的第一个元素为本 Message, 随后为按顺序的 another 中的元素.

open operator fun plus(another: CharSequence): MessageChain

创建一个消息链, 将 another 连接到这个消息的尾部. 这不会改变本 Message, 而是会创建新的 MessageChain 实例. 返回的 MessageChain 实例的第一个元素为本 Message, 随后为按顺序的 another 中的元素.

open operator fun plus(another: String): MessageChain

创建一个消息链, 将 another 连接到这个消息的尾部. 这不会改变本 Message, 而是会创建新的 MessageChain 实例. 返回的 MessageChain 实例的第一个元素为本 Message, 随后为按顺序的 another 中的元素.

@JvmName(name = "plusIterableString")
open operator fun plus(another: Iterable<String>): MessageChain

创建一个消息链, 将 another 连接到这个消息的尾部. 这不会改变本 Message, 而是会创建新的 MessageChain 实例. 返回的 MessageChain 实例的第一个元素为本 Message, 随后为按顺序的 another 中的元素.

open operator fun plus(another: Iterable<Message>): MessageChain

创建一个消息链, 将 another 连接到这个消息的尾部. 这不会改变本 Message, 而是会创建新的 MessageChain 实例. 返回的 MessageChain 实例的第一个元素为本 Message, 随后为按顺序的 another 中的元素.

open operator fun plus(another: Sequence<Message>): MessageChain

创建一个消息链, 将 another 连接到这个消息的尾部. 这不会改变本 Message, 而是会创建新的 MessageChain 实例. 返回的 MessageChain 实例的第一个元素为本 Message, 随后为按顺序的 another 中的元素.

open operator fun plus(another: Message): MessageChain

创建一个消息链, 将 another 连接到这个消息的尾部. 这不会改变本 Message, 而是会创建新的 MessageChain 实例. 返回的 MessageChain 实例的第一个元素为本 Message, 随后为按顺序的 another 中的元素.

open operator fun plus(another: MessageChain): MessageChain

创建一个消息链, 将 another 连接到这个消息的尾部. 这不会改变本 Message, 而是会创建新的 MessageChain 实例. 返回的 MessageChain 实例的第一个元素为本 Message, 随后为按顺序的 another 中的元素.

open operator fun plus(another: SingleMessage): MessageChain

创建一个消息链, 将 another 连接到这个消息的尾部. 这不会改变本 Message, 而是会创建新的 MessageChain 实例. 返回的 MessageChain 实例的第一个元素为本 Message, 随后为按顺序的 another 中的元素.

Link copied to clipboard
inline suspend operator fun Message.plus(another: Flow<Message>): MessageChain

another 按顺序连接到这个消息的尾部.

Link copied to clipboard

引用这条消息. 仅从服务器接收的消息 (即来自 MessageEvent) 才可以通过这个方式被引用.

Link copied to clipboard

Bot 身份撤回该消息. 可撤回自己 2 分钟内发出的消息, 和任意时间的群成员的消息.

Link copied to clipboard

在一段时间后撤回这条消息.

Link copied to clipboard
inline fun Message.repeat(count: Int): MessageChain

将此消息元素按顺序重复 count 次.

Link copied to clipboard
inline suspend fun <C : Contact> Message.sendTo(contact: C): MessageReceipt<C>

this 发送给指定联系人

Link copied to clipboard
fun MessageChain.serializeToJsonString(json: Json = getDefaultJson()): String

MessageChain 序列化为 JSON 字符串.

Link copied to clipboard

转换为 mirai 码.

Link copied to clipboard
@ExperimentalSerializationApi
fun MessageChain.serializeToString(format: StringFormat): String

MessageChain 序列化为指定格式的字符串.

Link copied to clipboard
abstract fun subList(fromIndex: Int, toIndex: Int): List<SingleMessage>
Link copied to clipboard
inline operator fun Message.times(count: Int): MessageChain

将此消息元素按顺序重复 count 次.

Link copied to clipboard
fun Message.toForwardMessage(sender: User, time: Int = currentTimeSeconds().toInt(), displayStrategy: ForwardMessage.DisplayStrategy = DisplayStrategy): ForwardMessage
fun Message.toForwardMessage(senderId: Long, senderName: String, time: Int = currentTimeSeconds().toInt(), displayStrategy: ForwardMessage.DisplayStrategy = DisplayStrategy): ForwardMessage

转换为 ForwardMessage

Link copied to clipboard
@JvmName(name = "newChain")
inline fun Iterable<Message>.toMessageChain(): MessageChain

扁平化 this 并创建一个 MessageChain.

@JvmName(name = "newChain")
fun Message.toMessageChain(): MessageChain
Link copied to clipboard
abstract override fun toString(): String

得到包含 mirai 消息元素代码的, 易读的字符串. 如 At(member) + "test" 将转为 "[mirai:at:qqId]test".

Properties

Link copied to clipboard

消息内部 ids.

Link copied to clipboard
Link copied to clipboard

消息 ids.

Link copied to clipboard

消息内部 ids.

Link copied to clipboard
abstract override val size: Int
Link copied to clipboard

获取这条消息的 消息源.

Link copied to clipboard

获取这条消息的 消息源.

Link copied to clipboard

消息时间.