@onebots/adapter-kook 1.0.0
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.
- package/LICENSE +21 -0
- package/README.md +133 -0
- package/lib/adapter.d.ts +137 -0
- package/lib/adapter.js +817 -0
- package/lib/bot.d.ts +155 -0
- package/lib/bot.js +403 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.js +3 -0
- package/lib/types.d.ts +240 -0
- package/lib/types.js +20 -0
- package/lib/utils.d.ts +93 -0
- package/lib/utils.js +240 -0
- package/package.json +39 -0
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KOOK (开黑了) API 类型定义
|
|
3
|
+
* 基于 KOOK 开发者平台官方 API
|
|
4
|
+
*/
|
|
5
|
+
export interface KookConfig {
|
|
6
|
+
account_id: string;
|
|
7
|
+
token: string;
|
|
8
|
+
verifyToken?: string;
|
|
9
|
+
encryptKey?: string;
|
|
10
|
+
mode?: 'webhook' | 'websocket';
|
|
11
|
+
maxRetry?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface KookUser {
|
|
14
|
+
id: string;
|
|
15
|
+
username: string;
|
|
16
|
+
nickname?: string;
|
|
17
|
+
identify_num: string;
|
|
18
|
+
online: boolean;
|
|
19
|
+
bot?: boolean;
|
|
20
|
+
status: number;
|
|
21
|
+
avatar: string;
|
|
22
|
+
vip_avatar?: string;
|
|
23
|
+
mobile_verified?: boolean;
|
|
24
|
+
roles?: number[];
|
|
25
|
+
joined_at?: number;
|
|
26
|
+
active_time?: number;
|
|
27
|
+
}
|
|
28
|
+
export interface KookGuild {
|
|
29
|
+
id: string;
|
|
30
|
+
name: string;
|
|
31
|
+
topic: string;
|
|
32
|
+
user_id: string;
|
|
33
|
+
icon: string;
|
|
34
|
+
notify_type: number;
|
|
35
|
+
region: string;
|
|
36
|
+
enable_open: boolean;
|
|
37
|
+
open_id: string;
|
|
38
|
+
default_channel_id: string;
|
|
39
|
+
welcome_channel_id: string;
|
|
40
|
+
roles?: KookRole[];
|
|
41
|
+
channels?: KookChannel[];
|
|
42
|
+
}
|
|
43
|
+
export interface KookChannel {
|
|
44
|
+
id: string;
|
|
45
|
+
name: string;
|
|
46
|
+
user_id: string;
|
|
47
|
+
guild_id: string;
|
|
48
|
+
topic: string;
|
|
49
|
+
is_category: boolean;
|
|
50
|
+
parent_id: string;
|
|
51
|
+
level: number;
|
|
52
|
+
slow_mode: number;
|
|
53
|
+
type: number;
|
|
54
|
+
permission_overwrites?: KookPermissionOverwrite[];
|
|
55
|
+
permission_users?: any[];
|
|
56
|
+
permission_sync: number;
|
|
57
|
+
has_password: boolean;
|
|
58
|
+
}
|
|
59
|
+
export interface KookRole {
|
|
60
|
+
role_id: number;
|
|
61
|
+
name: string;
|
|
62
|
+
color: number;
|
|
63
|
+
position: number;
|
|
64
|
+
hoist: number;
|
|
65
|
+
mentionable: number;
|
|
66
|
+
permissions: number;
|
|
67
|
+
}
|
|
68
|
+
export interface KookPermissionOverwrite {
|
|
69
|
+
role_id: number;
|
|
70
|
+
allow: number;
|
|
71
|
+
deny: number;
|
|
72
|
+
}
|
|
73
|
+
export type KookMessageType = 1 | 2 | 3 | 4 | 8 | 9 | 10 | 255;
|
|
74
|
+
export interface KookChannelMessage {
|
|
75
|
+
id: string;
|
|
76
|
+
type: KookMessageType;
|
|
77
|
+
content: string;
|
|
78
|
+
mention: string[];
|
|
79
|
+
mention_all: boolean;
|
|
80
|
+
mention_roles: number[];
|
|
81
|
+
mention_here: boolean;
|
|
82
|
+
embeds: any[];
|
|
83
|
+
attachments: KookAttachment[];
|
|
84
|
+
create_at: number;
|
|
85
|
+
updated_at: number;
|
|
86
|
+
reactions: KookReaction[];
|
|
87
|
+
author: KookUser;
|
|
88
|
+
image_name?: string;
|
|
89
|
+
read_status?: boolean;
|
|
90
|
+
quote?: KookChannelMessage;
|
|
91
|
+
mention_info?: any;
|
|
92
|
+
}
|
|
93
|
+
export interface KookDirectMessage {
|
|
94
|
+
id: string;
|
|
95
|
+
type: KookMessageType;
|
|
96
|
+
content: string;
|
|
97
|
+
embeds: any[];
|
|
98
|
+
attachments: KookAttachment[];
|
|
99
|
+
create_at: number;
|
|
100
|
+
updated_at: number;
|
|
101
|
+
reactions: KookReaction[];
|
|
102
|
+
author_id: string;
|
|
103
|
+
image_name?: string;
|
|
104
|
+
read_status?: boolean;
|
|
105
|
+
quote?: KookDirectMessage;
|
|
106
|
+
nonce?: string;
|
|
107
|
+
}
|
|
108
|
+
export interface KookAttachment {
|
|
109
|
+
type: string;
|
|
110
|
+
url: string;
|
|
111
|
+
name: string;
|
|
112
|
+
file_type?: string;
|
|
113
|
+
size?: number;
|
|
114
|
+
duration?: number;
|
|
115
|
+
width?: number;
|
|
116
|
+
height?: number;
|
|
117
|
+
}
|
|
118
|
+
export interface KookReaction {
|
|
119
|
+
emoji: KookEmoji;
|
|
120
|
+
count: number;
|
|
121
|
+
me: boolean;
|
|
122
|
+
}
|
|
123
|
+
export interface KookEmoji {
|
|
124
|
+
id: string;
|
|
125
|
+
name: string;
|
|
126
|
+
}
|
|
127
|
+
export interface KookIntimacy {
|
|
128
|
+
img_url: string;
|
|
129
|
+
social_info: string;
|
|
130
|
+
last_read: number;
|
|
131
|
+
score: number;
|
|
132
|
+
img_list: Array<{
|
|
133
|
+
id: string;
|
|
134
|
+
url: string;
|
|
135
|
+
}>;
|
|
136
|
+
}
|
|
137
|
+
export interface KookUserChat {
|
|
138
|
+
code: string;
|
|
139
|
+
last_read_time: number;
|
|
140
|
+
latest_msg_time: number;
|
|
141
|
+
unread_count: number;
|
|
142
|
+
is_friend: boolean;
|
|
143
|
+
is_blocked: boolean;
|
|
144
|
+
is_target_blocked: boolean;
|
|
145
|
+
target_info: KookUser;
|
|
146
|
+
}
|
|
147
|
+
export interface KookGame {
|
|
148
|
+
id: number;
|
|
149
|
+
name: string;
|
|
150
|
+
type: number;
|
|
151
|
+
options: string;
|
|
152
|
+
kmhook_admin: boolean;
|
|
153
|
+
process_name: string[];
|
|
154
|
+
product_name: string[];
|
|
155
|
+
icon: string;
|
|
156
|
+
}
|
|
157
|
+
export interface KookApiResponse<T = any> {
|
|
158
|
+
code: number;
|
|
159
|
+
message: string;
|
|
160
|
+
data: T;
|
|
161
|
+
}
|
|
162
|
+
export interface KookListResponse<T> {
|
|
163
|
+
items: T[];
|
|
164
|
+
meta: {
|
|
165
|
+
page: number;
|
|
166
|
+
page_total: number;
|
|
167
|
+
page_size: number;
|
|
168
|
+
total: number;
|
|
169
|
+
};
|
|
170
|
+
sort?: Record<string, number>;
|
|
171
|
+
}
|
|
172
|
+
export interface KookSignal {
|
|
173
|
+
s: number;
|
|
174
|
+
d: any;
|
|
175
|
+
sn?: number;
|
|
176
|
+
}
|
|
177
|
+
export declare const KookSignalType: {
|
|
178
|
+
readonly EVENT: 0;
|
|
179
|
+
readonly HELLO: 1;
|
|
180
|
+
readonly PING: 2;
|
|
181
|
+
readonly PONG: 3;
|
|
182
|
+
readonly RESUME: 4;
|
|
183
|
+
readonly RECONNECT: 5;
|
|
184
|
+
readonly RESUME_ACK: 6;
|
|
185
|
+
};
|
|
186
|
+
export type KookEventType = 'message' | 'added_reaction' | 'deleted_reaction' | 'updated_message' | 'deleted_message' | 'pinned_message' | 'unpinned_message' | 'added_channel' | 'updated_channel' | 'deleted_channel' | 'joined_guild' | 'exited_guild' | 'updated_guild_member' | 'guild_member_online' | 'guild_member_offline' | 'added_role' | 'deleted_role' | 'updated_role' | 'joined_channel' | 'exited_channel' | 'user_updated' | 'self_joined_guild' | 'self_exited_guild' | 'message_btn_click' | 'added_block_list' | 'deleted_block_list' | 'private_added_reaction' | 'private_deleted_reaction' | 'updated_private_message' | 'deleted_private_message';
|
|
187
|
+
export declare const KookChannelType: {
|
|
188
|
+
readonly TEXT: 1;
|
|
189
|
+
readonly VOICE: 2;
|
|
190
|
+
};
|
|
191
|
+
export interface KookEvent {
|
|
192
|
+
channel_type: 'GROUP' | 'PERSON' | 'BROADCAST';
|
|
193
|
+
type: number;
|
|
194
|
+
target_id: string;
|
|
195
|
+
author_id: string;
|
|
196
|
+
content: string;
|
|
197
|
+
msg_id: string;
|
|
198
|
+
msg_timestamp: number;
|
|
199
|
+
nonce: string;
|
|
200
|
+
extra: KookEventExtra;
|
|
201
|
+
}
|
|
202
|
+
export interface KookEventExtra {
|
|
203
|
+
type?: KookEventType | number;
|
|
204
|
+
guild_id?: string;
|
|
205
|
+
channel_name?: string;
|
|
206
|
+
mention?: string[];
|
|
207
|
+
mention_all?: boolean;
|
|
208
|
+
mention_roles?: number[];
|
|
209
|
+
mention_here?: boolean;
|
|
210
|
+
author?: KookUser;
|
|
211
|
+
body?: any;
|
|
212
|
+
code?: string;
|
|
213
|
+
[key: string]: any;
|
|
214
|
+
}
|
|
215
|
+
export interface KookWebhookChallenge {
|
|
216
|
+
s: 0;
|
|
217
|
+
d: {
|
|
218
|
+
type: 255;
|
|
219
|
+
channel_type: 'WEBHOOK_CHALLENGE';
|
|
220
|
+
challenge: string;
|
|
221
|
+
verify_token: string;
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
export interface KookSendMessageParams {
|
|
225
|
+
type?: KookMessageType;
|
|
226
|
+
target_id: string;
|
|
227
|
+
content: string;
|
|
228
|
+
quote?: string;
|
|
229
|
+
nonce?: string;
|
|
230
|
+
temp_target_id?: string;
|
|
231
|
+
}
|
|
232
|
+
export interface KookSendDirectMessageParams {
|
|
233
|
+
type?: KookMessageType;
|
|
234
|
+
target_id?: string;
|
|
235
|
+
chat_code?: string;
|
|
236
|
+
content: string;
|
|
237
|
+
quote?: string;
|
|
238
|
+
nonce?: string;
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=types.d.ts.map
|
package/lib/types.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KOOK (开黑了) API 类型定义
|
|
3
|
+
* 基于 KOOK 开发者平台官方 API
|
|
4
|
+
*/
|
|
5
|
+
// 信令类型
|
|
6
|
+
export const KookSignalType = {
|
|
7
|
+
EVENT: 0, // 服务端推送消息
|
|
8
|
+
HELLO: 1, // 客户端和服务端的 Hello
|
|
9
|
+
PING: 2, // 客户端发送的 Ping
|
|
10
|
+
PONG: 3, // 服务端回复的 Pong
|
|
11
|
+
RESUME: 4, // 恢复连接
|
|
12
|
+
RECONNECT: 5, // 服务端通知重连
|
|
13
|
+
RESUME_ACK: 6, // 恢复成功
|
|
14
|
+
};
|
|
15
|
+
// 频道类型
|
|
16
|
+
export const KookChannelType = {
|
|
17
|
+
TEXT: 1, // 文字频道
|
|
18
|
+
VOICE: 2, // 语音频道
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=types.js.map
|
package/lib/utils.d.ts
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 验证 Webhook 请求
|
|
3
|
+
*/
|
|
4
|
+
export declare function verifyWebhook(body: any, verifyToken: string): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* 解密 Webhook 消息(当配置了 encryptKey 时)
|
|
7
|
+
*/
|
|
8
|
+
export declare function decryptWebhookMessage(encryptedData: string, encryptKey: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* 解析 KMarkdown 消息为文本
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseKMarkdown(content: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* 将文本转换为 KMarkdown 格式
|
|
15
|
+
*/
|
|
16
|
+
export declare function textToKMarkdown(text: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* 构建 @用户 的 KMarkdown
|
|
19
|
+
*/
|
|
20
|
+
export declare function mentionUser(userId: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* 构建 @全体成员 的 KMarkdown
|
|
23
|
+
*/
|
|
24
|
+
export declare function mentionAll(): string;
|
|
25
|
+
/**
|
|
26
|
+
* 构建 @在线成员 的 KMarkdown
|
|
27
|
+
*/
|
|
28
|
+
export declare function mentionHere(): string;
|
|
29
|
+
/**
|
|
30
|
+
* 构建 @角色 的 KMarkdown
|
|
31
|
+
*/
|
|
32
|
+
export declare function mentionRole(roleId: number): string;
|
|
33
|
+
/**
|
|
34
|
+
* 构建 #频道 的 KMarkdown
|
|
35
|
+
*/
|
|
36
|
+
export declare function mentionChannel(channelId: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* 构建表情的 KMarkdown
|
|
39
|
+
*/
|
|
40
|
+
export declare function emojiKMarkdown(emojiName: string, emojiId: string): string;
|
|
41
|
+
/**
|
|
42
|
+
* 构建链接的 KMarkdown
|
|
43
|
+
*/
|
|
44
|
+
export declare function linkKMarkdown(text: string, url: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* 构建加粗的 KMarkdown
|
|
47
|
+
*/
|
|
48
|
+
export declare function boldKMarkdown(text: string): string;
|
|
49
|
+
/**
|
|
50
|
+
* 构建斜体的 KMarkdown
|
|
51
|
+
*/
|
|
52
|
+
export declare function italicKMarkdown(text: string): string;
|
|
53
|
+
/**
|
|
54
|
+
* 构建删除线的 KMarkdown
|
|
55
|
+
*/
|
|
56
|
+
export declare function strikethroughKMarkdown(text: string): string;
|
|
57
|
+
/**
|
|
58
|
+
* 构建代码块的 KMarkdown
|
|
59
|
+
*/
|
|
60
|
+
export declare function codeBlockKMarkdown(code: string, language?: string): string;
|
|
61
|
+
/**
|
|
62
|
+
* 构建行内代码的 KMarkdown
|
|
63
|
+
*/
|
|
64
|
+
export declare function inlineCodeKMarkdown(code: string): string;
|
|
65
|
+
/**
|
|
66
|
+
* 构建引用的 KMarkdown
|
|
67
|
+
*/
|
|
68
|
+
export declare function quoteKMarkdown(text: string): string;
|
|
69
|
+
/**
|
|
70
|
+
* 构建分割线的 KMarkdown
|
|
71
|
+
*/
|
|
72
|
+
export declare function dividerKMarkdown(): string;
|
|
73
|
+
/**
|
|
74
|
+
* 生成随机 nonce
|
|
75
|
+
*/
|
|
76
|
+
export declare function generateNonce(): string;
|
|
77
|
+
/**
|
|
78
|
+
* 解析卡片消息
|
|
79
|
+
*/
|
|
80
|
+
export declare function parseCardMessage(content: string): any[];
|
|
81
|
+
/**
|
|
82
|
+
* 构建简单文本卡片
|
|
83
|
+
*/
|
|
84
|
+
export declare function buildTextCard(text: string, theme?: 'primary' | 'success' | 'danger' | 'warning' | 'info' | 'secondary' | 'none'): string;
|
|
85
|
+
/**
|
|
86
|
+
* 构建图片卡片
|
|
87
|
+
*/
|
|
88
|
+
export declare function buildImageCard(imageUrl: string, title?: string): string;
|
|
89
|
+
/**
|
|
90
|
+
* 计算消息签名(用于验证)
|
|
91
|
+
*/
|
|
92
|
+
export declare function calculateSignature(data: string, key: string): string;
|
|
93
|
+
//# sourceMappingURL=utils.d.ts.map
|
package/lib/utils.js
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KOOK (开黑了) 工具函数
|
|
3
|
+
*/
|
|
4
|
+
import { createDecipheriv, createHash } from 'crypto';
|
|
5
|
+
/**
|
|
6
|
+
* 验证 Webhook 请求
|
|
7
|
+
*/
|
|
8
|
+
export function verifyWebhook(body, verifyToken) {
|
|
9
|
+
if (!body || !body.d)
|
|
10
|
+
return false;
|
|
11
|
+
return body.d.verify_token === verifyToken;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 解密 Webhook 消息(当配置了 encryptKey 时)
|
|
15
|
+
*/
|
|
16
|
+
export function decryptWebhookMessage(encryptedData, encryptKey) {
|
|
17
|
+
if (!encryptKey) {
|
|
18
|
+
throw new Error('未配置 encryptKey,无法解密消息');
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
// 解码 base64
|
|
22
|
+
const encrypted = Buffer.from(encryptedData, 'base64');
|
|
23
|
+
// 提取 IV(前 16 字节)
|
|
24
|
+
const iv = encrypted.slice(0, 16);
|
|
25
|
+
const ciphertext = encrypted.slice(16);
|
|
26
|
+
// 生成密钥(encryptKey 需要是 32 字节)
|
|
27
|
+
const key = Buffer.alloc(32);
|
|
28
|
+
Buffer.from(encryptKey).copy(key);
|
|
29
|
+
// 解密
|
|
30
|
+
const decipher = createDecipheriv('aes-256-cbc', key, iv);
|
|
31
|
+
let decrypted = decipher.update(ciphertext);
|
|
32
|
+
decrypted = Buffer.concat([decrypted, decipher.final()]);
|
|
33
|
+
return decrypted.toString('utf-8');
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
throw new Error(`解密消息失败: ${error.message}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 解析 KMarkdown 消息为文本
|
|
41
|
+
*/
|
|
42
|
+
export function parseKMarkdown(content) {
|
|
43
|
+
if (!content)
|
|
44
|
+
return '';
|
|
45
|
+
// 移除 KMarkdown 格式标记
|
|
46
|
+
let text = content;
|
|
47
|
+
// 移除加粗 **text**
|
|
48
|
+
text = text.replace(/\*\*(.+?)\*\*/g, '$1');
|
|
49
|
+
// 移除斜体 *text*
|
|
50
|
+
text = text.replace(/\*(.+?)\*/g, '$1');
|
|
51
|
+
// 移除删除线 ~~text~~
|
|
52
|
+
text = text.replace(/~~(.+?)~~/g, '$1');
|
|
53
|
+
// 移除下划线 (ins)text(/ins)
|
|
54
|
+
text = text.replace(/\(ins\)(.+?)\(\/ins\)/g, '$1');
|
|
55
|
+
// 移除剧透 (spl)text(/spl)
|
|
56
|
+
text = text.replace(/\(spl\)(.+?)\(\/spl\)/g, '$1');
|
|
57
|
+
// 提取链接文本 [text](url)
|
|
58
|
+
text = text.replace(/\[(.+?)\]\(.+?\)/g, '$1');
|
|
59
|
+
// 提取 @用户 (met)id(/met)
|
|
60
|
+
text = text.replace(/\(met\)(\w+)\(\/met\)/g, '@$1');
|
|
61
|
+
// 提取 @角色 (rol)id(/rol)
|
|
62
|
+
text = text.replace(/\(rol\)(\w+)\(\/rol\)/g, '@角色$1');
|
|
63
|
+
// 提取 #频道 (chn)id(/chn)
|
|
64
|
+
text = text.replace(/\(chn\)(\w+)\(\/chn\)/g, '#$1');
|
|
65
|
+
// 提取表情 (emj)name(/emj)[id]
|
|
66
|
+
text = text.replace(/\(emj\)(.+?)\(\/emj\)\[.+?\]/g, ':$1:');
|
|
67
|
+
// 移除代码块 ```code```
|
|
68
|
+
text = text.replace(/```[\s\S]*?```/g, '[代码块]');
|
|
69
|
+
// 移除行内代码 `code`
|
|
70
|
+
text = text.replace(/`(.+?)`/g, '$1');
|
|
71
|
+
return text.trim();
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* 将文本转换为 KMarkdown 格式
|
|
75
|
+
*/
|
|
76
|
+
export function textToKMarkdown(text) {
|
|
77
|
+
// 转义特殊字符
|
|
78
|
+
return text
|
|
79
|
+
.replace(/\\/g, '\\\\')
|
|
80
|
+
.replace(/\*/g, '\\*')
|
|
81
|
+
.replace(/~/g, '\\~')
|
|
82
|
+
.replace(/`/g, '\\`')
|
|
83
|
+
.replace(/\[/g, '\\[')
|
|
84
|
+
.replace(/\(/g, '\\(');
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* 构建 @用户 的 KMarkdown
|
|
88
|
+
*/
|
|
89
|
+
export function mentionUser(userId) {
|
|
90
|
+
return `(met)${userId}(/met)`;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* 构建 @全体成员 的 KMarkdown
|
|
94
|
+
*/
|
|
95
|
+
export function mentionAll() {
|
|
96
|
+
return '(met)all(/met)';
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* 构建 @在线成员 的 KMarkdown
|
|
100
|
+
*/
|
|
101
|
+
export function mentionHere() {
|
|
102
|
+
return '(met)here(/met)';
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* 构建 @角色 的 KMarkdown
|
|
106
|
+
*/
|
|
107
|
+
export function mentionRole(roleId) {
|
|
108
|
+
return `(rol)${roleId}(/rol)`;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* 构建 #频道 的 KMarkdown
|
|
112
|
+
*/
|
|
113
|
+
export function mentionChannel(channelId) {
|
|
114
|
+
return `(chn)${channelId}(/chn)`;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* 构建表情的 KMarkdown
|
|
118
|
+
*/
|
|
119
|
+
export function emojiKMarkdown(emojiName, emojiId) {
|
|
120
|
+
return `(emj)${emojiName}(emj)[${emojiId}]`;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* 构建链接的 KMarkdown
|
|
124
|
+
*/
|
|
125
|
+
export function linkKMarkdown(text, url) {
|
|
126
|
+
return `[${text}](${url})`;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* 构建加粗的 KMarkdown
|
|
130
|
+
*/
|
|
131
|
+
export function boldKMarkdown(text) {
|
|
132
|
+
return `**${text}**`;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* 构建斜体的 KMarkdown
|
|
136
|
+
*/
|
|
137
|
+
export function italicKMarkdown(text) {
|
|
138
|
+
return `*${text}*`;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* 构建删除线的 KMarkdown
|
|
142
|
+
*/
|
|
143
|
+
export function strikethroughKMarkdown(text) {
|
|
144
|
+
return `~~${text}~~`;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* 构建代码块的 KMarkdown
|
|
148
|
+
*/
|
|
149
|
+
export function codeBlockKMarkdown(code, language) {
|
|
150
|
+
return `\`\`\`${language || ''}\n${code}\n\`\`\``;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* 构建行内代码的 KMarkdown
|
|
154
|
+
*/
|
|
155
|
+
export function inlineCodeKMarkdown(code) {
|
|
156
|
+
return `\`${code}\``;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* 构建引用的 KMarkdown
|
|
160
|
+
*/
|
|
161
|
+
export function quoteKMarkdown(text) {
|
|
162
|
+
return `> ${text}`;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* 构建分割线的 KMarkdown
|
|
166
|
+
*/
|
|
167
|
+
export function dividerKMarkdown() {
|
|
168
|
+
return '---';
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* 生成随机 nonce
|
|
172
|
+
*/
|
|
173
|
+
export function generateNonce() {
|
|
174
|
+
return `${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* 解析卡片消息
|
|
178
|
+
*/
|
|
179
|
+
export function parseCardMessage(content) {
|
|
180
|
+
try {
|
|
181
|
+
return JSON.parse(content);
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
return [];
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* 构建简单文本卡片
|
|
189
|
+
*/
|
|
190
|
+
export function buildTextCard(text, theme = 'primary') {
|
|
191
|
+
const card = [{
|
|
192
|
+
type: 'card',
|
|
193
|
+
theme,
|
|
194
|
+
size: 'lg',
|
|
195
|
+
modules: [{
|
|
196
|
+
type: 'section',
|
|
197
|
+
text: {
|
|
198
|
+
type: 'plain-text',
|
|
199
|
+
content: text,
|
|
200
|
+
},
|
|
201
|
+
}],
|
|
202
|
+
}];
|
|
203
|
+
return JSON.stringify(card);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* 构建图片卡片
|
|
207
|
+
*/
|
|
208
|
+
export function buildImageCard(imageUrl, title) {
|
|
209
|
+
const modules = [];
|
|
210
|
+
if (title) {
|
|
211
|
+
modules.push({
|
|
212
|
+
type: 'header',
|
|
213
|
+
text: {
|
|
214
|
+
type: 'plain-text',
|
|
215
|
+
content: title,
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
modules.push({
|
|
220
|
+
type: 'container',
|
|
221
|
+
elements: [{
|
|
222
|
+
type: 'image',
|
|
223
|
+
src: imageUrl,
|
|
224
|
+
}],
|
|
225
|
+
});
|
|
226
|
+
const card = [{
|
|
227
|
+
type: 'card',
|
|
228
|
+
theme: 'none',
|
|
229
|
+
size: 'lg',
|
|
230
|
+
modules,
|
|
231
|
+
}];
|
|
232
|
+
return JSON.stringify(card);
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* 计算消息签名(用于验证)
|
|
236
|
+
*/
|
|
237
|
+
export function calculateSignature(data, key) {
|
|
238
|
+
return createHash('sha256').update(data + key).digest('hex');
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=utils.js.map
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@onebots/adapter-kook",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "onebots KOOK(开黑了)适配器",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "lib/index.js",
|
|
7
|
+
"types": "lib/index.d.ts",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"onebots",
|
|
10
|
+
"kook",
|
|
11
|
+
"kaiheila",
|
|
12
|
+
"adapter"
|
|
13
|
+
],
|
|
14
|
+
"author": "凉菜",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public",
|
|
18
|
+
"registry": "https://registry.npmjs.org"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"/lib/**/*.js",
|
|
22
|
+
"/lib/**/*.d.ts"
|
|
23
|
+
],
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"tsc-alias": "latest",
|
|
26
|
+
"typescript": "latest",
|
|
27
|
+
"@types/node": "^22.7.3"
|
|
28
|
+
},
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"onebots": "1.0.0"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"kook-client": "^1.0.4"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "rm -f *.tsbuildinfo && tsc --project tsconfig.json && tsc-alias -p tsconfig.json",
|
|
37
|
+
"clean": "rm -rf lib *.tsbuildinfo"
|
|
38
|
+
}
|
|
39
|
+
}
|