-
Notifications
You must be signed in to change notification settings - Fork 16
2. 使用 SDK
在上一节中, 我们讲到, 要制作一个 QQ 机器人, 我们需要与 Go-CqHttp 进行通信. 然而, Go-CqHttp 的操作接口与上报数据如此多, 如果我们从 0 开始开发, 肯定会遇到诸多困难.
使用 EleCho.GoCqHttpSdk 是极其便捷的, 你只需要为你的项目添加 EleCho.GoCqHttpSdk 包引用即可. 剩下的, 就是享受 SDK 为你带来的舒适与便捷了.
Go-CqHttp 支持四种通信, EleCho.GoCqHttpSdk 拥有对它们的完全支持:
- 正向 HTTP (机器人程序向 Go-CqHttp 发送 HTTP 请求实现执行操作)
- 反向 HTTP (Go-CqHttp 向机器人程序发送 HTTP 请求实现消息上报)
- 正向 WebSocket (机器人程序通过 WebSocket 连接到 Go-CqHttp 进行双向通信, 执行操作或消息上报)
- 反向 WebSocket (和正向 WebSocket 一样, 只不过是由 Go-CqHttp 连接到机器人程序)
建立一个 WebSocket 会话, 你可以使用下面的代码:
// 初始化一个 CqWsSession 用来与 Go-CqHttp 通信
CqWsSession session = new CqWsSession(new CqWsSessionOptions()
{
BaseUri = new Uri("ws://127.0.0.1:6700"), // WebSocket 地址
});
session.Start(); // 开始连接 (你也可以使用它的异步版本)
因为 WebSocket 会话是双向的, 并且是长连接, 所以在实际使用中, 更推荐 WebSocket 会话
要执行一个操作, 例如发送一条消息, 你需要一个 能够执行操作 的会话, 例如 HTTP 会话和 WebSocket. 然后只需要使用它的 ActionSender
来执行操作即可. 下面是一个简单的操作:
// 新建一个发送私聊消息的操作
CqSendPrivateMessageAction action = new CqSendPrivateMessageAction(114514, new CqMessage("这是一条文本消息"));
// 执行操作
CqActionResult? rst = await session.ActionSender.InvokeActionAsync(action);
其中, rst
是 Action 的响应结果, 虽然你得到的是一个 CqActionResult
, 但是你可以将它强转为对应具体的结果类型. 例如这样:
// 从父类转换为子类
CqSendPrivateMessageActionResult? msgRst = (CqSendPrivateMessageActionResult?)rst;
不过, 注意, 之所以你可以这么转换, 是因为执行 "发送私聊消息" 这个操作的时候, 它返回的就是一个 "发送私聊消息操作结果", 它们是一一对应的, 如果你将它转换为 CqSendGroupMessageActionResult
, 那肯定是会出问题的, 因为它不是那样的实例.
很明显, 上面的操作十分繁琐, 我们也不推荐这样使用, 你可以使用 IActionSession
的拓展方法来直接执行特定操作, 并得到特定结果:
// 通过拓展方法直接进行调用
CqSendPrivateMessageActionResult? rst = await session.SendPrivateMessageAsync(114514, new CqMessage("这是一条文本消息"));
拓展方法内部帮你完成了上述繁琐的过程, 并自动将结果转换为了你想要类型的结果.
对于反向 HTTP 会话和 WebSocket 会话, 你可以拿到来自 Go-CqHttp 的上报数据, 并进行处理. 下面是一个最基础的, 处理群聊消息的逻辑:
// 在上报管线中, 添加自己的中间件
session.PostPipeline.Use(async (context, next) =>
{
// 判断上报是否是一个群消息上报
if (context is CqGroupMessagePostContext groupMessagePostContext)
{
// 在这个消息所在的群中发送一条消息 "检测到这个群发送了一条消息"
await session.SendGroupMessageAsync(groupMessagePostContext.GroupId, new CqMessage("检测到这个群发送了一条消息"));
}
// 这里你可以放任何你想要的逻辑
await next.Invoke(); // 执行下一个中间件
});
上面的代码中, 我们需要手动判断它的上报类型, 十分繁琐, 我们也不推荐这么使用, 你可以使用 IPostSession
提供的拓展方法来直接对特定类型的上报执行操作:
// 直接添加一个仅处理群消息上报的中间件
session.UseGroupMessage(async (context, next) =>
{
await session.SendGroupMessageAsync(context.GroupId, new CqMessage("检测到这个群发送了一条消息"));
await next.Invoke(); // 执行下一个中间件
});
同理, 其他类型的上报, 也可以使用拓展方法来快速添加处理逻辑.
中间件可以理解为一堆处理数据中的逻辑中的一个, 它可以具备 "拦截" 的功能, 例如上面的代码中, 在最后一句总有一个
await next.Invoke();
这个就是执行处理逻辑中下一个中间件的意思. 如果你不想这个数据继续被其他的中间件处理, 你可以不调用next.Invoke
.
EleCho.GoCqHttpSdk