✨ Alconna Usage For NoneBot2 ✨
本仓库已迁移至 nonebot/plugin-alconna
该插件提供了 Alconna 的 Nonebot2 适配版本与工具
- 完整的 Alconna 特性支持
- 基本的 rule, matcher 与 依赖注入
- 自动回复命令帮助信息 (help, shortcut, completion) 选项
- 现有全部协议的 Segment 标注
- match_value, match_path 等检查函数
- 补全会话支持
QQ 交流群: 链接
from nonebot.adapters.onebot.v12 import Message, MessageSegment
from arclet.alconna import Alconna, Option, Args
msg = Message("Hello! --foo 123")
img = MessageSegment.image("1.png")
print(msg)
alc = Alconna("Hello!", Option("--foo", Args["foo", int]))
res = alc.parse(msg)
assert res.matched
assert res.query("foo.foo") == 123
assert not alc.parse(Message(["Hello!", img])).matched
特定适配器:
from nonebot_plugin_alconna.adapters.onebot12 import Mention
from nonebot.adapters.onebot.v12 import Message
from arclet.alconna import Alconna, Args
msg = Message(["Hello!", Mention("123")])
print(msg) # Hello![mention:user_id=123]
alc = Alconna("Hello!", Args["target", Mention])
res = alc.parse(msg)
assert res.matched
assert res.query("target").data['user_id'] == '123'
通用标注:
from nonebot.adapters.onebot.v12 import Message as Ob12Msg, MessageSegment as Ob12MS
from nonebot.adapters.onebot.v11 import Message as Ob11Msg, MessageSegment as Ob11MS
from nonebot_plugin_alconna.adapters import At
from arclet.alconna import Alconna, Args
msg1 = Ob12Msg(["Hello!", Ob12MS.mention("123")]) # Hello![mention:user_id=123]
msg2 = Ob11Msg(["Hello!", Ob11MS.at(123)]) # Hello![CQ:at,qq=123]
alc = Alconna("Hello!", Args["target", At])
res1 = alc.parse(msg1)
assert res1.matched
target = res1.query("target")
assert isinstance(target, At)
assert target.target == '123'
res2 = alc.parse(msg2)
assert res2.matched
target = res2.query("target")
assert isinstance(target, At)
assert target.target == '123'
...
from nonebot import require
require("nonebot_plugin_alconna")
...
from nonebot_plugin_alconna import (
on_alconna,
Match,
Query,
AlconnaMatch,
AlconnaQuery,
AlcMatches,
AlcResult
)
from arclet.alconna import Alconna, Args, Option
test = on_alconna(
Alconna(
"test",
Option("foo", Args["bar", int]),
Option("baz", Args["qux", bool, False])
),
auto_send_output=True
)
@test.handle()
async def handle_test1(result: AlcResult):
await test.send(f"matched: {result.matched}")
await test.send(f"maybe output: {result.output}")
@test.handle()
async def handle_test2(result: AlcMatches):
await test.send(f"head result: {result.header_result}")
await test.send(f"args: {result.all_matched_args}")
@test.handle()
async def handle_test3(bar: Match[int] = AlconnaMatch("bar")):
if bar.available:
await test.send(f"foo={bar.result}")
@test.handle()
async def handle_test4(qux: Query[bool] = AlconnaQuery("baz.qux", False)):
if qux.available:
await test.send(f"baz.qux={qux.result}")
...
from nonebot import require
require("nonebot_plugin_alconna")
...
from arclet.alconna import Alconna, Subcommand, Option, Args
from nonebot_plugin_alconna import assign, on_alconna, AlconnaResult, CommandResult, Check
pip = Alconna(
"pip",
Subcommand(
"install",
Args["pak", str],
Option("--upgrade"),
Option("--force-reinstall")
),
Subcommand(
"list",
Option("--out-dated")
)
)
pip_cmd = on_alconna(pip)
@pip_cmd.handle([Check(assign("install.pak", "pip"))])
async def update(arp: CommandResult = AlconnaResult()):
...
@pip_cmd.handle([Check(assign("list"))])
async def list_(arp: CommandResult = AlconnaResult()):
...
@pip_cmd.handle([Check(assign("install"))])
async def install(arp: CommandResult = AlconnaResult()):
...
...
from nonebot import require
require("nonebot_plugin_alconna")
...
from nonebot_plugin_alconna import (
on_alconna,
AlconnaDuplication
)
from arclet.alconna import Alconna, Args, Duplication, Option, OptionStub
test = on_alconna(
Alconna(
"test",
Option("foo", Args["bar", int]),
Option("baz", Args["qux", bool, False])
),
auto_send_output=True
)
class MyResult(Duplication):
bar: int
qux: bool
foo: OptionStub
@test.handle()
async def handle_test1(result: MyResult = AlconnaDuplication(MyResult)):
await test.send(f"matched: bar={result.bar}, qux={result.qux}")
await test.send(f"options: foo={result.foo.origin}")
目前配置项有:
- ALCONNA_AUTO_SEND_OUTPUT : 是否全局启用输出信息自动发送
- ALCONNA_USE_COMMAND_START : 是否将 COMMAND_START 作为全局命令前缀
- ALCONNA_AUTO_COMPLETION: 是否全局启用补全会话功能
def on_alconna(
command: Alconna | str,
skip_for_unmatch: bool = True,
auto_send_output: bool = False,
output_converter: Callable[[OutputType, str], Message | Awaitable[Message]] | None = None,
aliases: set[str | tuple[str, ...]] | None = None,
comp_config: CompConfig | None = None,
**kwargs,
) -> type[Matcher]:
command
: Alconna 命令skip_for_unmatch
: 是否在命令不匹配时跳过该响应auto_send_output
: 是否自动发送输出信息并跳过响应output_converter
: 输出信息字符串转换为 Message 方法aliases
: 命令别名, 作用类似于on_command
comp_config
: 补全会话配置, 不传入则不启用补全会话
协议名称 | 路径 |
---|---|
OneBot 协议 | adapters.onebot11, adapters.onebot12 |
Telegram | adapters.telegram |
飞书 | adapters.feishu |
GitHub | adapters.github |
QQ 频道 | adapters.qqguild |
钉钉 | adapters.ding |
Console | adapters.console |
开黑啦 | adapters.kook |
Mirai | adapters.mirai |
Ntchat | adapters.ntchat |
MineCraft | adapters.minecraft |
BiliBili Live | adapters.bilibili |
funcommand
装饰器用于将一个接受任意参数,返回 str
或 Message
或 MessageSegment
的函数转换为命令响应器。
from nonebot_plugin_alconna import funcommand
@funcommand()
async def echo(msg: str):
return msg