@karinjs/adapter-qqbot 1.2.10 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +869 -84
  2. package/dist/chunk-PYOUSZ6B.js +1501 -0
  3. package/dist/index.d.ts +499 -0
  4. package/dist/index.js +100 -0
  5. package/dist/web.config.d.ts +25 -0
  6. package/dist/web.config.js +224 -0
  7. package/package.json +22 -15
  8. package/config/comment/config.json +0 -3
  9. package/config/config/config.yaml +0 -53
  10. package/lib/cli/pr.d.ts +0 -2
  11. package/lib/cli/pr.js +0 -73
  12. package/lib/core/adapter/adapter.d.ts +0 -91
  13. package/lib/core/adapter/adapter.js +0 -144
  14. package/lib/core/adapter/handler.d.ts +0 -49
  15. package/lib/core/adapter/handler.js +0 -140
  16. package/lib/core/adapter/markdown.d.ts +0 -38
  17. package/lib/core/adapter/markdown.js +0 -220
  18. package/lib/core/adapter/normal.d.ts +0 -30
  19. package/lib/core/adapter/normal.js +0 -263
  20. package/lib/core/api/index.d.ts +0 -167
  21. package/lib/core/api/index.js +0 -180
  22. package/lib/core/api/sign.d.ts +0 -22
  23. package/lib/core/api/sign.js +0 -40
  24. package/lib/core/api/types.d.ts +0 -236
  25. package/lib/core/api/types.js +0 -1
  26. package/lib/core/event/conver.d.ts +0 -10
  27. package/lib/core/event/conver.js +0 -57
  28. package/lib/core/event/index.d.ts +0 -9
  29. package/lib/core/event/index.js +0 -98
  30. package/lib/core/event/message.d.ts +0 -27
  31. package/lib/core/event/message.js +0 -95
  32. package/lib/core/event/notice.d.ts +0 -50
  33. package/lib/core/event/notice.js +0 -133
  34. package/lib/core/event/types.d.ts +0 -473
  35. package/lib/core/event/types.js +0 -1
  36. package/lib/core/internal/axios.d.ts +0 -25
  37. package/lib/core/internal/axios.js +0 -46
  38. package/lib/core/internal/sign.d.ts +0 -22
  39. package/lib/core/internal/sign.js +0 -40
  40. package/lib/core/webhook/c2c.d.ts +0 -2
  41. package/lib/core/webhook/c2c.js +0 -14
  42. package/lib/core/webhook/http.d.ts +0 -2
  43. package/lib/core/webhook/http.js +0 -35
  44. package/lib/core/webhook/index.d.ts +0 -17
  45. package/lib/core/webhook/index.js +0 -87
  46. package/lib/core/webhook/ws.d.ts +0 -2
  47. package/lib/core/webhook/ws.js +0 -79
  48. package/lib/index.d.ts +0 -1
  49. package/lib/index.js +0 -5
  50. package/lib/root.d.ts +0 -5
  51. package/lib/root.js +0 -9
  52. package/lib/types/config.d.ts +0 -53
  53. package/lib/types/config.js +0 -1
  54. package/lib/utils/common.d.ts +0 -80
  55. package/lib/utils/common.js +0 -198
  56. package/lib/utils/config.d.ts +0 -9
  57. package/lib/utils/config.js +0 -54
  58. package/lib/utils/dir.d.ts +0 -1
  59. package/lib/utils/dir.js +0 -1
  60. package/lib/utils/index.d.ts +0 -4
  61. package/lib/utils/index.js +0 -4
@@ -0,0 +1,499 @@
1
+ import FormData from 'form-data';
2
+ import * as axios from 'axios';
3
+ import { karinToQQBot, AdapterBase, LogMethodNames, Contact, ButtonElement, KeyboardElement, MarkdownElement, MarkdownTplElement, SendMsgResults } from 'node-karin';
4
+
5
+ /**
6
+ * @description 创建axios实例
7
+ * @param url 请求地址
8
+ * @param appId 机器人ID
9
+ */
10
+ declare const createAxiosInstance: (url: string, appId: string) => axios.AxiosInstance;
11
+
12
+ /** 上传富媒体文件场景 */
13
+ type Scene = 'user' | 'group';
14
+ /** 上传富媒体文件类型 */
15
+ type MediaType = 'image' | 'video' | 'record' | 'file';
16
+ /** 发送QQ消息请求参数基类 */
17
+ interface SendQQMessageRequest {
18
+ /** 消息类型:0 是文本,2 是 markdown, 3 ark,4 embed,7 media 富媒体 */
19
+ msg_type: 0 | 2 | 3 | 4 | 7;
20
+ }
21
+ /** 发送QQ被动消息参数 */
22
+ interface QQMessageID {
23
+ /** 前置收到的事件 ID,用于发送被动消息,支持事件:"INTERACTION_CREATE"、"C2C_MSG_RECEIVE"、"FRIEND_ADD" */
24
+ event_id?: string;
25
+ /** 前置收到的用户发送过来的消息 ID,用于发送被动(回复)消息 */
26
+ msg_id?: string;
27
+ /** 回复消息的序号,与 msg_id 联合使用,避免相同消息id回复重复发送,不填默认是1。相同的 msg_id + msg_seq 重复发送会失败。 */
28
+ msg_seq?: number;
29
+ }
30
+ /** 发送QQ文本消息请求参数 */
31
+ interface SendQQTextMessageRequest extends SendQQMessageRequest, QQMessageID {
32
+ msg_type: 0;
33
+ /**
34
+ * 消息内容 支持如下内嵌格式
35
+ * - `<qqbot-at-user id="" />` `@用户` **注意双引号不能省略**
36
+ * - `<qqbot-at-everyone />` `@所有人`
37
+ */
38
+ content: string;
39
+ }
40
+ /** markdown消息结构 */
41
+ type Markdown = {
42
+ /** markdown 文本 */
43
+ content: string;
44
+ } | {
45
+ /** markdown 模版id,申请模版后获得 */
46
+ custom_template_id: string;
47
+ /** 模版内变量与填充值的kv映射 */
48
+ params: {
49
+ key: string;
50
+ values: string[];
51
+ }[];
52
+ };
53
+ /** 按钮消息结构 */
54
+ type Keyboard = {
55
+ content: {
56
+ rows: ReturnType<typeof karinToQQBot>;
57
+ };
58
+ } | {
59
+ /** 按钮模版id */
60
+ id: string;
61
+ };
62
+ /** 发送QQ Markdown 消息请求参数 */
63
+ interface SendQQMarkdownMessageRequest extends SendQQMessageRequest, QQMessageID {
64
+ msg_type: 2;
65
+ /**
66
+ * markdown 消息内容 支持如下内嵌格式
67
+ * - `<qqbot-cmd-enter text="xxx" />` `回车按钮: 点击后,文本直接发送`
68
+ * - `<qqbot-cmd-input text="xxx" show="xxx" reference="false" />` `点击后,文本输入框弹出`
69
+ * - `text 用户点击后插入输入框的文本,参数必填,最大限制 100 字符,传值时需要 urlencode`
70
+ * - `show 用户在消息内看到的文本,参数选填,默认取 text 值,最大限制 100 字符,传值时需要 urlencode。`
71
+ * - `reference 插入输入框时是否带消息原文回复引用,参数选填,默认为 false,填入 true 时则带引用回复到输入框中。`
72
+ *
73
+ * {@link https://bot.q.qq.com/wiki/develop/api-v2/server-inter/message/trans/text-chain.html}
74
+ */
75
+ markdown: Markdown;
76
+ /** 按钮 */
77
+ keyboard?: Keyboard;
78
+ }
79
+ /** 发送QQ Ark 消息请求参数 */
80
+ interface SendQQArkMessageRequest extends SendQQMessageRequest, QQMessageID {
81
+ msg_type: 3;
82
+ /** ark 消息内容 */
83
+ ark: {
84
+ /** ark 模版id */
85
+ template_id: number;
86
+ /** 模版内变量与填充值的kv映射 tips: 未经测试 先any */
87
+ kv: any[];
88
+ };
89
+ }
90
+ /** 发送QQ Embed 消息请求参数 文档没看到发送接口 */
91
+ /** 发送QQ Media 消息请求参数 */
92
+ interface SendQQMediaMessageRequest extends SendQQMessageRequest, QQMessageID {
93
+ msg_type: 7;
94
+ /** media 消息内容 */
95
+ media: {
96
+ /** 文件信息,用于发消息接口的 media 字段使用 */
97
+ file_info: string;
98
+ };
99
+ /** 当 msg_type = 7 时,content 字段需要填入一个值,譬如一个空格 “ ”,后续版本会修复该问题。 */
100
+ content: string;
101
+ }
102
+ /** 发送QQ消息请求参数 */
103
+ type SendQQMsg = SendQQTextMessageRequest | SendQQMarkdownMessageRequest | SendQQArkMessageRequest | SendQQMediaMessageRequest;
104
+ /** 发送频道被动消息参数 */
105
+ interface SendGuildMessageID {
106
+ /** 消息ID */
107
+ msg_id?: string;
108
+ /** 事件id */
109
+ event_id?: string;
110
+ }
111
+ /** 发送频道引用消息参数 */
112
+ interface SendGuildQuoteMessage {
113
+ /** 引用消息的ID */
114
+ message_id?: string;
115
+ /** 是否忽略获取引用消息详情错误,默认否 */
116
+ ignore_get_message_error?: boolean;
117
+ }
118
+ /** 发送频道消息请求参数基类 */
119
+ interface SendGuildMessageRequest {
120
+ /** 单独加一个类型 用于区分不同的消息类型 */
121
+ type: 'text' | 'image' | 'embed' | 'ark' | 'markdown';
122
+ }
123
+ /** 发送频道 文本 消息请求参数 */
124
+ interface SendGuildTextMessageRequest extends SendGuildMessageID, SendGuildQuoteMessage, SendGuildMessageRequest {
125
+ type: 'text';
126
+ /**
127
+ * 消息内容 支持如下内嵌格式
128
+ * - `<@user_id>` `@用户`
129
+ * - `@everyone` `@所有人`
130
+ * - `<#channel_id>` `#子频道`
131
+ * - `<emoji:id>` `表情`
132
+ */
133
+ content: string;
134
+ /** 图片url地址 */
135
+ image?: string;
136
+ }
137
+ /** 发送频道 图片 消息请求参数 */
138
+ interface SendGuildImageMessageRequest extends SendGuildMessageID, SendGuildQuoteMessage, SendGuildMessageRequest {
139
+ type: 'image';
140
+ /** 图片url地址 */
141
+ image: string;
142
+ }
143
+ /** embeds消息结构 */
144
+ interface Embeds {
145
+ /** 标题 */
146
+ title: string;
147
+ /** 消息弹窗内容 */
148
+ prompt: string;
149
+ /** 缩略图 */
150
+ thumbnail: {
151
+ /** 图片地址 */
152
+ url: string;
153
+ };
154
+ /** embed 字段数据 */
155
+ fields: Record<string, any>[];
156
+ }
157
+ /** 发送频道 embed 消息请求参数 */
158
+ interface SendGuildEmbedMessageRequest extends SendGuildMessageID, SendGuildMessageRequest {
159
+ type: 'embed';
160
+ /** embed 消息内容 */
161
+ embed: Embeds;
162
+ }
163
+ /** ark消息结构 */
164
+ interface Ark {
165
+ /** 模版id */
166
+ template_id: number;
167
+ /** 模版内变量与填充值的kv映射 */
168
+ kv: {
169
+ key: string;
170
+ value: string;
171
+ /** 这个嵌套是认真的嘛... */
172
+ obj: {
173
+ obj_kv: {
174
+ key: string;
175
+ value: string;
176
+ }[];
177
+ }[];
178
+ }[];
179
+ }
180
+ /** 发送频道 ark 消息请求参数 */
181
+ interface SendGuildArkMessageRequest extends SendGuildMessageID, SendGuildMessageRequest {
182
+ type: 'ark';
183
+ /** ark 消息内容 */
184
+ ark: Ark;
185
+ }
186
+ /** 发送频道 markdown 消息请求参数 */
187
+ interface SendGuildMarkdownMessageRequest extends SendGuildMessageID, SendGuildMessageRequest {
188
+ type: 'markdown';
189
+ /** markdown 消息内容 */
190
+ markdown: Markdown;
191
+ /** 按钮 */
192
+ keyboard?: Keyboard;
193
+ }
194
+ /** 发送频道消息请求参数 */
195
+ type SendGuildMsg = SendGuildTextMessageRequest | SendGuildImageMessageRequest | SendGuildEmbedMessageRequest | SendGuildArkMessageRequest | SendGuildMarkdownMessageRequest;
196
+ /** 获取当前机器人详情接口响应 */
197
+ interface GetMeResponse {
198
+ /** 机器人的频道ID */
199
+ id: string;
200
+ /** 机器人的昵称 */
201
+ username: string;
202
+ /** 用户头像 */
203
+ avatar: string;
204
+ /** 特殊关联应用的 openid */
205
+ union_openid: string;
206
+ /** 机器人关联的互联应用的用户信息 */
207
+ union_user_account: string;
208
+ /** 机器人的分享url */
209
+ share_url: string;
210
+ /** 机器人介绍 */
211
+ welcome_msg: string;
212
+ }
213
+ /** 创建私信会话接口响应 */
214
+ interface DmsResponse {
215
+ /** 频道ID 用于私信会话使用 */
216
+ guild_id: string;
217
+ /** 子频道ID 用于私信会话使用 */
218
+ channel_id: string;
219
+ /** 创建时间 */
220
+ create_time: string;
221
+ }
222
+ /** 发送QQ消息后响应 */
223
+ interface SendQQMsgResponse {
224
+ /** 消息唯一 ID */
225
+ id: string;
226
+ /** 发送时间 */
227
+ timestamp: number;
228
+ }
229
+ /** 发送频道消息后响应 */
230
+ interface SendGuildResponse {
231
+ /** 消息唯一 ID */
232
+ id: string;
233
+ /** 发送时间 ISO8601 timestamp */
234
+ timestamp: string;
235
+ }
236
+ /** 上传富媒体文件响应 */
237
+ interface UploadMediaResponse {
238
+ /** 文件 ID */
239
+ file_uuid: string;
240
+ /** 文件信息,用于发消息接口的 media 字段使用 */
241
+ file_info: string;
242
+ /** 有效期,表示剩余多少秒到期,到期后 file_info 失效,当等于 0 时,表示可长期使用 */
243
+ ttl: number;
244
+ /** 发送消息的唯一ID,当srv_send_msg设置为true时返回 */
245
+ id: string;
246
+ }
247
+
248
+ declare class QQBotApi {
249
+ /** axios 实例 */
250
+ axios: ReturnType<typeof createAxiosInstance>;
251
+ constructor(axios: ReturnType<typeof createAxiosInstance>);
252
+ /**
253
+ * 发送get请求
254
+ * @param path 请求路径
255
+ * @returns 请求结果
256
+ */
257
+ get<T>(path: string): Promise<T>;
258
+ /**
259
+ * 发送post请求
260
+ * @param path 请求路径
261
+ * @param options 请求数据
262
+ * @param headers 请求头
263
+ */
264
+ post<T>(path: string, options?: {}, headers?: Record<string, string>): Promise<T>;
265
+ /**
266
+ * 处理请求错误
267
+ * @param error 错误信息
268
+ */
269
+ handleError(path: string, options: any, error: any): void;
270
+ /**
271
+ * 发送单聊消息
272
+ * @param targetId 目标QQ用户的 openid
273
+ * @param options 消息参数
274
+ */
275
+ sendFriendMsg(targetId: string, options: SendQQMsg): Promise<SendQQMsgResponse>;
276
+ /**
277
+ * 发送群聊消息
278
+ * @param targetId 目标QQ群的 openid
279
+ * @param options 消息参数
280
+ */
281
+ sendGroupMsg(targetId: string, options: SendQQMsg): Promise<SendQQMsgResponse>;
282
+ /**
283
+ * 构建QQBot文本消息参数
284
+ * @param content 消息文本内容
285
+ */
286
+ QQdMsgOptions(type: 'text', content: string): SendQQTextMessageRequest;
287
+ /**
288
+ * 构建Markdown消息参数
289
+ * @param markdown Markdown文本内容
290
+ * @param keyboard 按钮
291
+ */
292
+ QQdMsgOptions(type: 'markdown', markdown: Markdown, keyboard?: Keyboard): SendQQMarkdownMessageRequest;
293
+ /**
294
+ * 构建Ark消息参数
295
+ * @param ark Ark参数
296
+ */
297
+ QQdMsgOptions(type: 'ark', ark: SendQQArkMessageRequest['ark']): SendQQArkMessageRequest;
298
+ /**
299
+ * 构建Media消息参数
300
+ * @param file 文件信息
301
+ */
302
+ QQdMsgOptions(type: 'media', file: string): SendQQMediaMessageRequest;
303
+ /**
304
+ * 构建频道文本、文本图片消息参数
305
+ * @param type 消息类型
306
+ * @param content 消息内容
307
+ * @param image 图片url
308
+ */
309
+ GuildMsgOptions(type: 'text', content: string, image?: string): SendGuildTextMessageRequest;
310
+ /**
311
+ * 构建图片消息参数
312
+ * @param type 消息类型
313
+ * @param image 图片url
314
+ */
315
+ GuildMsgOptions(type: 'image', image: string): SendGuildTextMessageRequest;
316
+ /**
317
+ * 构建Embed消息参数
318
+ * @param type 消息类型
319
+ * @param embed Embed参数
320
+ */
321
+ GuildMsgOptions(type: 'embed', embed: Embeds): SendGuildEmbedMessageRequest;
322
+ /**
323
+ * 构建Ark消息参数
324
+ * @param type 消息类型
325
+ * @param ark Ark参数
326
+ */
327
+ GuildMsgOptions(type: 'ark', ark: Ark): SendGuildArkMessageRequest;
328
+ /**
329
+ * 构建Markdown消息参数
330
+ * @param type 消息类型
331
+ * @param markdown Markdown文本
332
+ */
333
+ GuildMsgOptions(type: 'markdown', markdown: Markdown): SendGuildMarkdownMessageRequest;
334
+ /**
335
+ * 上传富媒体文件
336
+ * @param scene 上传场景
337
+ * @param targetId 目标id
338
+ * @param type 文件类型
339
+ * @param url 需要上传的文件的url
340
+ * @param srvSendMsg 是否发送消息
341
+ */
342
+ uploadMedia(scene: Scene, targetId: string, type: MediaType, url: string, srvSendMsg?: boolean): Promise<UploadMediaResponse>;
343
+ /**
344
+ * 上传富媒体文件
345
+ * @param scene 上传场景
346
+ * @param targetId 目标id
347
+ * @param type 文件类型
348
+ * @param base64 需要上传的文件的base64编码
349
+ * @param srvSendMsg 是否发送消息
350
+ */
351
+ uploadMedia(scene: Scene, targetId: string, type: MediaType, base64: string, srvSendMsg?: boolean): Promise<UploadMediaResponse>;
352
+ /**
353
+ * 单聊撤回消息
354
+ * @param type 场景类型
355
+ * @param targetId 目标QQ用户的openid
356
+ * @param messageId 消息id
357
+ */
358
+ recallMsg(type: 'user', targetId: string, messageId: string): Promise<boolean>;
359
+ /**
360
+ * 群聊撤回消息
361
+ * @param type 场景类型
362
+ * @param targetId 目标QQ群的openid
363
+ * @param messageId 消息id
364
+ */
365
+ recallMsg(type: 'group', targetId: string, messageId: string): Promise<boolean>;
366
+ /**
367
+ * 文字子频道撤回消息
368
+ * @param type 场景类型
369
+ * @param channelId 子频道的id
370
+ * @param messageId 消息id
371
+ * @param hidetip 是否隐藏提示小灰条,true 为隐藏,false 为显示。默认为false
372
+ */
373
+ recallMsg(type: 'channels', channelId: string, messageId: string, hidetip?: boolean): Promise<boolean>;
374
+ /**
375
+ * 频道私信撤回消息
376
+ * @param type 场景类型
377
+ * @param guildId 频道的id
378
+ * @param messageId 消息id
379
+ * @param hidetip 是否隐藏提示小灰条,true 为隐藏,false 为显示。默认为false
380
+ */
381
+ recallMsg(type: 'dms', guildId: string, messageId: string, hidetip?: boolean): Promise<boolean>;
382
+ /**
383
+ * 发送文字子频道消息
384
+ * @param targetId 目标子频道的id
385
+ * @param options 消息参数
386
+ */
387
+ sendChannelMsg(targetId: string, options: SendGuildMsg | FormData): Promise<SendGuildResponse>;
388
+ /**
389
+ * 直接发送频道消息
390
+ * @param guildID 频道的id
391
+ * @param options 消息参数
392
+ */
393
+ sendDmsMsg(guildID: string, options: SendGuildMsg | FormData): Promise<SendGuildResponse>;
394
+ /**
395
+ * 发送频道私信消息
396
+ * @param targetId 目标的id
397
+ * @param srcGuildId 源频道的id
398
+ * @param options 消息参数
399
+ */
400
+ sendDmsMsg(targetId: string, srcGuildId: string, options: SendGuildMsg | FormData): Promise<SendGuildResponse>;
401
+ /**
402
+ * 获取当前机器人详情
403
+ */
404
+ getMe(): Promise<GetMeResponse>;
405
+ /**
406
+ * 创建私信会话
407
+ * @param recipientID 接受者id
408
+ * @param srcGuildID 源频道id
409
+ */
410
+ dms(recipientID: string, srcGuildID: string): Promise<DmsResponse>;
411
+ }
412
+
413
+ /** 发送函数所需参数 */
414
+ type Options<T extends 'qq' | 'guild'> = T extends 'qq' ? SendQQMsg : SendGuildMsg | FormData;
415
+ type Pasmsg<T extends 'qq' | 'guild'> = {
416
+ type: 'msg' | 'event';
417
+ msg_id: string;
418
+ msg_seq: T extends 'qq' ? number : never;
419
+ };
420
+ interface Grouping<T extends 'qq' | 'guild'> {
421
+ /** 文本 */
422
+ content: string[];
423
+ /** 图片 QQ专属 */
424
+ image: string[];
425
+ /** 单行按钮 */
426
+ button: ButtonElement[];
427
+ /** 多行按钮 */
428
+ keyboard: KeyboardElement[];
429
+ /** markdown */
430
+ markdown: MarkdownElement[];
431
+ /** markdown模板 */
432
+ markdownTpl: MarkdownTplElement[];
433
+ /** 频道专属 图片url */
434
+ imageUrls: string[];
435
+ /** 频道专属 图片file */
436
+ imageFiles: string[];
437
+ /** 引用回复 频道专属 */
438
+ reply: {
439
+ message_id: string;
440
+ };
441
+ /** pasmsg */
442
+ pasmsg: Pasmsg<T>;
443
+ /** 代发送列表 */
444
+ list: Array<Options<T>>;
445
+ /**
446
+ * 处理按钮、markdown
447
+ * 统一格式后推入待发送消息列表
448
+ * @param type 构建类型
449
+ * @param list 分类列表
450
+ * @returns
451
+ */
452
+ markdownToButton: (type: T, list: Grouping<T>) => void;
453
+ }
454
+ /**
455
+ * @adaoter QQBot
456
+ * @version 1.8.0
457
+ */
458
+ declare abstract class AdapterQQBot extends AdapterBase {
459
+ super: QQBotApi;
460
+ constructor(QQBot: QQBotApi);
461
+ logger(level: LogMethodNames, ...args: any[]): void;
462
+ /**
463
+ * 被动消息结构
464
+ * @param type 消息类型
465
+ */
466
+ pasmsg<T extends 'qq' | 'guild'>(type: T): Pasmsg<T>;
467
+ /**
468
+ * 撤回消息
469
+ * @param contact 联系人
470
+ * @param messageId 消息id
471
+ */
472
+ recallMsg(contact: Contact, messageId: string): Promise<void>;
473
+ /**
474
+ * 初始化消息分类对象
475
+ */
476
+ initList<T extends 'qq' | 'guild'>(type: T): Grouping<T>;
477
+ /**
478
+ * 初始化发送消息返回值
479
+ */
480
+ initSendMsgResults(): SendMsgResults;
481
+ /**
482
+ * 处理返回值
483
+ * @param data 返回值
484
+ */
485
+ handleResponse(data: SendMsgResults): SendMsgResults;
486
+ /**
487
+ * - 处理按钮、markdown
488
+ * - 统一格式后推入待发送消息列表
489
+ * @param type 消息类型
490
+ * @param button 按钮
491
+ * @param keyboard 键盘
492
+ * @param markdown markdown
493
+ * @param markdownTpl markdown模板
494
+ * @returns 消息列表
495
+ */
496
+ markdownToButton<T extends 'qq' | 'guild'>(type: T, list: Grouping<T>): void;
497
+ }
498
+
499
+ export { AdapterQQBot };
package/dist/index.js ADDED
@@ -0,0 +1,100 @@
1
+ import {
2
+ basename,
3
+ config_exports,
4
+ event,
5
+ fakeEvent,
6
+ getConfig,
7
+ initQQBotAdapter,
8
+ sign
9
+ } from "./chunk-PYOUSZ6B.js";
10
+
11
+ // src/index.ts
12
+ import { logger as logger2 } from "node-karin";
13
+
14
+ // src/connection/routing.ts
15
+ import { app } from "node-karin";
16
+ import express from "node-karin/express";
17
+
18
+ // src/connection/webhook.ts
19
+ import { logger } from "node-karin";
20
+ var webhookRouting = async (req, res) => {
21
+ var _a, _b, _c, _d;
22
+ const data = await checkAppid(req, res);
23
+ if (!data) return;
24
+ const cfg = getConfig(data.appid);
25
+ if (!cfg) {
26
+ logger.error(`[\u914D\u7F6E\u9519\u8BEF][${data.appid}] \u914D\u7F6E\u6587\u4EF6\u4E2D\u672A\u627E\u5230\u5BF9\u5E94\u7684appid\uFF0C\u8BF7\u68C0\u67E5\u914D\u7F6E\u6587\u4EF6`);
27
+ return;
28
+ }
29
+ if (cfg.event.type !== 1) {
30
+ logger.error(`[\u914D\u7F6E\u9519\u8BEF][${data.appid}] webhook\u672A\u542F\u7528\uFF0C\u8BF7\u68C0\u67E5\u914D\u7F6E\u6587\u4EF6`);
31
+ return;
32
+ }
33
+ if (data.body.op === 13) {
34
+ const eventTs = (_b = (_a = data.body) == null ? void 0 : _a.d) == null ? void 0 : _b.event_ts;
35
+ const plainToken = (_d = (_c = data.body) == null ? void 0 : _c.d) == null ? void 0 : _d.plain_token;
36
+ if (!eventTs || !plainToken) {
37
+ logger.error(`[\u8BF7\u6C42\u6570\u636E\u9519\u8BEF][${data.appid}] \u672A\u627E\u5230 event_ts \u6216 plain_token: ${data.rawBody}`);
38
+ return;
39
+ }
40
+ const signature2 = sign(cfg.secret, eventTs, plainToken);
41
+ logger.mark(`[signature][${data.appid}] ${signature2}`);
42
+ res.setHeader("Content-Type", "application/json");
43
+ res.status(200).end(JSON.stringify({ plain_token: plainToken, signature: signature2 }));
44
+ return;
45
+ }
46
+ const ed25519 = req.headers["x-signature-ed25519"];
47
+ const signature = sign(cfg.secret, req.headers["x-signature-timestamp"], data.rawBody);
48
+ if (ed25519 !== signature) {
49
+ fakeEvent(`\u7B7E\u540D\u9A8C\u8BC1\u5931\u8D25:
50
+ appid: ${data.appid}
51
+ ed25519: ${ed25519}
52
+ \u5B9E\u9645\u7B7E\u540D: ${signature}
53
+ body: ${data.rawBody}`);
54
+ return;
55
+ }
56
+ event.emit(data.appid, data.body);
57
+ };
58
+ var checkAppid = async (req, res) => {
59
+ let response = true;
60
+ try {
61
+ const ip = req.socket.remoteAddress;
62
+ const appid = req.headers["x-bot-appid"];
63
+ const rawBody = await new Promise((resolve) => {
64
+ const raw = [];
65
+ req.on("data", (chunk) => raw.push(chunk));
66
+ req.on("end", () => resolve(raw.join("")));
67
+ });
68
+ if (!appid) {
69
+ fakeEvent(`\u672A\u627E\u5230 x-bot-appid: ${ip} body: ${rawBody}`);
70
+ return;
71
+ }
72
+ const userAgent = req.headers["user-agent"];
73
+ if (userAgent !== "QQBot-Callback") {
74
+ fakeEvent(`\u672A\u627E\u5230 User-Agent: ${ip} body: ${rawBody}`);
75
+ return;
76
+ }
77
+ const body = JSON.parse(rawBody) || {};
78
+ if (typeof body.op !== "number") {
79
+ fakeEvent(`\u975E\u6CD5\u8BF7\u6C42\u4F53\uFF0C\u672A\u627E\u5230 op: ${ip} body: ${rawBody}`);
80
+ return;
81
+ } else if (body.op === 13) {
82
+ response = false;
83
+ }
84
+ return { appid, rawBody, body };
85
+ } finally {
86
+ response && res.status(200).end();
87
+ }
88
+ };
89
+
90
+ // src/connection/routing.ts
91
+ var createRouting = () => {
92
+ const router = express.Router();
93
+ router.use("/webhook", webhookRouting);
94
+ app.use("/qqbot", router);
95
+ };
96
+
97
+ // src/index.ts
98
+ logger2.info(`${logger2.violet(`[\u63D2\u4EF6:${config_exports.pkg().version}]`)} ${logger2.green(basename)} \u521D\u59CB\u5316\u5B8C\u6210~`);
99
+ createRouting();
100
+ initQQBotAdapter();
@@ -0,0 +1,25 @@
1
+ import * as node_karin from 'node-karin';
2
+
3
+ declare const _default: node_karin.DefineConfig<{
4
+ qqbot: [{
5
+ appId: string;
6
+ secret: string;
7
+ prodApi: string;
8
+ sandboxApi: string;
9
+ tokenApi: string;
10
+ sandbox: boolean;
11
+ qqEnable: boolean;
12
+ guildEnable: boolean;
13
+ guildMode: 0 | 1;
14
+ exclude: string[];
15
+ regex: string[];
16
+ "markdown:mode": 0 | 1 | 3 | 4 | 5;
17
+ "markdown:id": string;
18
+ "markdown:kv": string[];
19
+ "event:type": 0 | 1 | 2;
20
+ "event:wsUrl": string;
21
+ "event:wsToken": string;
22
+ }];
23
+ }>;
24
+
25
+ export { _default as default };