惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
人人都是产品经理
人人都是产品经理
Cisco Talos Blog
Cisco Talos Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
V2EX
博客园 - 三生石上(FineUI控件)
Martin Fowler
Martin Fowler
WordPress大学
WordPress大学
D
Docker
S
SegmentFault 最新的问题
博客园 - 聂微东
美团技术团队
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Last Week in AI
Last Week in AI
M
MIT News - Artificial intelligence
F
Fortinet All Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The GitHub Blog
The GitHub Blog
GbyAI
GbyAI
L
LangChain Blog
Vercel News
Vercel News
博客园 - 叶小钗
MongoDB | Blog
MongoDB | Blog
Stack Overflow Blog
Stack Overflow Blog
H
Help Net Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Cloudflare Blog
Engineering at Meta
Engineering at Meta
T
Threat Research - Cisco Blogs
T
Threatpost
Scott Helme
Scott Helme
T
Tailwind CSS Blog
Latest news
Latest news
Stack Overflow Blog
Stack Overflow Blog
Blog — PlanetScale
Blog — PlanetScale
The Register - Security
The Register - Security
罗磊的独立博客
P
Proofpoint News Feed
腾讯CDC
S
Schneier on Security
雷峰网
雷峰网
A
About on SuperTechFans
T
Tenable Blog
F
Full Disclosure
Cyberwarzone
Cyberwarzone
博客园_首页
有赞技术团队
有赞技术团队
K
Kaspersky official blog

文章列表

埃氮幂の命名空间 埃氮幂の命名空间 P13020 [GESP202506 八级] 遍历计数 题解 埃氮幂の命名空间 P3435 [POI 2006] OKR-Periods of Words 题解 埃氮幂の命名空间 埃氮幂の命名空间 埃氮幂の命名空间 埃氮幂の命名空间 埃氮幂の命名空间 埃氮幂の命名空间 埃氮幂の命名空间 埃氮幂の命名空间 埃氮幂の命名空间 Hexo博客0氪建站记录(下) 埃氮幂の命名空间 埃氮幂の命名空间
埃氮幂の命名空间
2025-05-25 · via

往事

一直沉迷在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文档修改)

  1. 确保您的 Python 版本 >= 3.11
  2. 安装包管理工具 Poetry(建议安装 2.1.0 及以上的版本)。
  3. 克隆仓库并安装依赖,可以使用以下指令:
SH
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 号供 NapCat 登录。同时,您可能需要承担该账号被 TX 冻结的风险。
  • 使用 Matcha: 目前已知无法显示 Moonlark 发出的图片。

NapCat确实好用,但是在qq上面,所有用了两天就被tx封。 Matcha虽然不能直接显示图片,但是在测试时可以通过nonebot的logger和with open(path,"wb")将bytes类型的图片保存到本地。

开发

一个moonlark插件基本上要有这些内容 假设插件的名字叫nonebot_plugin_[name]

src/plugins/nonebot_plugin_[name]

首先建立插件文件夹

SH
nb plugin create nonebot_plugin_[name]

修改Moonlark目录下的pyproject.toml toml ... [tool.nonebot] ... plugins=[ ..., "nonebot_plugin_[name]",#加入这一行,确保插件会被加载 ... ]

src/plugins/nonebot_plugin_[name]/__init__.py

这个文件包含了一些基本信息

PYTHON
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_twen_us下的[name].yaml都要有key这个键。

键的命名满足以下规则:

  • 不以数字开头;
  • 由26个大写、26个小写、10个阿拉伯数字或者减号(-)组成
  • 子键要缩进

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是用到了异步编程,所以很多函数都用了asyncawait关键字 我总结了一下使用规则:

  • def,for,with等关键字前可以使用async,让其异步执行;
  • 调用使用了async定义的函数,需要使用await;
  • 函数体中调用其他函数使用了await的函数(函数调用了其他异步函数),这个函数定义时要使用async(这个函数也一定是异步函数)

主命令的事件处理 ```python

记得在init.py加入这个

require("nonebot_plugin_larkutils")

记得在main.py开头导入这个

from nonebot_plugin_larkutils import get_user_id

@[command].assign("$main") async def _(args : [type], user_id: str = get_user_id()): #参数不止一个,建议指定类型 ...#干你想干的事情 ```

子命令就是把$main换成对应的子命令名称即可

向用户发送消息

事件处理的一个重要步骤就是让机器人发送消息。

Alconna发送消息

PYTHON
[command].send([message])#发送消息
[command].finish([message])#发送消息(终止事件处理)

[command]就是on_alconna()返回的AlconnaMatcher()对象。

LangHelper发送消息

Moonlark开发工具,用于本地化。

PYTHON
#lang就是刚才lang=LangHelper()创建的对象
lang.send("key",user_id,args)
lang.finish("key",user_id,args)

其中key是刚才本地化时添加的组件 访问子键时要先把父键写在前面,父键和子键用点号(.)连接。

渲染图片模版并发送图片

导入依赖

__init__.pypython require("nonebot_plugin_htmlrender")

__main__.py python from nonebot_plugin_render.render import render_template from nonebot_plugin_render.cache import creator

定义渲染模版函数
PYTHON
@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对应的信息。

发送图片
PYTHON
await UniMessage().image(raw=image).send(reply_to=True)

reply_to设置为True时,机器人会回复用户的消息。

测试

启动Nonebot

在moonlark文件夹下运行命令,启动机器人

SH
poetry run nb run

使用Matcha测试

不推荐Napcat测试,容易被封。 先设置角色(角色唯一标识必须是纯数字) image 在启动Nonebot后向机器人发送消息就可以收到消息了

Moonlark(Nonebot2+Python)命令式聊天机器人插件开发记录

作者

Admibrill

发布于

2025-05-25

更新于

2025-05-25

许可协议