上下文
如果你是用户,你可能想过能否在私聊中触发机器人;如果你是搭建者,你可能想过为什么机器人启动后不响应群聊。
由于 IdhagnBot 在设计时的目标之一就有同时服务多个群聊,IdhagnBot 引入了一个称作“上下文”(Context)的模块来管理不同群聊之间的行为。
用户说明
在群聊中使用 IdhagnBot,只能使用当前群聊里的命令,在私聊中使用 IdhagnBot,分这几种情况:
- 一部分命令会自动检测你是否加了可以使用对应命令的群,只要加的群有至少一个能使用该命令,就会在帮助里显示,并且可以在私聊中使用。IdhagnBot 的通用插件中并不包含此类命令,但搭建者在编写
user_plugins
时可以加入此类命令。 - 一部分命令需要你手动提供你所在的群号,只有提供了群号且对应群可以使用该命令时,命令才会在帮助里显示,并且才能在私聊中使用。如:
/签到
- 一部分命令可以直接使用,其中一部分命令如果手动提供了群号,在功能上会有所不同。如:
/硬币
(没有不同)、/petpet
(有细微不同)
提供群号的方式是在私聊中发送 /上下文 群号
,除了群号也可以使用搭建者在配置中指定的别名,要查看当前群聊的可用别名,请在群聊中发送 /别名
。
为防止误操作,一段时间(默认为 10 分钟)内没有在私聊中使用命令,就会清除提供的群号,你也可以发送 /上下文 退出
立即清除。
作者:很复杂是吧?其实我也这么觉得,可能没有我之外的第二个人能理解这种诡异的设计
/petpet 奈亚拉托提镨
示例
找不到 奈亚拉托提镨
/签到
命令不存在、权限不足或不适用于当前上下文
/上下文 de
已进入 su226 Development(123456789)的群聊上下文
/别名
当前群聊上下文有以下别名:
de
/petpet 奈亚拉托提镨
/签到
/上下文 退出
已退出群聊上下文
以上示例是在私聊中执行的,群聊中没有 /上下文 命令。
/上下文
进入或退出上下文命令
/上下文 - 查看当前上下文
/上下文 <群号或别名> - 进入群聊上下文
/上下文 退出|exit - 退出群聊上下文
别名
权限节点
/ctx
权限节点
context.ctx
/别名
查看当前群聊上下文的别名命令
该命令没有帮助
别名
权限节点
/ctx
权限节点
context.alias
搭建说明
默认的配置只会响应私聊,如需响应群聊,请修改配置文件。
配置文件在 configs/context.yaml
,参考如下:
groups: # 要响应的所有群,名单外的群不会响应
123456789: [别名1, 别名2]
987654321: [] # 如果不需要别名,数组可留空
private_limit: # 私聊黑/白名单,如果一个帐号同时用于调试和实际使用,你可能需要配置这个功能
- 123123123
private_limit_whitelist: true # 将上面的名单作为白名单(默认为黑名单)
timeout: 600 # /ctx 命令的超时,默认为 600 秒(10分钟)
状态文件在 states/context.yaml
,参考如下:
警告
你通常不应该修改状态文件,除非别无选择。
contexts: # 一项对应一个发送过 /ctx 的用户
123456789: # 用户 QQ 号
expire: '2022-03-28T20:29:51.850468' # 过期时间
group: 987654321 # 当前 /ctx 群号
开发示例
创建命令时,请使用 CommandBuilder
而非 nonebot.on_command
。
from nonebot.adapters.onebot.v11 import Event
from util import command
# 关于 CommandBuilder 的详细用法,请参考对应文档
matcher = (
command.CommandBuilder("some_plugin.some_command", "命令名")
# 群号可指定多个,对于 in_group 也可以不指定,代表任意群聊
.has_group(123456789, 987654321)
.build()
)
@matcher.handle()
async def handler(event: Event) -> None:
# 调用 context.get_event_context 来获取当前事件的上下文
# 对于群聊事件,始终返回当前群号
ctx = context.get_event_context(event)
await matcher.finish(f"当前上下文:{ctx}")