Nonebot-rs
Nonebot-rs 简称 nbrs,是一个基于 Nonebot2 思路的 Onebot 协议机器人框架 Rust 实现。
本框架的基本目标是实现比较便利的 Rust Onebot 机器人搭建。长期目标是以本项目为基础,
开发与其他脚本语言(比如:Python、Lua)互通的 Onebot 机器人平台(如果我能坚持下去
的话)。
基于本框架实现的机器人,可以由一下几部分组成:nbrs 核心、Matcher 插件、启动文件,
每个部分均可独立为单个 crate ,通过启动文件向 nbrs 注册 Matcher 后编译启动的方式
构建一个机器人实例。
nbrs 设计
nbrs 启动后,将读取设置文件、并注册 Matchers(其实这一步已经在编译时硬编码),当接
收到 WebSocket 连接后,加载 Bot 设置,接受 Event 后,由 nbrs 逐级匹配分发到各个 Matcher ,Matcher 处理后,通过 channel 将数据传递回 WebSocket 发送。每个 Event
的匹配与 Matcher 的处理均为独立协程,以此提高并发性能。
Nonebotrs.toml
当第一次运行 nbrs 时将会自动创建 Nonebotrs.toml 配置文件。
[global]
host = "127.0.0.1"
port = 8088
debug = true
superusers = ["YourID"]
nicknames = ["nickname"]
command_starts = ["/"]
[bots.BotID]
superusers = ["YourID"]
nicknames = ["nickname"]
command_starts = ["/"]
Matcher
需要启用 feature matcher
最小运行实例:
fn main() {
let mut nb = nonebot_rs::Nonebot::new(); nb.matchers
.add_message_matcher(nonebot_rs::builtin::echo::echo()) .add_message_matcher(nonebot_rs::builtin::rcnb::rcnb()); nb.run() }
Matcher 开发:
use nonebot_rs::matcher::prelude::*;
use rcnb_rs::encode;
#[derive(Clone)] pub struct Rcnb {}
#[async_trait]
impl Handler<MessageEvent> for Rcnb {
on_command!(MessageEvent, "rcnb", "RCNB", "Rcnb"); async fn handle(&self, event: MessageEvent, matcher: Matcher<MessageEvent>) {
let msg = matcher
.request_message(Some(&event), Some("Please enter something."))
.await;
if let Some(msg) = msg {
matcher.send_text(&encode(&msg)).await;
}
}
}
pub fn rcnb() -> Matcher<MessageEvent> {
Matcher::new("Rcnb", Rcnb {}) .add_pre_matcher(builtin::prematchers::to_me()) .add_pre_matcher(builtin::prematchers::command_start()) }
使用 Onebot Api:
let msg:Option<nonebot_rs::api_resp::Message> = matcher.get_msg().await
没有启用 matcher ?
let msg:Option<nonebot_rs::api_resp::Message> = bot.get_msg().await
就是这么简单~
定时任务
需要启用 feature scheduler
定义一个定时任务
use nonebot_rs::{Job, Message};
pub fn clock(nb: &nonebot_rs::Nonebot) -> Job {
let bot_getter = nb.bot_getter.clone();
Job::new("1 * * * * *", move |_, _| {
let bots = bot_getter.borrow().clone();
for (_, bot) in bots {
let bot = bot.clone();
tokio::spawn(send_a_msg(bot));
}
})
.unwrap()
}
async fn send_a_msg(bot: nonebot_rs::Bot) {
for superuser in &bot.config.superusers {
bot.send_private_msg(
superuser.parse().unwrap(),
vec![Message::text("One minute passed.")],
)
.await;
}
}
注册定时任务
use nonebot_rs;
fn main() {
let mut nb = nonebot_rs::Nonebot::new();
.add_message_matchers(r6s());
nb.scheduler.add(clock(&nb)).unwrap();
nb.run()
}
enjoy~