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,或用了不寻常的方法来获取它们的值,则可能会导致错误。
class SenderRoles(bot, event, sender) 1.9.0+
说明
封装了原生的
CQEvent便于权限检查。此类的实例一般会传入PermissionPolicy_T作为参数。参数
bot(NoneBot)event(aiocqhttp.event.Event)sender(dict[str, Any] | None)
instance-var bot
类型: NoneBot
说明: 机器人对象。
instance-var event
类型: aiocqhttp.event.Event
说明: 事件。
property is_admin
类型: bool
说明: 发送者是群管理员。
property is_anonymous
类型: bool
说明: 消息是匿名消息。
property is_discusschat
类型: bool
说明: 消息是讨论组消息。
property is_groupchat
类型: bool
说明: 消息是群聊消息。
property is_owner
类型: bool
说明: 发送者是群主。
property is_private_discuss
类型: bool
说明: 消息是讨论组私聊消息。
property is_private_friend
类型: bool
说明: 消息是好友私聊消息。
property is_private_group
类型: bool
说明: 消息是群私聊消息。
property is_privatechat
类型: bool
说明: 消息是私聊消息。
property is_superuser
类型: bool
说明: 发送者是配置文件中设置的超级用户。
instance-var sender
类型: dict[str, Any] | None
说明: 只有消息是群消息的时候才会有这个属性,其内容是
/get_group_member_infoAPI 调用的返回值。
async staticmethod create(bot, event)
说明
构造
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根据发送者的身份决定相应命令处理方式。
method from_group(self, group_id)
说明
表示发送者是否来自于群
group_id。参数
group_id(int | Container[int]): 群号码,可以为多个群号。
返回
- bool
method sent_by(self, sender_id)
说明
表示发送者 QQ 号是否是
sender_id。参数
sender_id(int | Container[int]): 表示发送者 QQ 号是否是sender_id。
返回
- bool
async def check_permission(bot, event, policy)
说明
检查用户是否具有所要求的权限。
一般用户应该没有必要使用该函数。
参数
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
def aggregate_policy(policies, aggregator=<built-in function all>) 1.9.0+
说明
在默认参数下,将多个权限检查策略函数使用 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