MessageScope
表示几个消息对象的 '域', 即消息对象的集合. 用于最小化将同一条消息发送给多个类型不同的目标的付出.
支持的消息对象类型
Contact, CommandSender, MessageScope (递归).
在下文, A
或 B
指代这三种类型的其中两种, 允许排列组合. 如 A.scopeWith(B)
可能表示 Contact.scopeWith(MessageScope)
.
获得 MessageScope
A.asMessageScope()
.C<A>.toMessageScope()
. 其中C
表示Iterable
,Sequence
,Flow
,Array
其中任一.
连接 MessageScope
A?.scopeWith(vararg B?)
.A?.scopeWith(vararg A?)
.
null
项将会被过滤.
自动去重
在连接时, MessageScope 会自动根据真实的 收信对象 去重.
如 member.asCommandSender().scopeWith(member.group)
, 返回的 MessageScope 实际上只包含 member.group
. 因为 member.asCommandSender()
的最终收信对象就是 member.group
.
因此在使用 scopeWith 时, 无需考虑重复性, 只需要把希望发送的目标全部列入.
使用 MessageScope
在 scopeWith
或 scopeWithNotNull
后加 lambda
参数即可表示使用 MessageScope. 如:
A.scopeWith(B) { // this: MessageScope
sendMessage(...)
}
典例
在处理指令时, 目标群对象可能与发件人群对象不同, 如用户在 A 群发指令, 以禁言 B 群的成员. 此时机器人可能需要同时广播通知到 A 群和 B 群.
由于 CommandSender 与 Contact 无公共接口, 无法使用 listOfNotNull 遍历处理. MessageScope 就是设计为解决这样的问题.
Kotlin
// 在一个 SimpleCommand 内
@Handler
suspend fun CommandSender.handle(target: Member) {
val duration = Random.nextInt(1, 15)
target.mute(duration)
// 不使用 MessageScope
val thisGroup = this.getGroupOrNull()
val message = "${this.name} 禁言 ${target.nameCardOrNick} $duration 秒"
if (target.group != thisGroup) {
target.group.sendMessage(message)
}
sendMessage(message)
// 使用 MessageScope
// 表示至少发送给 `this`, 当 `this` 的真实发信对象与 `target.group` 不同时, 还额外发送给 `target.group`
this.scopeWith(target.group) {
sendMessage("${name} 禁言了 ${target.nameCardOrNick} $duration 秒")
}
// 同样地, 可以扩展用法, 同时私聊指令执行者:
// this.scopeWith(
// target,
// target.group
// ) { ... }
}
Java
// 在一个 SimpleCommand 内
@Handler
public void handle(sender: CommandSender, target: Member) {
int duration = Random.nextInt(1, 15);
target.mute(duration);
// 不使用 MessageScope
Group thisGroup = this.getGroupOrNull();
String message = "${this.name} 禁言 ${target.nameCardOrNick} $duration 秒";
if (!target.group.equals(thisGroup)) {
target.group.sendMessage(message);
}
sender.sendMessage(message);
// 使用 MessageScope
// 表示至少发送给 `this`, 当 `this` 的真实发信对象与 `target.group` 不同时, 还额外发送给 `target.group`
MessageScope scope = MessageScopeKt.scopeWith(sender, target);
scope.sendMessage("${name} 禁言了 ${target.nameCardOrNick} $duration 秒");
// 或是只用一行:
MessageScopeKt.scopeWith(sender, target).sendMessage("${name} 禁言了 ${target.nameCardOrNick} $duration 秒");
}
Functions
立刻以此发送消息给所有在此 MessageScope 下的消息对象