MessageScope

interface MessageScope

表示几个消息对象的 '域', 即消息对象的集合. 用于最小化将同一条消息发送给多个类型不同的目标的付出.

支持的消息对象类型

Contact, CommandSender, MessageScope (递归).

在下文, AB 指代这三种类型的其中两种, 允许排列组合. 如 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

scopeWithscopeWithNotNull 后加 lambda 参数即可表示使用 MessageScope. 如:

A.scopeWith(B) { // this: MessageScope
sendMessage(...)
}

典例

在处理指令时, 目标群对象可能与发件人群对象不同, 如用户在 A 群发指令, 以禁言 B 群的成员. 此时机器人可能需要同时广播通知到 A 群和 B 群.

由于 CommandSenderContact 无公共接口, 无法使用 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

Link copied to clipboard
inline fun <R> MessageScope.scopeWith(action: MessageScope.() -> R): R
inline fun <R> MessageScope?.scopeWith(vararg others: CommandSender?, action: MessageScope.() -> R): R
inline fun <R> MessageScope?.scopeWith(vararg others: MessageScope?, action: MessageScope.() -> R): R
inline fun <R> MessageScope?.scopeWith(vararg others: Contact?, action: MessageScope.() -> R): R
Link copied to clipboard
abstract suspend fun sendMessage(message: String)
abstract suspend fun sendMessage(message: Message)

立刻以此发送消息给所有在此 MessageScope 下的消息对象