QQ机器人 OneBot 协议实现,同时支持 OneBot 11 (NapCat/CQHTTP) 和 OneBot 12 (ISO标准) 协议。可与 NapCat、Lagrange、go-cqhttp 等实现无缝对接。
$ dotnet add package Luolan.QQBot.OneBot一个模块化、可扩展的 QQ 机器人 SDK,支持多协议切换。只需更换实现包,即可在官方 API 和 OneBot 12 协议之间无缝切换!
| 包名 | 说明 |
|---|---|
Luolan.QQBot.Core | 核心抽象层,定义统一接口和模型 |
Luolan.QQBot.Official | QQ 官方机器人 API 实现 |
Luolan.QQBot.OneBot | OneBot 12 协议实现 |
Luolan.QQBot | v1.x 兼容包(推荐迁移到新架构) |
dotnet add package Luolan.QQBot.Core
dotnet add package Luolan.QQBot.Official
using Luolan.QQBot.Official;
using Luolan.QQBot.Core.Extensions;
// 创建官方机器人客户端
var bot = new OfficialBotClientBuilder()
.WithAppId("你的AppId")
.WithClientSecret("你的ClientSecret")
.WithIntents(Intents.Default | Intents.GroupAtMessages)
.Build();
// 监听消息事件
bot.Events.OnMessageReceived += async e =>
{
Console.WriteLine($"收到消息: {e.Message.Content}");
await bot.ReplyAsync(e.Message, "收到!");
};
// 启用控制器模式
bot.UseControllers();
await bot.StartAsync();
await Task.Delay(-1);
支持 OneBot 11 (NapCat/CQHTTP) 和 OneBot 12 (Lagrange) 两种协议
dotnet add package Luolan.QQBot.Core
dotnet add package Luolan.QQBot.OneBot
using Luolan.QQBot.Core.Abstractions;
using Luolan.QQBot.OneBot;
var bot = new OneBotClientBuilder()
.UseWebSocket("ws://127.0.0.1:6700") // NapCat 默认端口
.WithAccessToken("your_token") // 可选
.Build(); // 自动检测协议版本
bot.Events.OnReady += async e => Console.WriteLine("✅ 上线成功!");
bot.Events.OnMessageReceived += async e =>
{
if (e.Message.Content == "/ping")
await bot.ReplyAsync(e.Message, "Pong!");
};
bot.UseControllers();
await bot.StartAsync();var bot = new OneBotClientBuilder()
.UseWebSocket("ws://127.0.0.1:3001") // Lagrange 默认端口
.WithProtocolVersion(OneBotVersion.V12) // 可选:显式指定
.Build();
// 事件处理代码完全相同,切换协议无需修改业务代码!
await bot.StartAsync();💡 提示:协议切换只需修改端口和地址,代码无需改动!
更多详情请查看 OneBot 包文档。
核心优势:你的业务代码完全不需要修改!
// ===== 官方 API =====
using Luolan.QQBot.Official;
var bot = new OfficialBotClientBuilder()
.WithAppId("xxx").WithClientSecret("xxx")
.Build();
// ===== OneBot 12 =====
using Luolan.QQBot.OneBot;
var bot = new OneBotClientBuilder()
.UseWebSocket("ws://127.0.0.1:3001")
.Build();
// ===== 以下代码完全相同 =====
bot.Events.OnMessageReceived += async e =>
{
await bot.Messages.SendTextAsync(e.Message.Source, "Hello!");
};
bot.UseControllers();
await bot.StartAsync();使用 MessageBuilder 以流式方式构建复杂消息:
var message = MessageBuilder.Create()
.At(userId)
.Text(" 这是一个测试消息 ")
.Image("https://example.com/image.jpg")
.Build();
await bot.ReplyAsync(e.Message, message);或者直接传入 Builder(因为它实现了 IEnumerable<MessageSegment>):
await bot.Messages.SendMessageAsync(target, MessageBuilder.Create()
.Text("Hello ")
.Face("101")
);控制器模式与协议无关,可以在任何实现上工作:
using Luolan.QQBot.Core.Controllers;
public class MyController : BotController
{
// 基础命令
// 用户发送: /hello world
[Command("hello")]
public string Hello(string name)
{
return $"Hello {name}!";
}
// 参数自动转换
// 用户发送: /add 10 20
[Command("add")]
public string Add(int a, int b)
{
return $"Result: {a + b}";
}
// 返回图片
[Command("image")]
public ImageResult GetImage()
{
return new ImageResult("https://example.com/image.jpg");
}
// 异步方法
[Command("async")]
public async Task<string> AsyncWork()
{
await Task.Delay(1000);
return "Done!";
}
// 访问上下文
[Command("info")]
public string Info()
{
return $"Sender: {Sender?.Username}, MessageId: {Message.Id}";
}
}OneBot 实现支持多种连接方式:
// 正向 WebSocket(推荐)
var bot = new OneBotClientBuilder()
.UseWebSocket("ws://127.0.0.1:3001")
.Build();
// HTTP 模式
var bot = new OneBotClientBuilder()
.UseHttp("http://127.0.0.1:3000")
.Build();
// 反向 WebSocket(即将支持)
var bot = new OneBotClientBuilder()
.UseReverseWebSocket(port: 8080, path: "/onebot/v12/ws")
.Build();public interface IBotClient
{
bool IsConnected { get; }
BotUser? CurrentUser { get; }
IEventDispatcher Events { get; }
IMessageSender Messages { get; }
Task StartAsync(CancellationToken cancellationToken = default);
Task StopAsync();
}// 发送文本
await bot.Messages.SendTextAsync(target, "Hello!");
// 发送图片
await bot.Messages.SendImageAsync(target, "https://example.com/image.jpg");
// 发送复合消息
await bot.Messages.SendMessageAsync(target, new[]
{
MessageSegment.Text("Hello "),
MessageSegment.At("123456"),
MessageSegment.Text("!")
});// 群消息
var target = MessageTarget.Group("group_id");
// 私聊消息
var target = MessageTarget.Private("user_id");
// 频道消息
var target = MessageTarget.Channel("guild_id", "channel_id");统一的事件接口,所有协议实现都使用相同的事件模型:
// 消息事件
bot.Events.OnMessageReceived += async e =>
{
Console.WriteLine($"消息来源: {e.SourceType}");
Console.WriteLine($"发送者: {e.Message.Sender?.Username}");
Console.WriteLine($"内容: {e.Message.Content}");
};
// 连接就绪事件
bot.Events.OnReady += async e =>
{
Console.WriteLine($"机器人已上线: {e.Self?.Username}");
};
// 成员变动事件
bot.Events.OnMemberChanged += async e =>
{
Console.WriteLine($"成员变动: {e.ChangeType}");
};
// 原始事件(访问协议特定数据)
bot.Events.OnRawEvent += async e =>
{
Console.WriteLine($"原始事件: {e.EventType}");
};var officialBot = bot as OfficialBotClient;
// 访问官方特定 API
await officialBot!.Api.GetGuildAsync("guild_id");
await officialBot.Api.MuteMemberAsync("guild_id", "user_id", 60);var oneBotClient = bot as OneBotClient;
// 调用 OneBot Action
await oneBotClient!.Actions.GetGroupListAsync();
await oneBotClient.Actions.BanGroupMemberAsync("group_id", "user_id", 60);如果你正在使用 v1.x 版本,可以逐步迁移:
Luolan.QQBot 包仍然可用Luolan.QQBot.OfficialQQBotClient 改为 OfficialBotClientQQBotClientBuilder 改为 OfficialBotClientBuilderEvents.OnMessageReceived