部署建议看 NoneBot+Lagrange 搭建 qq 机器人保姆级别教程_lagrange.onebot-CSDN 博客
如果只是利用现成的插件可以直接用 nb-cli
nb plugin #插件管理
nb driver #驱动器管理
nb adapter #适配器管理
nb plugin list #查看商店内的插件
nb plugin install <plugin-name>
nb plugin uninstall <plugin-name>
#注意nb下载的插件和python的包在同一个地方
#nb会自己配置toml里的内容,正常来说无需变更
#但还是建议去nonobot商店找到对应的项目看看有没有其他要配置的
# 开发
模块可以是一个文件也可以一个文件夹。文件夹中必须直接包含一个 __init__.py
。插件不可重名。
项目目录里有几个比较重要的文件:
.env开头的文件:各种环境下的配置文件 | |
src/pugins:通常来说的插件目录,nb下的不在这里 | |
pyproject.toml:项目插件配置文件 |
对于某文件类型插件自己的配置项可以:
#config.py | |
from pydantic import BaseModel,Extra | |
class Config(BaseModel,extra=Extra.ignore): | |
token: <配置> |
#__init__.py | |
from nonebot import get_driver | |
from .config import Config | |
... | |
plugin_config=Config.parse_obj(get_driver().config) | |
... |
# 事件响应器
# 内容
# 响应类型
用于设定触发 bot 的条件有多种,分为四类:
meta_event message notice request
@<xxx>.type_updater
#type不指定默认message,会话更新为该类型时触发
# 匹配规则(rule)
#rule 对象,用于细化匹配的条件(比如只有特定 id 的人才能触发,就是下面这个),可以自定义 | |
async def user_checker(event: Event) -> bool: | |
return event.get_user_id() == "123123" | |
matcher = on_message(rule=user_checker) | |
#可以合并规则,与 None 合并还是其本身 | |
rule1 = Rule(foo_checker) | |
rule2 = Rule(bar_checker) | |
rule = rule1 & rule2 | |
rule = rule1 & bar_checker | |
rule = foo_checker & rule2 |
# 触发权限(Permission)
用于对话时控制响应,写为:
@<xxx>.permission_updater
#用rule匹配会丢失上下文,但是permission不会,其会自动check session
# 优先级(priority)
响应器的执行顺序,同一个优先级同时运行,数字越小越先响应
# 阻断(block)
布尔类型的量,为 True 时阻止事件向后面的优先级传递
# 有效期
temp:下次响应后移除
expire_time:指定时间后移除
# 创建
from nonebot import on_message | |
matcher = on_message() |
可以使用的辅助函数:
# 事件处理流程
# 使用 handle
装饰器
这个函数在事件触发时自动执行
@matcher.handle() //后面假设事件都是matcher | |
async def handle_func(): |
如果希望其使用其他的函数,需要依赖注入
from nonebot import on_command | |
from nonebot.params import Depends # 1. 引用 Depends | |
from nonebot.adapters.onebot.v11 import MessageEvent | |
test = on_command("123") | |
async def depend(event: MessageEvent): # 2. 编写依赖函数,可以是简单同步函数,返回值可以是任意的类型 | |
return {"uid": event.get_user_id(), "nickname": event.sender.nickname} | |
@test.handle() | |
async def _(x: dict = Depends(depend)): # 3. 在事件处理函数里声明依赖项,注意写法。x 获取返回值 | |
print(x["uid"], x["nickname"]) #使用返回的字典 |
Depends () 还有一个参数 use_cache,默认为 true,即第一次调用后写入缓存,之后只获取缓存中的数据,直到该事件结束
PS:依赖注入也可以是一个拥有 __init__
或者 __call__
方法的类,此时原来获取返回值就变成了创建这个类的实例
__call__方法可以让类的实例被当做函数来使用,php 中也有类似的魔术方法,此时相当于依赖函数
class EventChecker: #这玩意儿于是可以两用 | |
def __init__(self, EventClass: Type[MessageEvent]): | |
self.event_class = EventClass | |
def __call__(self, event: MessageEvent) -> bool: | |
return isinstance(event, self.event_class) | |
checker = EventChecker(GroupMessageEvent) # 3. 将类实例化 | |
@test.handle() | |
async def _(x: bool = Depends(checker)): # 4. 在事件处理函数里声明依赖项 | |
if x: | |
print("这是群聊消息") | |
else: | |
print("这不是群聊消息") |
事件处理函数可以重载,其他某些装饰器也可以:
@matcher.handle() | |
async def _(bot: Bot, event: GroupMessageEvent): | |
await matcher.send("群聊消息事件响应成功!") | |
@matcher.handle() | |
async def _(bot: Bot, event: PrivateMessageEvent): | |
await matcher.send("私聊消息事件响应成功!") |
装饰器可以有多个,它们是顺序执行的
# 使用 receive
装饰器
from nonebot.params import Received | |
@matcher.receive("id") | |
async def handle_func(e: Event = Received("id")): | |
#可以有多个该装饰器,但是 id 不能相同 |
可以使用 LastReceived () 代替 Received ("id"),直接获取最近一次 receive 的事件,要 import
会中断处理流程,等待接受一个新的事件,然后触发
# 使用 got
装饰器
from nonebot.paras import Arg | |
@matcher.got("key", prompt="Key?") | |
async def handlunc(key: Message = Arg()): |
可使用 Argstr/ArgPlainText 代替 arg,将参数转为字符串 / 接受纯文本部分,要 import
和 receive 类似,但是不存在那个参数时会发送 prompt
got
和 receive
可以相互嵌套
# 事件响应器
matcher.send("hello") #回复
matcher.finish("end") #终止事件处理流程,可选回复
matcher.pause("Confirm?") #等待新的事件处理依赖,可选回复,类似receive
matcher.reject(“输入错误,请重新输入!”) #拒绝当前事件,等待再次接收处理,要配合依赖注入