EleCho.GoCqHttpSdk 1.0.0-alpha5

Prefix Reserved
This is a prerelease version of EleCho.GoCqHttpSdk.
There is a newer version of this package available.
See the version list below for details.
dotnet add package EleCho.GoCqHttpSdk --version 1.0.0-alpha5                
NuGet\Install-Package EleCho.GoCqHttpSdk -Version 1.0.0-alpha5                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="EleCho.GoCqHttpSdk" Version="1.0.0-alpha5" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add EleCho.GoCqHttpSdk --version 1.0.0-alpha5                
#r "nuget: EleCho.GoCqHttpSdk, 1.0.0-alpha5"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install EleCho.GoCqHttpSdk as a Cake Addin
#addin nuget:?package=EleCho.GoCqHttpSdk&version=1.0.0-alpha5&prerelease

// Install EleCho.GoCqHttpSdk as a Cake Tool
#tool nuget:?package=EleCho.GoCqHttpSdk&version=1.0.0-alpha5&prerelease                

<div align="center"> <img src="logo.png" width="200"/>

EleCho.GoCqHttpSdk

✨ 专为 Go-CqHttp 打造的, 便捷与优雅的通信 SDK ✨

LICENSE nuget

</div>

📖 简介:

虽然有很多的 OneBot 通信 SDK, 但没有一个是专为 go-cqhttp 打造的 .NET SDK. 秉持着 C# 的优雅开发理念, 这个库诞生了.

用户可以享受到完全遵守 C# 编码风格, 高度封装的各种接口, 以及优化过命名的接口, 事件, 数据成员, 枚举类型等.

如果你不了解 go-cqhttp, 可以从这里了解一下: go-cqhttp 文档 / go-cqhttp 仓库

🚀 使用:

你可以在 nuget.org 下载到本库的发布包, 也可以直接在 Visual Studio 中为项目添加引用.

目前库仍处于开发阶段, 你需要勾选 "包含预发布版本" 才能搜索到结果

通信协议支持: 正反向 HTTP 与正向 WebSocket.
上报格式支持: array(json), string.
功能支持: CqCode 转码, API 快速操作
设计模式: 上报为中间件模式, 同时也支持基于中间件的插件

🔗 连接

要与 go-cqhttp 建立一个 WebSocket 连接, 需要使用位于 EleCho.GoCqHttpSdk 命名空间下的 CqWsSession 来创建一个会话

// 初始化一个 CqWsSession 用来与 go-cqhttp
CqWsSession session = new CqWsSession(new CqWsSessionOptions()
{
    BaseUri = new Uri("ws://127.0.0.1:6700"),  // WebSocket 地址
    UseApiEndPoint = true,                     // 使用 api 终结点
    UseEventEndPoint = true,                   // 使用事件终结点
});
session.Start(); //开始连接

指定 UseApiEndPointUseEventEndPoint 将使用独立的 api 和 event 套接字来单独处理功能调用以及事件处理 参考文档: Onebot11:正向WebSocket

📩 上报

上报数据也就是所谓的 "事件", 所有继承了 EleCho.GoCqHttpSdk.ICqPostSession 接口的类都将处理上报数据, 该接口规定必须要有一个名为 PostPipelineCqPostPipeline 成员

CqPostPipeline 是用户处理上报的途径, 它符合中间件设计模型, 你可以直接使用使用它添加中间件.

CqWsSession session;   // 要处理上报数据的会话
session.PostPipeline.Use(async (context, next) =>
{
    // context 为上报数据的上下文, 其中包含了具体的信息
    
    // 在这里添加你的逻辑代码 //
    
    // next 是中间件管道中的下一个中间件, 
    // 如果你希望当中间件执行时, 不继续执行下一个中间件
    // 可以选择不执行 next
    await next();
});

上述订阅方法将会处理所有的上报, 我们更推荐使用 EleCho.GoCqHttpSdk.CqPostContextExtensions 类所提供的拓展方法, 通过它你可以非常便捷的处理任何具体类型的事件

CqWsSession session;   // 要处理上报数据的会话
session.PostPipeline.UseGroupMessage(async (context, next) =>
{
    // context 为 CqGroupMessagePostContext, 其中包含了群聊消息的具体信息
    
    // 在这里添加你的逻辑代码 //
    
    // 简单实现一个复读机:
    if (context.RawMessage.StartsWith("echo "))
    {
        string msg = context.RawMessage.SubString(5);                  // 获取 "echo " 后的字符
        context.SendGroupMessageAsync(context.GroupId, new CqTextMsg(msg)); // 发送它 (关于消息发送后面会详细讲解)
    }
    
    await next();
});

📝 消息发送

所有继承了 EleCho.GoCqHttpSdk.ICqActionSession 接口的类都将具备使用 Action 的能力, 消息发送属于 Action, 该接口规定必须有一个名为 ActionSenderCqActionSender 成员

CqActionSender 是程序向 go-cqhttp 发送 "Action" 的途径, 其中需要实现 CqAction 的发送逻辑以及响应逻辑, 你可以直接使用它来调用任何 CqAction

CqWsSession session;   // 要使用 Action 的会话
session.ActionSender.SendActionAsync(new CqSendGroupMessageAction(群聊ID, new CqMsg[] { new CqTextMsg("一个文本消息") }));

可以看到, 使用 session.ActionSender 直接发送 Action 的步骤比较繁琐, 所以同样的, 推荐使用拓展方法, 它们由 EleCho.GoCqHttpSdk.CqActionSessionExtensions 提供.

CqWsSession session;   // 要使用 Action 的会话
context.SendGroupMessageAsync(群聊ID, new CqTextMsg("一个文本消息")); // 发送它 (关于消息发送后面会详细讲解)

EleCho.GoCqHttpSdk.CqActionSessionExtensions 类不直接为 CqActionSender 类提供拓展, 你只能在实现了 ICqActionSession 接口的类上调用这些拓展方法

📦 使用插件

在本库中, 你可以为能够进行上报的会话添加插件, 它本质还是一个中间件, 但是插件中, 它分离了所有类型的上报. 如果要处理某种类型的上报, 只需要 override 对应的方法即可.

class MyPostPlugin : CqPostPlugin
{
    public override async Task OnGroupMessageAsync(CqGroupMessagePostContext context)
    {
        if (context.Session is not ICqActionSession actionSession)   // 判断是否能够发送 Action
            return;
        
        string text = context.Message.GetText();
        if (text.StartsWith("TTS:", StringComparison.OrdinalIgnoreCase))
        {
            await actionSession.SendGroupMessageAsync(context.GroupId, new CqTtsMsg(text[4..]));
        }
        else if (text.StartsWith("ToFace:"))
        {
            if (CqFaceMsg.FromName(text[7..]) is CqFaceMsg face)
            
            await actionSession.SendGroupMessageAsync(context.GroupId, face);
        }
    }

    public override async Task OnGroupMessageRecalledAsync(CqGroupMessageRecalledPostContext context)
    {
        if (context.Session is not ICqActionSession actionSession)   // 判断是否能够发送 Action
            return;

        var msg = (await actionSession.GetMessageAsync(context.MessageId));

        await actionSession.SendGroupMessageAsync(context.GroupId, CqMsg.Chain("让我康康你撤回了什么: ", msg.Message));
    }
}

它的使用也非常简单, 只需要在会话上调用 UsePlugin 方法即可

session.UsePlugin(new MyPostPlugin());

与 ICqPostSession 的拓展方法 Use 不同, 一个插件拥有处理多种类型上报的能力, 但它本质是单个中间件, 而诸如 UseGroupMessage 这种拓展方法, 在使用的时候, 会创建一个新的中间件并添加到上报处理管线.

📎 小提示

  1. CqMsg 类中包含了对于消息的一写帮助方法, 例如将多个 CqMsg 拼合为一个 CqMsg[], 或者从 CQ 码转换为 CqMsg[]
  2. CqFaceMsg 是 QQ 小黄脸消息, 它还提供了从中文名称转换为对应类型的方法, 例如 "斜眼笑", "可怜" 等中文名称.
  3. 上报中的 QuickOperation 是不推荐使用的, 除非你使用的是反向 HTTP, 这是因为在 WebSocket 中, 快速操作是模拟出来的

📃 近期计划:

  1. 实现反向 WebSocket 通信
  2. 实现所有 Action

🧬 项目

💼 关于数据结构

因为 go-cqhttp 给的数据, JSON 都是小驼峰, 并且为了用户操作上的便捷, 所以 JSON 解析上使用了以下方法:

  1. 分为用户的操作类和具体调用时使用的 Model 类
  2. 在调用接口, 或者解析上报的时候, 两种类会相互转换
  3. 一些原始 Model 类中的 data 字段, 或者 params 字段, 他们在用户的操作类中直接作为类型成员存在, 而不独立分出一个 dataparams 成员存放.

同时, 为了用户操作的便捷, 用户所操作的类与实际传输使用的类, 字段格式是不一样的, 例如在 Music 消息中 sub_type 表示该 Music 消息的音乐类型, 于是在用户的操作类中, 它使用 MusicType 命名.

📄 消息

首先是 go-cqhttp 中的基础消息类型, 也就是 CQ 码(CQ Code):

它的 JSON 格式是这样的:

{
    "type": "消息类型",
    "data": {
        // 消息的数据
    }
}

如果让用户访问 data 然后访问它的成员, 肯定有些繁琐, 所以在用户操作的类中, 是这样的:

public class CqXxxMsg : CqMsg
{
    public override string Type => "消息类型";  // Type 是不允许用户修改的, 一个类型对应一个 Type
    
    // 直接将消息数据作为消息的成员
}
📥 上报

上报的原始数据 JSON 格式中, 并没有专门为数据抽出一个 data 字段, 所以不做特殊处理.

✋ Action

Action 在 go-cqhttp 中的 JSON 格式与消息类似, 它为参数抽出了一个 params 字段, 然后将所有参数放在这个字段中. 所以在这方面, 做了与消息类型近似的处理, 也就是直接将参数独立出来, 而不是放在 params 字段中.

同样, ActionResult(Action 调用的返回结果) 也将数据放在了 data 字段中, 所以同样做了特殊处理.

🎉 贡献

关于任何对项目上的意见, 例如命名, 设计模式, 或者其他任何方面的问题, 直接提交一个 discussion 就可以啦, 然后咱们就可以讨论讨论具体要采取什么措施啦. ψ(`∇´)ψ

如果你有什么好的想法, 也可以直接提交一个 PR, 我们一起来完善这个项目吧!

球球了, 有问题请直接提出来, 不要犹豫, 咱真的很需要用户意见, 尤其是如何提升这个库的 "优雅程度".

📚 编写规范

下面是编写时可能提供帮助的一些规范:

虽然库的有些内部代码真的很丑(例如命名), 但这是为了外部访问的便捷而做出的妥协, 实属无奈之举.

🗂️ 各个文件夹的内容
  • /Action : 用户要使用到的各种 CqAction
  • /Action/Sender : 用来发送 CqAction 的各个协议实现
  • /Action/Model/Params : CqAction 进行调用时所需要的具体参数 (用户不可见)
  • /Action/Result : 用户要使用到的各种 CqActionResult
  • /Action/Result/Model/Data : CqActionResult 返回时要读取的具体数据 (用户不可见)
  • /DataStructure : CqAction 参数或返回数据中所使用到的各种结构
  • /DataStructure/Model : CqAction 参数或返回数据中所使用到的各种结构的实际传输声明 (用户不可见)
  • /Enumeration : 各种枚举类型
  • /Extension : 各种拓展方法
  • /JsonConverter : 程序集所需要使用的 JSON 转换器 (用户不可见)
  • /Message : 用户会用到的各种消息类型
  • /Message/CqCodeDef : CQ 码操作类
  • /Message/DataModel : 消息的实际传输数据模型 (用户不可见)
  • /Message/JsonConverter : 某些特殊消息需要使用到的 JSON 转换器 (用户不可见)
  • /Post : 消息上报的各种类型
  • /Utils : 各种工具类
  • / : 被用户直接访问, 不需要进行归类的内容
🛠️ 编写步骤

编写一个 Action 的参考步骤:

  1. 添加 CqActionType 成员
  2. 添加 Consts.ActionType 成员
  3. CqEnum 中实现 CqActionType 转字符串
  4. 编写它的 CqAction
  5. 编写它的 CqActionParamsModel 类 (internal, 有一个全参构造函数, 成员名称为原始名称)
  6. 编写它的 CqActionResult 类 (不能有公开构造函数, 因为用户不能创建它的实例)
  7. 编写它的 CqActionResultDataModel 类 (internal, 只有 JSON 构造函数, 成员名称为原始名称)
  8. 实现 CqActionResult.FromRaw
  9. 实现 CqActionResultDataModel.FromRaw
  10. CqActionSessionExtensions 中添加对应拓展方法

编写一个 CqMsg 的参考步骤:

  1. 添加 CqMsgType 成员
  2. 编写它的 CqMsg
  3. 编写它的 CqMsgDataModel 类 (internal, 一个无参构造函数, 一个全参构造函数)
  4. 实现它在 CqMsgModelConverter 中的转换
  5. 实现它在 CqCode.ModelChainFromCqCodeString 中的转换
📃 命名规范
  • 尽量将缩写改为全称, 尽量将奇怪的名称改为正常的名称
    例如: SetGroupBan → BanGroupMember (禁言群成员)
  • 尽量将错误的名称改为正确的名称
    例如: CheckUrlSafely → CheckUrlSafety (检查链接安全性)
📎 类型声明提示
  • 在原文档中以 number 标识的类型, 统一使用 long, 否则可能会溢出
  • 在原文档中, 消息 ID 有的地方声明为 int32, 有的地方声明为 int64, 在本库中, 将统一使用 int64
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 is compatible. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 is compatible.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on EleCho.GoCqHttpSdk:

Package Downloads
EleCho.GoCqHttpSdk.MessageMatching

EleCho.GoCqHttpSdk 的消息匹配拓展

EleCho.GoCqHttpSdk.CommandExecuting

EleCho.GoCqHttpSdk 的指令执行拓展

GitHub repositories (3)

Showing the top 3 popular GitHub repositories that depend on EleCho.GoCqHttpSdk:

Repository Stars
yiyungent/KnifeHub
🧰 简单易用的效率工具平台
GardenHamster/Theresa3rd-Bot
一个QQ群聊机器人,基于Mirai和GoCQHttp,包括 Pixiv搜索、Pixiv推送、Pixiv日榜、词云、定时提醒、复读机等功能
Alex1911-Jiang/GreenOnions
一个Mirai的QQ机器人, 实现了搜图, RSS订阅转发, 根据PixivID下载原图, 翻译, setu等功能
Version Downloads Last updated
1.3.0 167 8/21/2024
1.2.6 149 8/18/2024
1.2.5 363 12/27/2023
1.2.4 418 9/20/2023
1.2.3 156 9/15/2023
1.2.2 303 7/17/2023
1.2.1 235 7/15/2023
1.2.0 221 7/13/2023
1.1.2 345 6/8/2023
1.1.1 185 6/8/2023
1.1.0 177 6/5/2023
1.0.14 290 5/19/2023
1.0.13 257 5/12/2023
1.0.12 261 4/11/2023
1.0.11 293 3/23/2023
1.0.10 281 3/19/2023
1.0.9 586 3/19/2023
1.0.8 370 3/12/2023
1.0.7 301 3/11/2023
1.0.6 300 3/8/2023
1.0.5 309 2/27/2023
1.0.4 284 2/26/2023
1.0.3 284 2/26/2023
1.0.2 266 2/23/2023
1.0.1 406 2/13/2023
1.0.0 876 2/12/2023
1.0.0-alpha6 233 2/4/2023
1.0.0-alpha5 143 2/4/2023
1.0.0-alpha4 185 1/16/2023
1.0.0-alpha3 166 1/15/2023
1.0.0-alpha2 139 1/13/2023
1.0.0-alpha1 193 5/17/2022