import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

# Alconna 插件

[`nonebot-plugin-alconna`](https://github.com/nonebot/plugin-alconna) 是一类极大地提升了 NoneBot 开发体验的插件。

该插件可分为三个部分：

- 增强的命令解析: 基于 [Alconna](https://github.com/ArcletProject/Alconna), 提供一类新的事件响应器辅助函数 `on_alconna`. 相比 `on_command`, `on_shell`, `on_regex` 等函数，`on_alconna` 提供了更强大的命令解析能力与诸多特性。
- 通用消息组件: 实现了跨平台接收、发送、撤回、编辑、表态消息的功能。
  - `UniMessage` 通用消息模型，支持各适配器下的消息转换和导出，发送。
  - `Text`, `Image`, `At` 等通用消息段模型，既与 `UniMessage` 配合使用，又能用于 `Alconna` 的命令解析。
  - `message_recall`, `message_edit`, `message_reaction` 等功能函数。
  - `Target` 通用消息目标模型，并通过该模型进行主动消息发送。
  - `UniMsg`, `MsgId`, `MsgTarget`, `at_in`, `at_me` 等提供给 nonebot 使用的依赖注入和 `Rule`。
- 内置功能插件：基于上述部分实现的内置功能插件。
  - `echo`: 通过 `on_alconna` 实现的 echo 插件，支持回显回复消息。
  - `help`: 列出所有 `on_alconna` 事件响应器的帮助信息或其对应的插件信息。
  - `lang`: 切换 `Alconna` 使用的语言
  - `switch`: 禁用/启用某个指令
  - `with`: 针对具有多个子命令的指令，通过 `with` 在当前会话中载入命令头以节省输入。

以最新版本为例 (v0.59), 本插件已支持 NoneBot 生态中几乎所有的适配器, 包括:

| 协议名称                                                            | 路径                                 |
| ------------------------------------------------------------------- | ------------------------------------ |
| [OneBot 协议](https://onebot.dev/)                                  | adapters.onebot11, adapters.onebot12 |
| [Telegram](https://core.telegram.org/bots/api)                      | adapters.telegram                    |
| [飞书](https://open.feishu.cn/document/home/index)                  | adapters.feishu                      |
| [GitHub](https://docs.github.com/en/developers/apps)                | adapters.github                      |
| [QQ bot](https://github.com/nonebot/adapter-qq)                     | adapters.qq                          |
| [钉钉](https://open.dingtalk.com/document/)                         | adapters.ding                        |
| [Console](https://github.com/nonebot/adapter-console)               | adapters.console                     |
| [开黑啦](https://developer.kookapp.cn/)                             | adapters.kook                        |
| [Mirai](https://docs.mirai.mamoe.net/mirai-api-http/)               | adapters.mirai                       |
| [Ntchat](https://github.com/JustUndertaker/adapter-ntchat)          | adapters.ntchat                      |
| [MineCraft](https://github.com/17TheWord/nonebot-adapter-minecraft) | adapters.minecraft                   |
| [Walle-Q](https://github.com/onebot-walle/nonebot_adapter_walleq)   | adapters.onebot12                    |
| [Discord](https://github.com/nonebot/adapter-discord)               | adapters.discord                     |
| [Red 协议](https://github.com/nonebot/adapter-red)                  | adapters.red                         |
| [Satori](https://github.com/nonebot/adapter-satori)                 | adapters.satori                      |
| [Dodo IM](https://github.com/nonebot/adapter-dodo)                  | adapters.dodo                        |
| [Kritor](https://github.com/nonebot/adapter-kritor)                 | adapters.kritor                      |
| [Tailchat](https://github.com/eya46/nonebot-adapter-tailchat)       | adapters.tailchat                    |
| [Mail](https://github.com/mobyw/nonebot-adapter-mail)               | adapters.mail                        |
| [微信公众号](https://github.com/YangRucheng/nonebot-adapter-wxmp)   | adapters.wxmp                        |
| [黑盒语音](https://github.com/lclbm/adapter-heybox)                 | adapters.heybox                      |
| [Milky](https://github.com/nonebot/adapter-milky)                   | adapters.milky                       |
| [EFChat](https://github.com/molanp/nonebot_adapter_efchat)          | adapters.efchat                      |

## 安装插件

在使用前请先安装 `nonebot-plugin-alconna` 插件至项目环境中，可参考[获取商店插件](../../tutorial/store.mdx#安装插件)来了解并选择安装插件的方式。如：

在**项目目录**下执行以下命令：

<Tabs groupId="install">
<TabItem value="cli" label="使用 nb-cli">

```shell
nb plugin install nonebot-plugin-alconna
```

</TabItem>
<TabItem value="pip" label="使用 pip">

```shell
pip install nonebot-plugin-alconna
```

</TabItem>

<TabItem value="pdm" label="使用 pdm">

```shell
pdm add nonebot-plugin-alconna
```

</TabItem>
</Tabs>

## 导入插件

由于 `nonebot-plugin-alconna` 作为插件，因此需要在使用前对其进行**加载**。使用 `require` 方法可轻松完成这一过程，可参考 [跨插件访问](../../advanced/requiring.md) 一节进行了解。

```python
from nonebot import require

require("nonebot_plugin_alconna")

from nonebot_plugin_alconna import ...
```

## 使用插件

在前面的[深入指南](../../appendices/session-control.mdx)中，我们已经得到了一个天气插件。
现在我们将使用 `Alconna` 来改写这个插件。

<details>
  <summary>插件示例</summary>

```python title=weather/__init__.py
from nonebot import on_command
from nonebot.rule import to_me
from nonebot.matcher import Matcher
from nonebot.adapters import Message
from nonebot.params import CommandArg, ArgPlainText

weather = on_command("天气", rule=to_me(), aliases={"weather", "天气预报"})

@weather.handle()
async def handle_function(matcher: Matcher, args: Message = CommandArg()):
    if args.extract_plain_text():
        matcher.set_arg("location", args)

@weather.got("location", prompt="请输入地名")
async def got_location(location: str = ArgPlainText()):
    if location not in ["北京", "上海", "广州", "深圳"]:
        await weather.reject(f"你想查询的城市 {location} 暂不支持，请重新输入！")
    await weather.finish(f"今天{location}的天气是...")
```

</details>

```python {5-9,13-15,17-18}
from nonebot.rule import to_me
from arclet.alconna import Alconna, Args
from nonebot_plugin_alconna import Match, on_alconna

weather = on_alconna(
    Alconna("天气", Args["location?", str]),
    aliases={"weather", "天气预报"},
    rule=to_me(),
)


@weather.handle()
async def handle_function(location: Match[str]):
    if location.available:
        weather.set_path_arg("location", location.result)

@weather.got_path("location", prompt="请输入地名")
async def got_location(location: str):
    if location not in ["北京", "上海", "广州", "深圳"]:
        await weather.reject(f"你想查询的城市 {location} 暂不支持，请重新输入！")
    await weather.finish(f"今天{location}的天气是...")
```

在上面的代码中，我们使用 `Alconna` 来解析命令，`on_alconna` 用来创建响应器，使用 `Match` 来获取解析结果。

关于更多 `Alconna` 的使用方法，可参考 [Alconna 文档](https://arclet.top/tutorial/alconna)，
或阅读 [Alconna 基本介绍](./command.md) 一节。

关于更多 `on_alconna` 的使用方法，可参考 [插件文档](https://github.com/nonebot/plugin-alconna/blob/master/docs.md)，
或阅读 [响应规则的使用](./matcher.mdx) 一节。

## 交流与反馈

QQ 交流群: [🔗 链接](https://jq.qq.com/?_wv=1027&k=PUPOnCSH)

友链: [📚 文档](https://graiax.cn/guide/message_parser/alconna.html)
