# 写在前面
本教程介绍如何使用 Jie2GG 的 SDK 编写原生酷 Q 插件。编写出的插件可以在各种酷 Q 兼容框架上运行。 跟随教程最终将编写出一个复读机
# 相关资源
- Visual Studio
- SDK Github
- cqp.cc
# 下载
- 安装
Visual Studio,本教程使用的为VS2022。需要具备基础的 C# 开发环境 - 在上方
相关资源-SDK Github-Release中下载最后一个版本,并解压![file]()
# 配置
# .net Framework 升级
在上一步解压出的文件中,打开
Native.sln,这是工程的解决方案文件。此时 VS 应当弹出弹窗,提示
.net Framework 4.5不受支持![file]()
点击右侧的继续,将所有项目的框架版本更新至
.net Framework 4.8弹出是否执行文本模板的提示,点击确定执行。此文本模板用于生成与酷 Q 框架对接的代码部分
![file]()
SDK 结构
![file]()
AppData.cs插件公用部分CQExport.tt文本模板,用于将app.json翻译为插件需要的代码app.json插件的描述文本,插件名称、版本、声明的事件均在此定义CQMain.cs事件注册入口,事件需要在这里注册才能被调用到Native.SdkSDK 主体部分,事件参数描述、API 调用以及 Dll 方法原型都在这里Native.Tool预先封装好的工具类,不需要时可以裁剪以减小插件文件大小- 此处为预先实现的 Http 工具类、Ini 配置工具类以及 Sqlite 数据库工具类
# 配置 AppID
AppID 为插件的唯一标识符,部分兼容框架会以此作为插件标识,重复可能导致不可预料的后果。
右键
Native.Core-属性编辑
程序集名称为你需要的 AppID,按Ctrl+S保存![file]()
AppID 拥有命名规则,但是由于酷 Q 已经不存在,所以也没那么严格,保证能用就行。大致规则是这样的:
- AppID 由两部分构成:个人网址倒写以及插件的名称
- 个人网址倒写:假如你的个人网站为
hellobaka.xyz,那么倒写就是xyz.hellobaka;若没有个人网站可以使用酷 Q 的个人首页:cqp.me,倒写也就是me.cqp。由于是通用网址,所以还需要加上作者的名称加以区分,也就变成了me.cqp.xxx - 插件名称:能够描述插件的作用。比如复读机可以叫做
Repeater,词云可以叫做WordCloud - 连在一起便构成了 AppID:
xyz.hellobaka.Repeaterme.cqp.luohuaming.WordCloud
# 配置 app.json
此文件为描述插件的名称、版本、作者、描述,以及已经实现的事件、窗口、悬浮窗说明和使用到的权限 ID。 Json 文件对格式敏感,使用带有语法提示或者格式检查的编辑器进行修改。
# 主节点
1 | { |
ret: 返回值。固定返回 1apiver: API 版本号。固定返回 9.name: 应用名称。该参数将被显示在酷 Q 的应用列表中version: 版本号。使用 x.x.x 形式。该参数将被显示在酷 Q 的应用列表中version_id: 版本号 ID。建议每次更新版本时该参数至少加 1.author: 应用作者。 该参数将会被显示在酷 Q 的应用列表中description: 应用描述。该参数将被显示在应用列表的详细信息处。建议在描述中添加触发应用的命令语句,方便用户上手。使用\r\n可以在应用描述中换行
# 事件节点
1 | "event": [ |
id: 事件唯一 ID, 整数类型 (Int32), 每个事件的唯一标识type: 事件类型,整数类型 (Int32), 用于标识每个事件在 SDK 中的实现方式 目前支持的事件列表如下:21: 私聊消息 如:好友消息,群临时私聊,讨论组临时私聊,临时消息2: 群聊消息4: 讨论组消息11: 群文件上传101: 群管理员变动 如:群管理员增加,群管理员减少102: 群成员减少 如:群成员退群,群成员被移除103: 群成员增加 如:群成员入群,群成员被邀请104: 群禁言处理 如:群成员被禁言,群成员被解除禁言201: 好友已添加301: 好友添加请求302: 群添加请求1001: 酷 Q 启动事件1002: 酷 Q 退出事件1003: 应用启用事件1004: 应用停用事件
name: 事件名称,字符串类型 (String), 每个事件的事件名称,该参数会被显示在酷 Q 的事件优先级调整器中function: 函数名称,字符串类型 (String), 事件在被酷 Q 调用时,约定好的函数名称。该函数将在 SDK 中定义priority: 调用优先级,整数类型 (Int32), 事件在被酷 Q 调用时,将依照相同事件的优先级,以从小到大的顺序调用插件。即数值越大,优先级越低。目前支持以下几种优先级:- 10000 最高:监控类应用,无法拦截消息 (如:消息统计等)
- 20000 高:消息控制类应用,可用于拦截消息 (如:机器人开关等)
- 30000 一般:普通功能类应用 (如:天气查询,游戏类等)
- 40000 低:聊天对话类应用
请按照实际情况选择优先级。如果一个事件需要不同的优先级执行,可以申请多个事件,并使用不同的 function 及 priority 。Native.SDK 会根据 Json 的定义生成需要的函数
regex: 正则消息过滤器,Json 对象类型 (JObject), 其定义方式为子 Json 节点。在 regex 节点中,包含以下两个部分:Key: 标识组,Json 数组类型 (JArray), 内部的元素由 "字符串 (String)" 组成,表示随后在 SDK 中获取该结果时使用的 idexpression: 正则表达式组,Json 数组类型 (JArray), 内部元素由 "字符串 (String)" 组成,表示酷 Q 用来匹配消息的正则表达式。
# 菜单节点
1 | "menu": [ |
name: 菜单名称,字符串类型 (String), 该字符串是显示在酷 Q 应用管理器菜单按钮下的项目,一个 Json 表示一个项目function: 函数名称,字符串类型 (String), 事件在被酷 Q 调用时,约定好的函数名称。该函数将在 SDK 中定义
# 悬浮窗节点
此节点几乎很少被使用,框架也很少实现,可留空
# 权限信息
1 | "auth": [ |
此处填写本插件需要使用的权限信息,不需要的权限删除
# 示例
本插件仅需使用 群消息处理 事件以及 发送群消息 权限,故修改后的 json 如下
1 | { |
部分框架不支持注释,建议还是删除所有注释
# 执行文本模板

# 尝试编译
在修改完 AppID 与 app.json 后,尝试编译一下项目,看看有没有报错。 
有类似输出即可认为通过,接下来就是编写插件逻辑部分
# 编写逻辑
# 创建 Code 项目
建议将插件逻辑与公用模块分开,故重新创建一个类库
# 创建项目



# 引用项目
新生成的项目需要引用 Sdk 项目
![file]()
![file]()
- 点击确定完成
# 实现接口
我们为了增加可维护性,将默认的 Class1.cs 重命名为 Event_GroupMessage.cs 标识这个文件内实现了 GroupMessage 事件
之后打开这个文件,在 Using 部分添加引用
1
2using Native.Sdk.Cqp.EventArgs;
using Native.Sdk.Cqp.Interface;在类名后添加接口
IGroupMessage,并添加默认接口实现1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17using Native.Sdk.Cqp.EventArgs;
using Native.Sdk.Cqp.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace xyz.Hellobaka.Repeater.Code
{
public class Event_GroupMessage : IGroupMessage
{
public void GroupMessage(object sender, CQGroupMessageEventArgs e)
{
throw new NotImplementedException();
}
}
}
# 注册接口
- 对
Core项目添加对Code项目的引用 - 打开
Native.Core-CQMain.cs - 添加 using 引用,
using xyz.Hellobaka.Repeater.Code; - 添加以下代码以实现接口注册
1 | public class CQMain |
# 编写逻辑
复读机,逻辑很简单,将收到的消息再发出去就是复读。 打开在上一步中创建的 Event_GroupMessage.cs 文件,在实现的接口部分添加以下代码:
1 | public void GroupMessage(object sender, CQGroupMessageEventArgs e) |
上面的代码即是我们刚才介绍的逻辑在代码上的实现,下面是讲解:
参数
e,为群消息事件的参数e.FromGroup是消息来源的群,里面包含了群号。e.FromGroup.Id即是群号e.Message是消息的类,里面包含了消息的文本、CQ 码与消息类型 (图片、语音)。.Text即是这个消息的文本e.CQApi表示根据这个参数创建的CQApi实例。此实例用于调用框架方法,比如:发送群消息、发送私聊消息、处理好友添加请求。此处使用了SendGroupMessage来发送群组消息,参数为群号与消息内容。注:
CQApi实例创建需要传递一个Authcode,此Authcode是由框架传递而来,不应当由用户创建,故需要使用参数传递来的或者使用在AppData中储存的CQAPI实例e.Handler表示了框架如何处理这个消息及以后的消息。True表示阻塞,本插件处理完成之后其他插件不再处理这个消息。False表示放行,本插件处理完成之后,其他插件仍会继续处理。
我们将这部分逻辑扩充一下,插件在返回消息时会发送群号以及发送者的 ID,之后再接上内容:
1 | public void GroupMessage(object sender, CQGroupMessageEventArgs e) |
好像短了很多呢。下面是讲解:
e.FromGroup是消息来源的群,里面包含了群号。SDK 对这个类进行了二次封装,添加了直接根据这个类调用 API 的方法,故可以直接.SendGroupMessage来发送消息e.Message是消息的类,里面包含了消息的文本、CQ 码与消息类型 (图片、语音)。.Text即是这个消息的文本$""为内插字符串- SDK 对常用类实现了转换方法,当需要时类可以不添加显式转换,会隐式转换为
long或string。故此处内插字符串时不需要.Id
# 生成发布
将
Native.Core项目重新生成在没有错误的情况下,即可认为是发布完成
打开生成目录,
Native.Core\bin\x86\Debug\xyz.Hellobaka.Repeater![file]()
app.dll与app.json即是生成的插件,文件没有必要叫这个,可以改成自己的 AppID。但是要求 dll 文件与 json 文件同名将插件放在框架中,进行功能测试:
注意,由于插件会复读所有收到的消息,如果你的机器人消息繁忙可能会引起一些问题,所以建议选择消息少的机器人或者对代码进行改造,添加群来源的限制:
1 | public void GroupMessage(object sender, CQGroupMessageEventArgs e) |









