
























一直沉迷在lingmo-webbrowser的开发中无法自拔。
但是,由于Qt WebEngine 一个致命的问题——如果想要支持html5视频元素,就得重新编译qt
这个问题很难解决
后来,由于种种原因,webbrowser最终archive掉了,于是我有了时间去看别的。
在接触IT Craft Development Team)后,我开始想去给由Python+Nonebot2写出来的Moonlark做一些贡献。
{% link 'Nonebot' 'https://nonebot.dev/' 'https://nonebot.dev/' %} {% link 'Moonlark开发文档' 'https://moonlark-docs.itcdt.top/' 'https://moonlark-docs.itcdt.top/' %}
(基于moonlark文档修改)
>= 3.11。2.1.0 及以上的版本)。git clone https://github.com/Moonlark-Dev/Moonlark
cd Moonlark
pip install pipx
pipx install nb-cli
pipx install poetry
poetry install将.env.template 复制为 .env 并在 .env 文件中填写相关环境变量。
(不测试对应的功能不用填)
为了测试 Moonlark 的代码,您需要运行一个 OneBot 实现并使其连接到 ws://localhost:8080/onebot/v11/ws(默认状态下),我们提供了以下两个参考方案:
NapCat确实好用,但是在qq上面,所有用了两天就被tx封。 Matcha虽然不能直接显示图片,但是在测试时可以通过nonebot的logger和with open(path,"wb")将bytes类型的图片保存到本地。
一个moonlark插件基本上要有这些内容
假设插件的名字叫nonebot_plugin_[name]。
src/plugins/nonebot_plugin_[name]首先建立插件文件夹
nb plugin create nonebot_plugin_[name]修改Moonlark目录下的pyproject.toml
toml
...
[tool.nonebot]
...
plugins=[
...,
"nonebot_plugin_[name]",#加入这一行,确保插件会被加载
...
]
src/plugins/nonebot_plugin_[name]/__init__.py这个文件包含了一些基本信息
from nonebot import require
from nonebot.plugin import PluginMetadata
from .config import Config
__plugin_meta__ = PluginMetadata(
name="nonebot_plugin_[name]",
description="描述",
usage="",
config=Config,
)
require("nonebot_plugin_[othername]")
from . import __main__src/lang/[lang]/[name].yaml这是moonlark用于本地化(翻译)的文件
目前支持zh_hans(简体中文,大陆)、zh_tw(繁体中文,台湾)、en_us(英语,美国)三种语言。
每个语言文件夹下都要创建一个对应的yaml,才能识别成功,并且每个对应的yaml中的键都要相同
例如,在zh_hans/[name].yaml中有一个键key,那么在zh_tw和en_us下的[name].yaml都要有key这个键。
键的命名满足以下规则:
-)组成src/templates/[name].html.jinja有时候,机器人需要发送图片。这时需要一个图片模版来图片 引用Moonlark开发文档:
模板编写
Render 读取的模板储存在
src/templates中,后缀为*.jinja。一个模板的格式如下:
html
TEXT
{% extends base %} {% block body %} {{ content }} {% endblock body %}基模板
html
TEXT
{% extends base %}这里使用了一个模板变量
base作为基模板的名称,这个变量在渲染时会自动填充为对应主题的基模板。内容块
header拓展页面页面的头部。
body卡片主体内容。
card卡片。
保留变量
这些变量会在渲染时被自动填充,请避免使用这些模板变量名。
base: 主题基模板的相对路径。main_title: 页面主标题。footer: 页面页脚(版权信息)。主题
Render 支持主题,主题基模板储存在
src/templates/base中,主题列表储存在src/plugins/nonebot_plugin_render/themes.json中。基模板
一个主题的基模板需要定义以下变量和内容块:
模板变量
main_title: 页面主标题。footer: 页面页脚(版权信息)。内容块
header: 页面拓展头部。body: 卡片主体内容。card: 卡片。TIP
一般来说,
card会覆盖body块。主题配置
主题配置是一个 JSON 文件,格式为
"主题ID": "主题模板相对于 src/templates 的路径"。本地化
所有向用户展示的文本都要被本地化。
本地文件引用
可以使用
{% include "xx" %}块或src=xxx引入本地文件。 使用相对引入时,基路径为src/templates。
src/plugins/nonebot_plugin_[name]/__main__.py一般nonebot的插件主要部分都是在这里写的
里面的内容由插件的功能而定,由开发者自由发挥
但是有需要注意的几点:
用户通过命令来使用nonebot2的插件。
Moonlark提供了一系列相关工具。(注意:这些都是nonebot2本身没有的)
首先在__init__.py里加上
python
require("nonebot_plugin_alconna")
require("nonebot_plugin_larklang")
require("nonebot_plugin_larkuser")
然后就可以在__main__.py里导入工具
python
from nonebot_plugin_alconna import Alconna, Args, on_alconna, Subcommand
from nonebot_plugin_larklang.__main__ import LangHelper
from nonebot_plugin_larkuser.utils.matcher import patch_matcher
接着就可以创建插件的命令
nonebot本身有on_command()方法,但是不方便获取参数,Moonlark使用Alconna让获取命令的参数更方便。
python
[command] = on_alconna(
Alconna(
"[command]",
Subcommand("[subcommand]", Args["[argument name]", [argument type],[default value]])
)
)
期中[command]指命令名称
[subcommand]指子命令名称
[argument name]指参数名称
[argument type]参数类型
[default value]默认值(可选)
python
lang = LangHelper() #本地化
patch_matcher(sudoku) #启动指令配对器
Nonebot是用到了异步编程,所以很多函数都用了async和await关键字
我总结了一下使用规则:
def,for,with等关键字前可以使用async,让其异步执行;async定义的函数,需要使用await;await的函数(函数调用了其他异步函数),这个函数定义时要使用async(这个函数也一定是异步函数)主命令的事件处理 ```python
require("nonebot_plugin_larkutils")
from nonebot_plugin_larkutils import get_user_id
@[command].assign("$main") async def _(args : [type], user_id: str = get_user_id()): #参数不止一个,建议指定类型 ...#干你想干的事情 ```
子命令就是把$main换成对应的子命令名称即可
事件处理的一个重要步骤就是让机器人发送消息。
[command].send([message])#发送消息
[command].finish([message])#发送消息(终止事件处理)[command]就是on_alconna()返回的AlconnaMatcher()对象。
Moonlark开发工具,用于本地化。
#lang就是刚才lang=LangHelper()创建的对象
lang.send("key",user_id,args)
lang.finish("key",user_id,args)其中key是刚才本地化时添加的组件
访问子键时要先把父键写在前面,父键和子键用点号(.)连接。
在__init__.py中
python
require("nonebot_plugin_htmlrender")
在__main__.py中
python
from nonebot_plugin_render.render import render_template
from nonebot_plugin_render.cache import creator
@creator("[command].html.jinja")
async def render(content: dict, user_id: str = get_user_id()):
return await render_template("[command].html.jinja", "", user_id, content, {}, True)使用
python
async def _(user_id: str = get_user_id()):
...
image = await render([content], user_id)
...
其中content是记录内容的字典,要提供jinja对应的信息。
await UniMessage().image(raw=image).send(reply_to=True)reply_to设置为True时,机器人会回复用户的消息。
在moonlark文件夹下运行命令,启动机器人
poetry run nb run不推荐Napcat测试,容易被封。 先设置角色(角色唯一标识必须是纯数字) image 在启动Nonebot后向机器人发送消息就可以收到消息了
Moonlark(Nonebot2+Python)命令式聊天机器人插件开发记录
作者
Admibrill
发布于
2025-05-25
更新于
2025-05-25
许可协议
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。