nonebot.permission
NoneBot 支持为命令和自然语言处理器设置触发条件,此条件为一个类型为 PermissionPolicy_T
的可调用对象:
# 同步: 返回值恒为假,即表示所有消息和发送者都没有权限
disabled: PermissionPolicy_T = lambda sender: False
# 同步: 当消息是群聊,且发送者既不是管理员也不是群主时给予权限
def normal_group_member(sender: SenderRoles):
return sender.is_groupchat and not sender.is_admin and not sender.is_owner
# 异步: 在检查器中查询数据库再根据返回值决定是否给予权限
async def db_check(sender: SenderRoles):
query = await db.execute('if exists (select * from list where user=?) 1 else 0', (sender.event.user_id,))
return query[0] != 0
2
3
4
5
6
7
8
9
10
11
在实际使用时应当避免挂起太久的异步操作。在定义了这些条件后,可作为 permission
参数传递给相关的装饰器:
permit_group = { 768887710 }
banned_people = { 10000, 10001 }
def foo(sender: SenderRoles):
return sender.is_groupchat and sender.from_group(permit_group) and not sender.sendby(banned_people)
@on_natural_language({'天气'}, only_to_me=False, permission=(foo, db_check)) # 需要同时满足 foo 和 db_check
# permission=aggregate_policy((foo, db_check)) # 需要同时满足 foo 和 db_check
# permission=aggregate_policy((foo, db_check), any) # 只需满足一个
async def _(session: NLPSession):
return IntentCommand('weather', 100.0)
2
3
4
5
6
7
8
9
10
权限声明常量
适用于 1.9.0 之前的版本。点此展开
NoneBot 在 1.9.0 后改变了声明权限的风格。为了保持向前兼容,尽管不建议使用,如果你的代码仍包含以下常量,则无需改动它们仍将工作:
PRIVATE_FRIEND
: 好友私聊PRIVATE_GROUP
: 群临时私聊PRIVATE_DISCUSS
: 讨论组临时私聊PRIVATE_OTHER
: 其它私聊PRIVATE
: 任何私聊DISCUSS
: 讨论组GROUP_MEMBER
: 群成员GROUP_ADMIN
: 群管理员GROUP_OWNER
: 群主GROUP
: 任何群成员SUPERUSER
: 超级用户EVERYBODY
: 任何人
用于权限声明的常量可通过 |
合并,在命令或自然语言处理器装饰器的 permission
参数中传入,表示允许触发相应命令或自然语言处理器的用户类型。
例如下面的代码中,只有私聊和群管理员可以访问 hello
命令:
@nonebot.on_command('hello', permission=PRIVATE | GROUP_ADMIN)
async def _(session):
pass
2
3
需要注意的是,当一个用户是「群管理员」时,ta 同时也是「群成员」;当 ta 是「群主」时,ta 同时也是「群管理员」和「群成员」。
在 1.9.0 后,这些常量的类型从 int
改变为了 PermissionPolicy_T,所以如果你之前包含了它们的 type hints,或用了不寻常的方法来获取它们的值,则可能会导致错误。
SenderRoles(bot, event, sender)
1.9.0+
class 说明
封装了原生的
CQEvent
便于权限检查。此类的实例一般会传入PermissionPolicy_T
作为参数。参数
bot
(NoneBot)event
(aiocqhttp.event.Event)sender
(dict[str, Any] | None)
bot
instance-var 类型: NoneBot
说明: 机器人对象。
event
instance-var 类型: aiocqhttp.event.Event
说明: 事件。
is_admin
property 类型: bool
说明: 发送者是群管理员。
is_anonymous
property 类型: bool
说明: 消息是匿名消息。
is_discusschat
property 类型: bool
说明: 消息是讨论组消息。
is_groupchat
property 类型: bool
说明: 消息是群聊消息。
is_owner
property 类型: bool
说明: 发送者是群主。
is_private_discuss
property 类型: bool
说明: 消息是讨论组私聊消息。
is_private_friend
property 类型: bool
说明: 消息是好友私聊消息。
is_private_group
property 类型: bool
说明: 消息是群私聊消息。
is_privatechat
property 类型: bool
说明: 消息是私聊消息。
is_superuser
property 类型: bool
说明: 发送者是配置文件中设置的超级用户。
sender
instance-var 类型: dict[str, Any] | None
说明: 只有消息是群消息的时候才会有这个属性,其内容是
/get_group_member_info
API 调用的返回值。
create(bot, event)
async staticmethod 说明
构造
SenderRoles
。参数
bot
(NoneBot): 接收事件的 NoneBot 对象event
(aiocqhttp.event.Event): 上报事件
返回
- SenderRoles
用法
sender = await SenderRoles.create(session.bot, session.event) if sender.is_groupchat: if sender.is_owner: await process_owner(session) elif sender.is_admin: await process_admin(session) else: await process_member(session)
1
2
3
4
5
6
7
8根据发送者的身份决定相应命令处理方式。
from_group(self, group_id)
method 说明
表示发送者是否来自于群
group_id
。参数
group_id
(int | Container[int]): 群号码,可以为多个群号。
返回
- bool
sent_by(self, sender_id)
method 说明
表示发送者 QQ 号是否是
sender_id
。参数
sender_id
(int | Container[int]): 表示发送者 QQ 号是否是sender_id
。
返回
- bool
check_permission(bot, event, policy)
async def 说明
检查用户是否具有所要求的权限。
一般用户应该没有必要使用该函数。
参数
bot
(NoneBot): NoneBot 对象event
(aiocqhttp.event.Event): 消息事件对象policy
(PermissionPolicy_T) 1.9.0+: 返回布尔值的权限检查策略
返回
- bool: 消息事件所对应的上下文是否具有所要求的权限
用法
has_perm = await check_permission(bot, event, normal_group_member)
1
aggregate_policy(policies, aggregator=<built-in function all>)
1.9.0+
def 说明
在默认参数下,将多个权限检查策略函数使用 AND 操作符连接并返回单个权限检查策略。在实现中对这几个策略使用内置
all
函数,会优先执行同步函数而且尽可能在同步模式的情况下短路。在新的策略下,只有事件满足了
policies
中所有的原策略,才会返回True
。aggregator
参数也可以设置为其他函数,例如any
: 在此情况下会使用OR
操作符连接。如果参数中所有的策略都是同步的,则返回值是同步的,否则返回值是异步函数。
参数
policies
(Iterable[(SenderRoles) -> bool | (SenderRoles) -> Awaitable[bool]]): 要合并的权限检查策略aggregator
((Iterable[object]) -> bool): 用于合并策略的函数
返回
- PermissionPolicy_T: 新的权限检查策略
用法
# 以下两种方式在效果上等同 policy1 = lambda sender: sender.is_groupchat and sender.from_group(123456789) policy2 = aggregate_policy(lambda sender: sender.is_groupchat, lambda sender: sender.from_group(123456789))
1
2
3
4
5