napcat-sdk 0.1.2 → 0.2.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.
- package/dist/index.cjs +154 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +89 -5
- package/dist/index.d.mts +89 -5
- package/dist/index.mjs +154 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -52,7 +52,7 @@ const CONSOLE_LOGGER = {
|
|
|
52
52
|
//#endregion
|
|
53
53
|
//#region package.json
|
|
54
54
|
var name$1 = "napcat-sdk";
|
|
55
|
-
var version$1 = "0.1
|
|
55
|
+
var version$1 = "0.2.1";
|
|
56
56
|
|
|
57
57
|
//#endregion
|
|
58
58
|
//#region src/segment.ts
|
|
@@ -100,6 +100,7 @@ const segment = {
|
|
|
100
100
|
title,
|
|
101
101
|
...options
|
|
102
102
|
}),
|
|
103
|
+
node: (options) => createSegment("node", { ...options }),
|
|
103
104
|
forward: (id) => createSegment("forward", { id }),
|
|
104
105
|
json: (data) => createSegment("json", { data }),
|
|
105
106
|
file: (file, options) => createSegment("file", {
|
|
@@ -127,6 +128,14 @@ var NapCat = class {
|
|
|
127
128
|
#event = (0, mitt.default)();
|
|
128
129
|
/** Echo 事件发射器 */
|
|
129
130
|
#echoEvent = (0, mitt.default)();
|
|
131
|
+
/** 机器人 ID */
|
|
132
|
+
#uin = 0;
|
|
133
|
+
/** 机器人昵称 */
|
|
134
|
+
#nickname = "-";
|
|
135
|
+
/** 机器人状态 */
|
|
136
|
+
#online = false;
|
|
137
|
+
/** Cookies 缓存 */
|
|
138
|
+
#cookieCache = /* @__PURE__ */ new Map();
|
|
130
139
|
constructor(options) {
|
|
131
140
|
this.options = options;
|
|
132
141
|
}
|
|
@@ -156,6 +165,24 @@ var NapCat = class {
|
|
|
156
165
|
get segment() {
|
|
157
166
|
return segment;
|
|
158
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* 机器人 QQ 号
|
|
170
|
+
*/
|
|
171
|
+
get user_id() {
|
|
172
|
+
return this.uin;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* 机器人 QQ 号
|
|
176
|
+
*/
|
|
177
|
+
get uin() {
|
|
178
|
+
return this.#uin;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* 机器人昵称
|
|
182
|
+
*/
|
|
183
|
+
get nickname() {
|
|
184
|
+
return this.#nickname;
|
|
185
|
+
}
|
|
159
186
|
/** 生成唯一的 echo ID */
|
|
160
187
|
#echoId() {
|
|
161
188
|
return node_crypto.default.randomBytes(16).toString("hex");
|
|
@@ -218,6 +245,7 @@ var NapCat = class {
|
|
|
218
245
|
...extraInfo,
|
|
219
246
|
group_id,
|
|
220
247
|
group_name,
|
|
248
|
+
napcat: this,
|
|
221
249
|
doSign: () => this.api("set_group_sign", { group_id }),
|
|
222
250
|
getInfo: () => this.api("get_group_info", { group_id }),
|
|
223
251
|
getMemberList: async () => this.api("get_group_member_list", { group_id }),
|
|
@@ -251,6 +279,7 @@ var NapCat = class {
|
|
|
251
279
|
...extraInfo,
|
|
252
280
|
user_id,
|
|
253
281
|
nickname,
|
|
282
|
+
napcat: this,
|
|
254
283
|
delete: (block, both) => this.api("delete_friend", {
|
|
255
284
|
user_id,
|
|
256
285
|
temp_block: block,
|
|
@@ -260,24 +289,37 @@ var NapCat = class {
|
|
|
260
289
|
getInfo: () => this.api("get_stranger_info", { user_id })
|
|
261
290
|
};
|
|
262
291
|
}
|
|
263
|
-
/**
|
|
292
|
+
/** 构建私聊消息事件 */
|
|
264
293
|
#buildPrivateMessageEvent(event) {
|
|
294
|
+
const quote_id = event.message.find((el) => el.type === "reply")?.data?.id || null;
|
|
265
295
|
return {
|
|
266
296
|
...event,
|
|
267
|
-
|
|
297
|
+
quote_id,
|
|
298
|
+
getQuoteMessage: async () => {
|
|
299
|
+
if (!quote_id) return null;
|
|
300
|
+
const event$1 = await this.api("get_msg", { message_id: quote_id });
|
|
301
|
+
return this.#buildPrivateMessageEvent(event$1);
|
|
302
|
+
},
|
|
303
|
+
message: (event.message || []).filter((e) => e.type !== "reply").map((el) => ({
|
|
268
304
|
type: el.type,
|
|
269
305
|
...el.data
|
|
270
306
|
})),
|
|
271
307
|
friend: this.#buildFriend(event.user_id, event.sender?.nickname || ""),
|
|
272
|
-
recall: () => this.api("delete_msg", { message_id: event.message_id }),
|
|
273
308
|
reply: (sendable, reply = false) => this.sendPrivateMsg(event.user_id, this.#wrapReply(sendable, event.message_id, reply))
|
|
274
309
|
};
|
|
275
310
|
}
|
|
276
311
|
/** 构建群消息事件对象 */
|
|
277
312
|
#buildGroupMessageEvent(event) {
|
|
313
|
+
const quote_id = event.message.find((el) => el.type === "reply")?.data?.id || null;
|
|
278
314
|
return {
|
|
279
315
|
...event,
|
|
280
|
-
|
|
316
|
+
quote_id,
|
|
317
|
+
getQuoteMessage: async () => {
|
|
318
|
+
if (!quote_id) return null;
|
|
319
|
+
const event$1 = await this.api("get_msg", { message_id: quote_id });
|
|
320
|
+
return this.#buildGroupMessageEvent(event$1);
|
|
321
|
+
},
|
|
322
|
+
message: (event.message || []).filter((e) => e.type !== "reply").map((el) => ({
|
|
281
323
|
type: el.type,
|
|
282
324
|
...el.data
|
|
283
325
|
})),
|
|
@@ -311,7 +353,20 @@ var NapCat = class {
|
|
|
311
353
|
this.#event.emit("meta_event", data);
|
|
312
354
|
if (data.meta_event_type) {
|
|
313
355
|
this.#event.emit(`meta_event.${data.meta_event_type}`, data);
|
|
314
|
-
if (data.sub_type)
|
|
356
|
+
if (data.sub_type) {
|
|
357
|
+
if (data.sub_type === "connect") {
|
|
358
|
+
this.#uin = data.self_id;
|
|
359
|
+
this.#online = true;
|
|
360
|
+
this.#event.emit("napcat.connected", {
|
|
361
|
+
uin: this.#uin,
|
|
362
|
+
ts: data.time * 1e3
|
|
363
|
+
});
|
|
364
|
+
this.getLoginInfo().then((info) => {
|
|
365
|
+
this.#nickname = info.nickname;
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
this.#event.emit(`meta_event.${data.meta_event_type}.${data.sub_type}`, data);
|
|
369
|
+
}
|
|
315
370
|
}
|
|
316
371
|
break;
|
|
317
372
|
case "message":
|
|
@@ -407,13 +462,23 @@ var NapCat = class {
|
|
|
407
462
|
}
|
|
408
463
|
/** 获取一个群的信息,可以用于发送群消息等操作 */
|
|
409
464
|
async pickGroup(group_id) {
|
|
410
|
-
|
|
411
|
-
|
|
465
|
+
try {
|
|
466
|
+
const groupInfo = await this.api("get_group_info", { group_id });
|
|
467
|
+
return this.#buildGroup(group_id, groupInfo.group_name, groupInfo);
|
|
468
|
+
} catch (err) {
|
|
469
|
+
this.logger.warn(`Error to pickGroup ${group_id}: ${err?.message || err}`);
|
|
470
|
+
return null;
|
|
471
|
+
}
|
|
412
472
|
}
|
|
413
473
|
/** 获取一个好友的信息,可以用于发送私聊消息等操作 */
|
|
414
474
|
async pickFriend(user_id) {
|
|
415
|
-
|
|
416
|
-
|
|
475
|
+
try {
|
|
476
|
+
const friendInfo = await this.api("get_stranger_info", { user_id });
|
|
477
|
+
return this.#buildFriend(user_id, friendInfo.nickname, friendInfo);
|
|
478
|
+
} catch (err) {
|
|
479
|
+
this.logger.warn(`Error to pickFriend ${user_id}: ${err?.message || err}`);
|
|
480
|
+
return null;
|
|
481
|
+
}
|
|
417
482
|
}
|
|
418
483
|
/**
|
|
419
484
|
* 注册一次性事件监听器
|
|
@@ -444,6 +509,9 @@ var NapCat = class {
|
|
|
444
509
|
this.logger.debug(`unregistering: ${String(type)}`);
|
|
445
510
|
this.#event.off(type, handler);
|
|
446
511
|
}
|
|
512
|
+
/**
|
|
513
|
+
* 调用 NapCat API
|
|
514
|
+
*/
|
|
447
515
|
api(action, params = {}) {
|
|
448
516
|
this.#ensureWsConnection(this.#ws);
|
|
449
517
|
this.logger.debug(`calling api action: ${action} with params: ${JSON.stringify(params)}`);
|
|
@@ -473,10 +541,81 @@ var NapCat = class {
|
|
|
473
541
|
message: this.#normalizeSendable(sendable)
|
|
474
542
|
});
|
|
475
543
|
}
|
|
544
|
+
/**
|
|
545
|
+
* 机器人是否在线
|
|
546
|
+
*/
|
|
547
|
+
isOnline() {
|
|
548
|
+
return this.#ws?.readyState === WebSocket.OPEN && this.#online;
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* 计算 GTK 值
|
|
552
|
+
*/
|
|
553
|
+
getGTk(pskey) {
|
|
554
|
+
let gkt = 5381;
|
|
555
|
+
for (let i = 0, len = pskey.length; i < len; ++i) gkt += (gkt << 5) + pskey.charCodeAt(i);
|
|
556
|
+
return gkt & 2147483647;
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* 获取 NapCat 原始 Cookie 相关信息
|
|
560
|
+
*/
|
|
561
|
+
getNapCatCookies(domain) {
|
|
562
|
+
return this.api("get_cookies", { domain });
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* 获取版本信息
|
|
566
|
+
*/
|
|
567
|
+
getVersionInfo() {
|
|
568
|
+
return this.api("get_version_info");
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* 获取登录信息
|
|
572
|
+
*/
|
|
573
|
+
getLoginInfo() {
|
|
574
|
+
return this.api("get_login_info");
|
|
575
|
+
}
|
|
576
|
+
/**
|
|
577
|
+
* 获取 Cookie 相关信息
|
|
578
|
+
*/
|
|
579
|
+
async getCookie(domain) {
|
|
580
|
+
const cache = this.#cookieCache.get(domain);
|
|
581
|
+
if (cache) return cache;
|
|
582
|
+
const { cookies: cookieString, bkn } = await this.getNapCatCookies(domain);
|
|
583
|
+
const skey = cookieString.match(/skey=([^;]*)/)?.[1] || "";
|
|
584
|
+
const pskey = cookieString.match(/pskey=([^;]*)/)?.[1] || "";
|
|
585
|
+
const gtk = this.getGTk(pskey);
|
|
586
|
+
const returns = {
|
|
587
|
+
pskey,
|
|
588
|
+
skey,
|
|
589
|
+
uin: this.uin,
|
|
590
|
+
gtk: String(gtk),
|
|
591
|
+
bkn,
|
|
592
|
+
cookie: `uin=${this.uin}; skey=${skey}; p_uin=${this.uin}; p_skey=${pskey};`,
|
|
593
|
+
legacyCookie: `uin=o${this.uin}; skey=${skey}; p_uin=o${this.uin}; p_skey=${pskey};`
|
|
594
|
+
};
|
|
595
|
+
this.#cookieCache.set(domain, returns);
|
|
596
|
+
setTimeout(() => {
|
|
597
|
+
this.#cookieCache.delete(domain);
|
|
598
|
+
}, 1e3 * 60 * 60);
|
|
599
|
+
return returns;
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* 通过域名获取 Pskey
|
|
603
|
+
*/
|
|
604
|
+
async getPskey(domain) {
|
|
605
|
+
const { pskey } = await this.getCookie(domain);
|
|
606
|
+
return pskey;
|
|
607
|
+
}
|
|
608
|
+
/**
|
|
609
|
+
* 获取 Bkn 值
|
|
610
|
+
*/
|
|
611
|
+
async getBkn() {
|
|
612
|
+
const { bkn } = await this.getCookie("vip.qq.com");
|
|
613
|
+
return bkn;
|
|
614
|
+
}
|
|
476
615
|
/** 启动 NapCat SDK 实例,建立 WebSocket 连接 */
|
|
477
616
|
async run() {
|
|
478
|
-
const { logger: _, ...config } = this.#config;
|
|
479
|
-
this.logger.info(`
|
|
617
|
+
const { logger: _, token: __, ...config } = this.#config;
|
|
618
|
+
this.logger.info(`run with config: ${JSON.stringify(config)}`);
|
|
480
619
|
return new Promise((resolve, reject) => {
|
|
481
620
|
const ws = new WebSocket(this.#buildWsUrl());
|
|
482
621
|
ws.onmessage = (event) => {
|
|
@@ -495,16 +634,18 @@ var NapCat = class {
|
|
|
495
634
|
this.#bindInternalEvents(data);
|
|
496
635
|
};
|
|
497
636
|
ws.onclose = () => {
|
|
637
|
+
this.#online = false;
|
|
498
638
|
this.logger.info("closed");
|
|
499
639
|
this.#event.emit("ws.close");
|
|
500
640
|
};
|
|
501
641
|
ws.onerror = (error) => {
|
|
642
|
+
this.#online = false;
|
|
502
643
|
this.logger.error(`error: ${error}`);
|
|
503
644
|
this.#event.emit("ws.error", error);
|
|
504
645
|
reject(error);
|
|
505
646
|
};
|
|
506
647
|
ws.onopen = () => {
|
|
507
|
-
this.logger.info("connected");
|
|
648
|
+
this.logger.info("NapCat connected");
|
|
508
649
|
this.#event.emit("ws.open");
|
|
509
650
|
resolve();
|
|
510
651
|
};
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["ABSTRACT_LOGGER: Logger","CONSOLE_LOGGER: Logger","name: string","pkg.name","version: string","pkg.version","DEFAULT_NAPCAT_OPTIONS: Required<OptionalProps<MiokiOptions>>","options: MiokiOptions","#config","#ws","crypto","#echoEvent","#buildFriend","#wrapReply","#buildGroup","#event","#buildPrivateMessageEvent","#buildGroupMessageEvent","#ensureWsConnection","#echoId","#waitForAction","#normalizeSendable","#buildWsUrl","#bindInternalEvents","NAPCAT_NOTICE_NOTIFY_MAP: Record<string, { notice_type: string; sub_type: string }>","NAPCAT_NOTICE_EVENT_MAP: Record<string, { notice_type: string; sub_type: string }>"],"sources":["../src/logger.ts","../package.json","../src/segment.ts","../src/napcat.ts"],"sourcesContent":["export type LogLevel = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace'\n\nexport type Logger = Record<LogLevel, (...args: unknown[]) => void>\n\nexport const noop = (): void => {}\n\nexport const ABSTRACT_LOGGER: Logger = {\n fatal: noop,\n error: noop,\n warn: noop,\n info: noop,\n debug: noop,\n trace: noop,\n}\n\nexport const CONSOLE_LOGGER: Logger = {\n fatal: console.error.bind(console, '[FATAL]'),\n error: console.error.bind(console, '[ERROR]'),\n warn: console.warn.bind(console, '[WARN]'),\n info: console.info.bind(console, '[INFO]'),\n debug: console.debug.bind(console, '[DEBUG]'),\n trace: console.trace.bind(console, '[TRACE]'),\n}\n","{\n \"name\": \"napcat-sdk\",\n \"type\": \"module\",\n \"version\": \"0.1.2\",\n \"packageManager\": \"pnpm@10.26.0\",\n \"description\": \"A simple SDK for NapCat OneBot v11.\",\n \"keywords\": [\n \"napcat\",\n \"onebot\",\n \"onebot v11\",\n \"sdk\"\n ],\n \"homepage\": \"https://github.com/vikiboss/mioki#readme\",\n \"files\": [\n \"dist\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/vikiboss/mioki/issues\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/vikiboss/mioki.git\",\n \"directory\": \"packages/napcat-sdk\"\n },\n \"scripts\": {\n \"dev\": \"tsdown -w\",\n \"build\": \"tsdown\"\n },\n \"exports\": {\n \".\": {\n \"require\": \"./dist/index.cjs\",\n \"import\": \"./dist/index.mjs\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"author\": \"Viki <hi@viki.moe> (https://github.com/vikiboss)\",\n \"license\": \"MIT\",\n \"devDependencies\": {\n \"@types/node\": \"catalog:dev\",\n \"tsdown\": \"catalog:dev\",\n \"typescript\": \"catalog:dev\"\n },\n \"dependencies\": {\n \"mitt\": \"^3.0.1\"\n }\n}\n","import type { ExtractByType, SendElement } from './types'\n\nfunction createSegment<T extends SendElement['type'], D>(type: T, data: D): SendElement {\n return { type, ...data } as SendElement\n}\n\n/**\n * 消息片段构造器\n */\nexport const segment = {\n /** 创建一个文本消息片段 */\n text: (text: string): SendElement => createSegment('text', { text }),\n /** 创建一个艾特消息片段 */\n at: (qq: 'all' | (string & {})): SendElement => createSegment('at', { qq }),\n /** 创建一个 QQ 表情消息片段 */\n face: (id: number): SendElement => createSegment('face', { id }),\n /** 创建一个回复消息片段 */\n reply: (id: string): SendElement => createSegment('reply', { id }),\n /** 创建一个图片消息片段 */\n image: (file: string, options?: Omit<ExtractByType<SendElement, 'image'>, 'type' | 'file'>): SendElement =>\n createSegment('image', { file, ...options }),\n /** 创建一个语音消息片段 */\n record: (file: string, options?: Omit<ExtractByType<SendElement, 'record'>, 'type' | 'file'>): SendElement =>\n createSegment('record', { file, ...options }),\n /** 创建一个视频消息片段 */\n video: (file: string, options?: Omit<ExtractByType<SendElement, 'video'>, 'type' | 'file'>): SendElement =>\n createSegment('video', { file, ...options }),\n /** 创建一个动态表情消息片段 */\n mface: (options: Omit<ExtractByType<SendElement, 'mface'>, 'type'>): SendElement =>\n createSegment('mface', { ...options }),\n /** 创建一个大表情消息片段 */\n bface: (id: number): SendElement => createSegment('bface', { id }),\n /** 创建一个 联系人/群 分享消息片段 */\n contact: (type: 'qq' | 'group', id: string): SendElement => createSegment('contact', { id, sub_type: type }),\n /** 创建一个戳一戳消息片段 */\n poke: (): SendElement => createSegment('poke', {}),\n /** 创建一个音乐消息片段 */\n music: (platform: 'qq' | '163' | 'kugou' | 'migu' | 'kuwo', id: string): SendElement =>\n createSegment('music', { platform, id }),\n /** 创建一个自定义音乐消息片段 */\n musicCustom: (\n title: string,\n audio: string,\n url: string,\n options?: Omit<ExtractByType<SendElement, 'music'>, 'type' | 'platform' | 'url' | 'audio' | 'title'>,\n ): SendElement => createSegment('music', { platform: 'custom', url, audio, title, ...options }),\n /** 创建一个合并转发消息片段 */\n forward: (id: string): SendElement => createSegment('forward', { id }),\n /** 创建一个 JSON 消息片段 */\n json: (data: string): SendElement => createSegment('json', { data }),\n /** 创建一个文件消息片段 */\n file: (file: string, options?: Omit<ExtractByType<SendElement, 'file'>, 'type' | 'file'>): SendElement =>\n createSegment('file', { file, ...options }),\n /** 创建一个 Markdown 消息片段 */\n markdown: (): SendElement => createSegment('markdown', {}),\n /** 创建一个轻应用消息片段 */\n lightapp: (): SendElement => createSegment('lightapp', {}),\n}\n","import crypto from 'node:crypto'\nimport mitt from 'mitt'\nimport pkg from '../package.json' with { type: 'json' }\nimport { segment } from './segment'\nimport { ABSTRACT_LOGGER } from './logger'\n\nimport type { Emitter } from 'mitt'\nimport type { Logger } from './logger'\nimport type {\n API,\n EventMap,\n Friend,\n FriendWithInfo,\n Group,\n GroupMessageEvent,\n GroupWithInfo,\n MiokiOptions,\n NormalizedElementToSend,\n OptionalProps,\n PrivateMessageEvent,\n Sendable,\n} from './types'\n\nexport const name: string = pkg.name\nexport const version: string = pkg.version\n\nconst DEFAULT_NAPCAT_OPTIONS: Required<OptionalProps<MiokiOptions>> = {\n protocol: 'ws',\n host: 'localhost',\n port: 3333,\n logger: ABSTRACT_LOGGER,\n}\n\nexport class NapCat {\n /** WebSocket 实例 */\n #ws: WebSocket | null = null\n /** 事件发射器 */\n #event: Emitter<EventMap & Record<string | symbol, unknown>> = mitt()\n /** Echo 事件发射器 */\n #echoEvent: Emitter<Record<string, unknown>> = mitt()\n\n constructor(private readonly options: MiokiOptions) {}\n\n /** 配置项 */\n get #config(): Required<MiokiOptions> {\n return {\n protocol: this.options.protocol || DEFAULT_NAPCAT_OPTIONS.protocol,\n host: this.options.host || DEFAULT_NAPCAT_OPTIONS.host,\n port: this.options.port || DEFAULT_NAPCAT_OPTIONS.port,\n logger: this.options.logger || DEFAULT_NAPCAT_OPTIONS.logger,\n token: this.options.token,\n }\n }\n\n /** WebSocket 实例 */\n get ws(): WebSocket {\n if (!this.#ws) {\n this.logger.error('WebSocket is not connected.')\n throw new Error('WebSocket is not connected.')\n }\n\n return this.#ws\n }\n\n /** 日志记录器 */\n get logger(): Logger {\n return this.#config.logger\n }\n\n /** 消息段构建器 */\n get segment(): typeof segment {\n return segment\n }\n\n /** 生成唯一的 echo ID */\n #echoId() {\n return crypto.randomBytes(16).toString('hex')\n }\n\n /** 构建 WebSocket 连接地址 */\n #buildWsUrl(): string {\n return `${this.#config.protocol}://${this.#config.host}:${this.#config.port}?access_token=${this.#config.token}`\n }\n\n /** 包装回复消息 */\n #wrapReply(sendable: Sendable | Sendable[], message_id?: number, reply?: boolean): Sendable[] {\n const sendableList = typeof sendable === 'string' ? [sendable] : [sendable].flat()\n\n if (reply && message_id) {\n return [segment.reply(String(message_id)), ...sendableList]\n }\n\n return sendableList\n }\n\n /** 确保 WebSocket 已连接 */\n #ensureWsConnection(ws: WebSocket | null): asserts ws is WebSocket {\n if (!ws) {\n this.logger.error('WebSocket is not connected.')\n throw new Error('WebSocket is not connected.')\n }\n\n if (ws.readyState !== WebSocket.OPEN) {\n this.logger.error('WebSocket is not open.')\n throw new Error('WebSocket is not open.')\n }\n }\n\n /** 标准化可发送消息元素 */\n #normalizeSendable(msg: Sendable | Sendable[]): NormalizedElementToSend[] {\n return [msg].flat(2).map((item) => {\n if (typeof item === 'string') {\n return { type: 'text', data: { text: item } }\n }\n if (item.type === 'at') {\n return { type: 'at', data: { qq: String(item.qq) } }\n }\n const { type, ...data } = item\n return { type, data } as NormalizedElementToSend\n })\n }\n\n /** 等待服务器响应操作 */\n #waitForAction<T extends any>(echoId: string) {\n const eventName = `echo#${echoId}`\n\n return new Promise<T>((resolve, reject) => {\n const handle = (data: any) => {\n if (!data || data.echo !== echoId) return\n\n this.#echoEvent.off(eventName, handle)\n\n if (data.retcode === 0) {\n resolve(data.data as T)\n } else {\n reject(`Server Error: ${data.message}`)\n }\n }\n\n this.#echoEvent.on(eventName, handle)\n })\n }\n\n /** 构建群对象 */\n #buildGroup<T extends object>(group_id: number, group_name: string = '', extraInfo: T = {} as T): Group & T {\n return {\n ...extraInfo,\n group_id,\n group_name,\n doSign: () => this.api('set_group_sign', { group_id }),\n getInfo: () => this.api('get_group_info', { group_id }),\n getMemberList: async () => this.api('get_group_member_list', { group_id }),\n getMemberInfo: (user_id: number) => this.api('get_group_member_info', { group_id, user_id }),\n setTitle: (title: string) => this.api('set_group_special_title', { group_id, title }),\n setCard: (user_id: number, card: string) => this.api('set_group_card', { group_id, user_id, card }),\n addEssence: (message_id: string) => this.api('set_essence_msg', { message_id }),\n delEssence: (message_id: string) => this.api('delete_essence_msg', { message_id }),\n recall: (message_id: number) => this.api('delete_msg', { message_id }),\n banMember: (user_id: number, duration: number) => this.api('set_group_ban', { group_id, user_id, duration }),\n sendMsg: (sendable: Sendable | Sendable[]) => this.sendGroupMsg(group_id, sendable),\n }\n }\n\n /** 构建好友对象 */\n #buildFriend<T extends object>(user_id: number, nickname: string = '', extraInfo: T = {} as T): Friend & T {\n return {\n ...extraInfo,\n user_id,\n nickname,\n delete: (block?: boolean, both?: boolean) =>\n this.api('delete_friend', { user_id, temp_block: block, temp_both_del: both }),\n sendMsg: (sendable: Sendable | Sendable[]) => this.sendPrivateMsg(user_id, sendable),\n getInfo: () => this.api('get_stranger_info', { user_id }),\n }\n }\n\n /** 构建群消息事件 */\n #buildPrivateMessageEvent(event: PrivateMessageEvent) {\n return {\n ...event,\n message: (event.message || []).map((el: any) => ({ type: el.type, ...el.data })),\n friend: this.#buildFriend(event.user_id, event.sender?.nickname || ''),\n recall: () => this.api('delete_msg', { message_id: event.message_id }),\n reply: (sendable: Sendable | Sendable[], reply = false) =>\n this.sendPrivateMsg(event.user_id, this.#wrapReply(sendable, event.message_id, reply)),\n }\n }\n\n /** 构建群消息事件对象 */\n #buildGroupMessageEvent(event: GroupMessageEvent) {\n return {\n ...event,\n message: (event.message || []).map((el: any) => ({ type: el.type, ...el.data })),\n group: this.#buildGroup(event.group_id, event.group?.group_name || ''),\n recall: () => this.api('delete_msg', { message_id: event.message_id }),\n addReaction: (id: string) =>\n this.api('set_msg_emoji_like', { message_id: event.message_id, emoji_id: id, set: true }),\n delReaction: (id: string) =>\n this.api('set_msg_emoji_like', { message_id: event.message_id, emoji_id: id, set: false }),\n addEssence: () => this.api('set_essence_msg', { message_id: event.message_id }),\n delEssence: () => this.api('delete_essence_msg', { message_id: event.message_id }),\n reply: (sendable: Sendable | Sendable[], reply = false) =>\n this.sendGroupMsg(event.group_id, this.#wrapReply(sendable, event.message_id, reply)),\n }\n }\n\n /** 绑定内部事件处理器 */\n #bindInternalEvents(data: any) {\n if (data.echo) {\n this.#echoEvent.emit(`echo#${data.echo}`, data)\n return\n }\n\n if (data.post_type) {\n switch (data.post_type) {\n case 'meta_event': {\n this.logger.trace(`received meta_event: ${JSON.stringify(data)}`)\n this.#event.emit('meta_event', data)\n\n if (data.meta_event_type) {\n this.#event.emit(`meta_event.${data.meta_event_type}`, data)\n if (data.sub_type) {\n this.#event.emit(`meta_event.${data.meta_event_type}.${data.sub_type}`, data)\n }\n }\n\n break\n }\n\n case 'message': {\n if (data.message_type === 'private') {\n data = this.#buildPrivateMessageEvent(data)\n } else {\n data = this.#buildGroupMessageEvent(data)\n }\n\n this.#event.emit('message', data)\n\n switch (data.message_type) {\n case 'private': {\n this.logger.trace(`received private message: ${JSON.stringify(data)}`)\n this.#event.emit('message.private', data)\n this.#event.emit(`message.private.${data.sub_type}`, data)\n\n break\n }\n\n case 'group': {\n this.logger.trace(`received group message: ${JSON.stringify(data)}`)\n this.#event.emit('message.group', data)\n this.#event.emit(`message.group.${data.sub_type}`, data)\n\n break\n }\n\n default: {\n this.logger.debug(`received unknown message type: ${JSON.stringify(data)}`)\n\n break\n }\n }\n\n break\n }\n\n case 'message_sent': {\n this.logger.trace(`received message_sent: ${JSON.stringify(data)}`)\n this.#event.emit('message_sent', data)\n\n if (data.message_type) {\n this.#event.emit(`message_sent.${data.message_type}`, data)\n if (data.sub_type) {\n this.#event.emit(`message_sent.${data.message_type}.${data.sub_type}`, data)\n }\n }\n\n break\n }\n\n case 'notice': {\n this.logger.trace(`received notice: ${JSON.stringify(data)}`)\n\n if (!data.notice_type) {\n this.logger.debug(`received unknown notice type: ${JSON.stringify(data)}`)\n break\n }\n\n const isNotify = data.notice_type === 'notify'\n const isPoke = data.sub_type === 'poke'\n const isGroup = !!data.group_id\n\n const { notice_type, sub_type } = isNotify\n ? isPoke\n ? { notice_type: isGroup ? 'group' : 'friend', sub_type: 'poke' }\n : NAPCAT_NOTICE_NOTIFY_MAP[data.sub_type] || {}\n : NAPCAT_NOTICE_EVENT_MAP[data.notice_type] || {}\n\n data.original_notice_type = data.notice_type\n data.notice_type = notice_type || data.notice_type\n\n if (data.sub_type && data.sub_type !== sub_type) {\n data.action_type = data.sub_type\n }\n\n data.sub_type = sub_type || data.sub_type\n\n if (isGroup) {\n data.group = this.#buildGroup(data.group_id, data.group_name || '')\n } else {\n data.friend = this.#buildFriend(data.user_id, data.nickname || '')\n }\n\n this.#event.emit('notice', data)\n\n if (notice_type) {\n this.#event.emit(`notice.${notice_type}`, data)\n if (sub_type) {\n this.#event.emit(`notice.${notice_type}.${sub_type}`, data)\n }\n }\n\n break\n }\n\n case 'request': {\n this.logger.trace(`received request: ${JSON.stringify(data)}`)\n\n if (data.request_type === 'friend') {\n data.reject = () => this.api('set_friend_request', { flag: data.flag, approve: false })\n data.approve = () => this.api('set_friend_request', { flag: data.flag, approve: true })\n }\n\n if (data.request_type === 'group') {\n data.reject = (reason?: string) =>\n this.api('set_group_add_request', { flag: data.flag, approve: false, reason })\n data.approve = () => this.api('set_group_add_request', { flag: data.flag, approve: true })\n }\n\n this.#event.emit('request', data)\n\n if (data.request_type) {\n this.#event.emit(`request.${data.request_type}`, data)\n if (data.sub_type) {\n this.#event.emit(`request.${data.request_type}.${data.sub_type}`, data)\n }\n }\n\n break\n }\n\n default: {\n this.logger.debug(`received: ${JSON.stringify(data)}`)\n this.#event.emit(data.post_type, data)\n return\n }\n }\n\n return\n }\n }\n\n /** 获取一个群的信息,可以用于发送群消息等操作 */\n async pickGroup(group_id: number): Promise<GroupWithInfo> {\n const groupInfo = await this.api<ReturnType<Group['getInfo']>>('get_group_info', { group_id })\n return this.#buildGroup(group_id, groupInfo.group_name, groupInfo)\n }\n\n /** 获取一个好友的信息,可以用于发送私聊消息等操作 */\n async pickFriend(user_id: number): Promise<FriendWithInfo> {\n const friendInfo = await this.api<ReturnType<Friend['getInfo']>>('get_stranger_info', { user_id })\n return this.#buildFriend(user_id, friendInfo.nickname, friendInfo)\n }\n\n /**\n * 注册一次性事件监听器\n */\n once<T extends keyof EventMap>(type: T, handler: (event: EventMap[NoInfer<T>]) => void): void {\n const onceHandler = (event: EventMap[NoInfer<T>]) => {\n handler(event)\n this.#event.off(type, onceHandler)\n }\n\n this.logger.debug(`registering once: ${String(type)}`)\n this.#event.on(type, onceHandler)\n }\n\n /**\n * 注册事件监听器,支持主类型或者点分子类型\n *\n * 如: `notice`、`message.private`、`request.group.invite` 等\n *\n * 如果需要移除监听器,请调用 `off` 方法\n */\n on<T extends keyof EventMap>(type: T, handler: (event: EventMap[NoInfer<T>]) => void): void {\n this.logger.debug(`registering: ${String(type)}`)\n this.#event.on(type, handler)\n }\n\n /**\n * 移除事件监听器\n */\n off<T extends keyof EventMap>(type: T, handler: (event: EventMap[NoInfer<T>]) => void): void {\n this.logger.debug(`unregistering: ${String(type)}`)\n this.#event.off(type, handler)\n }\n\n api<T extends any>(action: API | (string & {}), params: Record<string, any> = {}): Promise<T> {\n this.#ensureWsConnection(this.#ws)\n this.logger.debug(`calling api action: ${action} with params: ${JSON.stringify(params)}`)\n const echo = this.#echoId()\n this.#ws.send(JSON.stringify({ echo, action, params }))\n return this.#waitForAction<T>(echo)\n }\n\n /**\n * 发送私聊消息\n */\n sendPrivateMsg(user_id: number, sendable: Sendable | Sendable[]): Promise<{ message_id: number }> {\n return this.api<{ message_id: number }>('send_private_msg', {\n user_id,\n message: this.#normalizeSendable(sendable),\n })\n }\n\n /**\n * 发送群消息\n */\n sendGroupMsg(group_id: number, sendable: Sendable | Sendable[]): Promise<{ message_id: number }> {\n return this.api<{ message_id: number }>('send_group_msg', {\n group_id,\n message: this.#normalizeSendable(sendable),\n })\n }\n\n /** 启动 NapCat SDK 实例,建立 WebSocket 连接 */\n async run(): Promise<void> {\n const { logger: _, ...config } = this.#config\n\n this.logger.info(`bootstrap with config: ${JSON.stringify(config)}`)\n\n return new Promise<void>((resolve, reject) => {\n const ws = new WebSocket(this.#buildWsUrl())\n\n ws.onmessage = (event) => {\n const data = (() => {\n try {\n return JSON.parse(event.data)\n } catch {\n return null\n }\n })() as any\n\n if (!data) {\n this.logger.warn(`received non-json message: ${event.data}`)\n return\n }\n\n this.#event.emit('ws.message', data)\n this.#bindInternalEvents(data)\n }\n\n ws.onclose = () => {\n this.logger.info('closed')\n this.#event.emit('ws.close')\n }\n\n ws.onerror = (error) => {\n this.logger.error(`error: ${error}`)\n this.#event.emit('ws.error', error)\n reject(error)\n }\n\n ws.onopen = () => {\n this.logger.info('connected')\n this.#event.emit('ws.open')\n resolve()\n }\n\n this.#ws = ws\n\n this.logger.trace(`WebSocket instance created: ${this.#ws}`)\n })\n }\n\n /** 销毁 NapCat SDK 实例,关闭 WebSocket 连接 */\n close(): void {\n if (this.#ws) {\n this.logger.info('destroying NapCat SDK instance...')\n this.#ws.close()\n this.#ws = null\n this.logger.info('NapCat SDK instance destroyed.')\n } else {\n this.logger.warn('NapCat SDK instance is not initialized.')\n }\n }\n}\n\n// ==================== 通知事件映射 ====================\n\n/**\n * NapCat 通知类型映射表(notify 类型)\n * @description 将 NapCat 特有的通知类型映射到标准的 notice_type 和 sub_type\n */\nconst NAPCAT_NOTICE_NOTIFY_MAP: Record<string, { notice_type: string; sub_type: string }> = {\n input_status: {\n notice_type: 'friend',\n sub_type: 'input',\n },\n profile_like: {\n notice_type: 'friend',\n sub_type: 'like',\n },\n title: {\n notice_type: 'group',\n sub_type: 'title',\n },\n}\n\n/**\n * NapCat 通知事件映射表(notice 类型)\n * @description 将 NapCat 的原始通知事件类型映射到标准的 notice_type 和 sub_type\n */\nconst NAPCAT_NOTICE_EVENT_MAP: Record<string, { notice_type: string; sub_type: string }> = {\n friend_add: {\n notice_type: 'friend',\n sub_type: 'increase',\n },\n friend_recall: {\n notice_type: 'friend',\n sub_type: 'recall',\n },\n offline_file: {\n notice_type: 'friend',\n sub_type: 'offline_file',\n },\n client_status: {\n notice_type: 'client',\n sub_type: 'status',\n },\n group_admin: {\n notice_type: 'group',\n sub_type: 'admin',\n },\n group_ban: {\n notice_type: 'group',\n sub_type: 'ban',\n },\n group_card: {\n notice_type: 'group',\n sub_type: 'card',\n },\n group_upload: {\n notice_type: 'group',\n sub_type: 'upload',\n },\n group_decrease: {\n notice_type: 'group',\n sub_type: 'decrease',\n },\n group_increase: {\n notice_type: 'group',\n sub_type: 'increase',\n },\n group_msg_emoji_like: {\n notice_type: 'group',\n sub_type: 'reaction',\n },\n essence: {\n notice_type: 'group',\n sub_type: 'essence',\n },\n group_recall: {\n notice_type: 'group',\n sub_type: 'recall',\n },\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["ABSTRACT_LOGGER: Logger","CONSOLE_LOGGER: Logger","name: string","pkg.name","version: string","pkg.version","DEFAULT_NAPCAT_OPTIONS: Required<OptionalProps<MiokiOptions>>","options: MiokiOptions","#config","#ws","#uin","#nickname","crypto","#echoEvent","quote_id: string | null","event","#buildPrivateMessageEvent","#buildFriend","#wrapReply","#buildGroupMessageEvent","#buildGroup","#event","#online","err: any","#ensureWsConnection","#echoId","#waitForAction","#normalizeSendable","#cookieCache","#buildWsUrl","#bindInternalEvents","NAPCAT_NOTICE_NOTIFY_MAP: Record<string, { notice_type: string; sub_type: string }>","NAPCAT_NOTICE_EVENT_MAP: Record<string, { notice_type: string; sub_type: string }>"],"sources":["../src/logger.ts","../package.json","../src/segment.ts","../src/napcat.ts"],"sourcesContent":["export type LogLevel = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace'\n\nexport type Logger = Record<LogLevel, (...args: unknown[]) => void>\n\nexport const noop = (): void => {}\n\nexport const ABSTRACT_LOGGER: Logger = {\n fatal: noop,\n error: noop,\n warn: noop,\n info: noop,\n debug: noop,\n trace: noop,\n}\n\nexport const CONSOLE_LOGGER: Logger = {\n fatal: console.error.bind(console, '[FATAL]'),\n error: console.error.bind(console, '[ERROR]'),\n warn: console.warn.bind(console, '[WARN]'),\n info: console.info.bind(console, '[INFO]'),\n debug: console.debug.bind(console, '[DEBUG]'),\n trace: console.trace.bind(console, '[TRACE]'),\n}\n","{\n \"name\": \"napcat-sdk\",\n \"type\": \"module\",\n \"version\": \"0.2.1\",\n \"packageManager\": \"pnpm@10.26.0\",\n \"description\": \"A simple SDK for NapCat OneBot v11.\",\n \"keywords\": [\n \"napcat\",\n \"onebot\",\n \"onebot v11\",\n \"sdk\"\n ],\n \"homepage\": \"https://github.com/vikiboss/mioki#readme\",\n \"files\": [\n \"dist\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/vikiboss/mioki/issues\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/vikiboss/mioki.git\",\n \"directory\": \"packages/napcat-sdk\"\n },\n \"scripts\": {\n \"dev\": \"tsdown -w\",\n \"build\": \"tsdown\"\n },\n \"exports\": {\n \".\": {\n \"require\": \"./dist/index.cjs\",\n \"import\": \"./dist/index.mjs\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"author\": \"Viki <hi@viki.moe> (https://github.com/vikiboss)\",\n \"license\": \"MIT\",\n \"devDependencies\": {\n \"@types/node\": \"catalog:dev\",\n \"tsdown\": \"catalog:dev\",\n \"typescript\": \"catalog:dev\"\n },\n \"dependencies\": {\n \"mitt\": \"^3.0.1\"\n }\n}\n","import type { ExtractByType, SendElement } from './types'\n\nfunction createSegment<T extends SendElement['type'], D>(type: T, data: D): SendElement {\n return { type, ...data } as SendElement\n}\n\n/**\n * 消息片段构造器\n */\nexport const segment = {\n /** 创建一个文本消息片段 */\n text: (text: string): SendElement => createSegment('text', { text }),\n /** 创建一个艾特消息片段 */\n at: (qq: 'all' | (string & {})): SendElement => createSegment('at', { qq }),\n /** 创建一个 QQ 表情消息片段 */\n face: (id: number): SendElement => createSegment('face', { id }),\n /** 创建一个回复消息片段 */\n reply: (id: string): SendElement => createSegment('reply', { id }),\n /** 创建一个图片消息片段 */\n image: (file: string, options?: Omit<ExtractByType<SendElement, 'image'>, 'type' | 'file'>): SendElement =>\n createSegment('image', { file, ...options }),\n /** 创建一个语音消息片段 */\n record: (file: string, options?: Omit<ExtractByType<SendElement, 'record'>, 'type' | 'file'>): SendElement =>\n createSegment('record', { file, ...options }),\n /** 创建一个视频消息片段 */\n video: (file: string, options?: Omit<ExtractByType<SendElement, 'video'>, 'type' | 'file'>): SendElement =>\n createSegment('video', { file, ...options }),\n /** 创建一个动态表情消息片段 */\n mface: (options: Omit<ExtractByType<SendElement, 'mface'>, 'type'>): SendElement =>\n createSegment('mface', { ...options }),\n /** 创建一个大表情消息片段 */\n bface: (id: number): SendElement => createSegment('bface', { id }),\n /** 创建一个 联系人/群 分享消息片段 */\n contact: (type: 'qq' | 'group', id: string): SendElement => createSegment('contact', { id, sub_type: type }),\n /** 创建一个戳一戳消息片段 */\n poke: (): SendElement => createSegment('poke', {}),\n /** 创建一个音乐消息片段 */\n music: (platform: 'qq' | '163' | 'kugou' | 'migu' | 'kuwo', id: string): SendElement =>\n createSegment('music', { platform, id }),\n /** 创建一个自定义音乐消息片段 */\n musicCustom: (\n title: string,\n audio: string,\n url: string,\n options?: Omit<ExtractByType<SendElement, 'music'>, 'type' | 'platform' | 'url' | 'audio' | 'title'>,\n ): SendElement => createSegment('music', { platform: 'custom', url, audio, title, ...options }),\n /** 创建一个合并转发消息片段 */\n node: (options: Partial<ExtractByType<SendElement, 'node'>>): SendElement => createSegment('node', { ...options }),\n /** 创建一个合并转发消息片段 */\n forward: (id: string): SendElement => createSegment('forward', { id }),\n /** 创建一个 JSON 消息片段 */\n json: (data: string): SendElement => createSegment('json', { data }),\n /** 创建一个文件消息片段 */\n file: (file: string, options?: Omit<ExtractByType<SendElement, 'file'>, 'type' | 'file'>): SendElement =>\n createSegment('file', { file, ...options }),\n /** 创建一个 Markdown 消息片段 */\n markdown: (): SendElement => createSegment('markdown', {}),\n /** 创建一个轻应用消息片段 */\n lightapp: (): SendElement => createSegment('lightapp', {}),\n}\n","import crypto from 'node:crypto'\nimport mitt from 'mitt'\nimport pkg from '../package.json' with { type: 'json' }\nimport { segment } from './segment'\nimport { ABSTRACT_LOGGER } from './logger'\n\nimport type { Emitter } from 'mitt'\nimport type { Logger } from './logger'\nimport type {\n API,\n EventMap,\n Friend,\n FriendWithInfo,\n Group,\n GroupMessageEvent,\n GroupWithInfo,\n MiokiOptions,\n NormalizedElementToSend,\n OptionalProps,\n PrivateMessageEvent,\n Sendable,\n} from './types'\n\nexport const name: string = pkg.name\nexport const version: string = pkg.version\n\nconst DEFAULT_NAPCAT_OPTIONS: Required<OptionalProps<MiokiOptions>> = {\n protocol: 'ws',\n host: 'localhost',\n port: 3333,\n logger: ABSTRACT_LOGGER,\n}\n\nexport class NapCat {\n /** WebSocket 实例 */\n #ws: WebSocket | null = null\n /** 事件发射器 */\n #event: Emitter<EventMap & Record<string | symbol, unknown>> = mitt()\n /** Echo 事件发射器 */\n #echoEvent: Emitter<Record<string, unknown>> = mitt()\n /** 机器人 ID */\n #uin: number = 0\n /** 机器人昵称 */\n #nickname: string = '-'\n /** 机器人状态 */\n #online: boolean = false\n /** Cookies 缓存 */\n #cookieCache = new Map<\n string,\n {\n uin: number\n pskey: string\n skey: string\n gtk: string\n bkn: string\n cookie: string\n legacyCookie: string\n }\n >()\n\n constructor(private readonly options: MiokiOptions) {}\n\n /** 配置项 */\n get #config(): Required<MiokiOptions> {\n return {\n protocol: this.options.protocol || DEFAULT_NAPCAT_OPTIONS.protocol,\n host: this.options.host || DEFAULT_NAPCAT_OPTIONS.host,\n port: this.options.port || DEFAULT_NAPCAT_OPTIONS.port,\n logger: this.options.logger || DEFAULT_NAPCAT_OPTIONS.logger,\n token: this.options.token,\n }\n }\n\n /** WebSocket 实例 */\n get ws(): WebSocket {\n if (!this.#ws) {\n this.logger.error('WebSocket is not connected.')\n throw new Error('WebSocket is not connected.')\n }\n\n return this.#ws\n }\n\n /** 日志记录器 */\n get logger(): Logger {\n return this.#config.logger\n }\n\n /** 消息段构建器 */\n get segment(): typeof segment {\n return segment\n }\n\n /**\n * 机器人 QQ 号\n */\n get user_id(): number {\n return this.uin\n }\n\n /**\n * 机器人 QQ 号\n */\n get uin(): number {\n return this.#uin\n }\n\n /**\n * 机器人昵称\n */\n get nickname(): string {\n return this.#nickname\n }\n\n /** 生成唯一的 echo ID */\n #echoId() {\n return crypto.randomBytes(16).toString('hex')\n }\n\n /** 构建 WebSocket 连接地址 */\n #buildWsUrl(): string {\n return `${this.#config.protocol}://${this.#config.host}:${this.#config.port}?access_token=${this.#config.token}`\n }\n\n /** 包装回复消息 */\n #wrapReply(sendable: Sendable | Sendable[], message_id?: number, reply?: boolean): Sendable[] {\n const sendableList = typeof sendable === 'string' ? [sendable] : [sendable].flat()\n\n if (reply && message_id) {\n return [segment.reply(String(message_id)), ...sendableList]\n }\n\n return sendableList\n }\n\n /** 确保 WebSocket 已连接 */\n #ensureWsConnection(ws: WebSocket | null): asserts ws is WebSocket {\n if (!ws) {\n this.logger.error('WebSocket is not connected.')\n throw new Error('WebSocket is not connected.')\n }\n\n if (ws.readyState !== WebSocket.OPEN) {\n this.logger.error('WebSocket is not open.')\n throw new Error('WebSocket is not open.')\n }\n }\n\n /** 标准化可发送消息元素 */\n #normalizeSendable(msg: Sendable | Sendable[]): NormalizedElementToSend[] {\n return [msg].flat(2).map((item) => {\n if (typeof item === 'string') {\n return { type: 'text', data: { text: item } }\n }\n if (item.type === 'at') {\n return { type: 'at', data: { qq: String(item.qq) } }\n }\n const { type, ...data } = item\n return { type, data } as NormalizedElementToSend\n })\n }\n\n /** 等待服务器响应操作 */\n #waitForAction<T extends any>(echoId: string) {\n const eventName = `echo#${echoId}`\n\n return new Promise<T>((resolve, reject) => {\n const handle = (data: any) => {\n if (!data || data.echo !== echoId) return\n\n this.#echoEvent.off(eventName, handle)\n\n if (data.retcode === 0) {\n resolve(data.data as T)\n } else {\n reject(`Server Error: ${data.message}`)\n }\n }\n\n this.#echoEvent.on(eventName, handle)\n })\n }\n\n /** 构建群对象 */\n #buildGroup<T extends object>(group_id: number, group_name: string = '', extraInfo: T = {} as T): Group & T {\n return {\n ...extraInfo,\n group_id,\n group_name,\n napcat: this,\n doSign: () => this.api('set_group_sign', { group_id }),\n getInfo: () => this.api('get_group_info', { group_id }),\n getMemberList: async () => this.api('get_group_member_list', { group_id }),\n getMemberInfo: (user_id: number) => this.api('get_group_member_info', { group_id, user_id }),\n setTitle: (title: string) => this.api('set_group_special_title', { group_id, title }),\n setCard: (user_id: number, card: string) => this.api('set_group_card', { group_id, user_id, card }),\n addEssence: (message_id: string) => this.api('set_essence_msg', { message_id }),\n delEssence: (message_id: string) => this.api('delete_essence_msg', { message_id }),\n recall: (message_id: number) => this.api('delete_msg', { message_id }),\n banMember: (user_id: number, duration: number) => this.api('set_group_ban', { group_id, user_id, duration }),\n sendMsg: (sendable: Sendable | Sendable[]) => this.sendGroupMsg(group_id, sendable),\n }\n }\n\n /** 构建好友对象 */\n #buildFriend<T extends object>(user_id: number, nickname: string = '', extraInfo: T = {} as T): Friend & T {\n return {\n ...extraInfo,\n user_id,\n nickname,\n napcat: this,\n delete: (block?: boolean, both?: boolean) =>\n this.api('delete_friend', { user_id, temp_block: block, temp_both_del: both }),\n sendMsg: (sendable: Sendable | Sendable[]) => this.sendPrivateMsg(user_id, sendable),\n getInfo: () => this.api('get_stranger_info', { user_id }),\n }\n }\n\n /** 构建私聊消息事件 */\n #buildPrivateMessageEvent(event: Omit<PrivateMessageEvent, 'message'> & { message: any[] }): PrivateMessageEvent {\n const quote_id: string | null = event.message.find((el: any) => el.type === 'reply')?.data?.id || null\n\n return {\n ...event,\n quote_id,\n getQuoteMessage: async (): Promise<PrivateMessageEvent | null> => {\n if (!quote_id) return null\n const event = await this.api<PrivateMessageEvent>('get_msg', { message_id: quote_id })\n return this.#buildPrivateMessageEvent(event)\n },\n message: (event.message || [])\n .filter((e) => e.type !== 'reply')\n .map((el: any) => ({ type: el.type, ...el.data })),\n friend: this.#buildFriend(event.user_id, event.sender?.nickname || ''),\n reply: (sendable: Sendable | Sendable[], reply = false) =>\n this.sendPrivateMsg(event.user_id, this.#wrapReply(sendable, event.message_id, reply)),\n }\n }\n\n /** 构建群消息事件对象 */\n #buildGroupMessageEvent(event: Omit<GroupMessageEvent, 'message'> & { message: any[] }): GroupMessageEvent {\n const quote_id: string | null = event.message.find((el: any) => el.type === 'reply')?.data?.id || null\n\n return {\n ...event,\n quote_id,\n getQuoteMessage: async (): Promise<GroupMessageEvent | null> => {\n if (!quote_id) return null\n const event = await this.api<GroupMessageEvent>('get_msg', { message_id: quote_id })\n return this.#buildGroupMessageEvent(event)\n },\n message: (event.message || [])\n .filter((e) => e.type !== 'reply')\n .map((el: any) => ({ type: el.type, ...el.data })),\n group: this.#buildGroup(event.group_id, event.group?.group_name || ''),\n recall: () => this.api<any>('delete_msg', { message_id: event.message_id }),\n addReaction: (id: string) =>\n this.api('set_msg_emoji_like', { message_id: event.message_id, emoji_id: id, set: true }),\n delReaction: (id: string) =>\n this.api('set_msg_emoji_like', { message_id: event.message_id, emoji_id: id, set: false }),\n addEssence: () => this.api('set_essence_msg', { message_id: event.message_id }),\n delEssence: () => this.api('delete_essence_msg', { message_id: event.message_id }),\n reply: (sendable: Sendable | Sendable[], reply = false) =>\n this.sendGroupMsg(event.group_id, this.#wrapReply(sendable, event.message_id, reply)),\n }\n }\n\n /** 绑定内部事件处理器 */\n #bindInternalEvents(data: any) {\n if (data.echo) {\n this.#echoEvent.emit(`echo#${data.echo}`, data)\n return\n }\n\n if (data.post_type) {\n switch (data.post_type) {\n case 'meta_event': {\n this.logger.trace(`received meta_event: ${JSON.stringify(data)}`)\n this.#event.emit('meta_event', data)\n\n if (data.meta_event_type) {\n this.#event.emit(`meta_event.${data.meta_event_type}`, data)\n if (data.sub_type) {\n if (data.sub_type === 'connect') {\n this.#uin = data.self_id\n this.#online = true\n this.#event.emit('napcat.connected', { uin: this.#uin, ts: data.time * 1000 })\n\n this.getLoginInfo().then((info) => {\n this.#nickname = info.nickname\n })\n }\n\n this.#event.emit(`meta_event.${data.meta_event_type}.${data.sub_type}`, data)\n }\n }\n\n break\n }\n\n case 'message': {\n if (data.message_type === 'private') {\n data = this.#buildPrivateMessageEvent(data)\n } else {\n data = this.#buildGroupMessageEvent(data)\n }\n\n this.#event.emit('message', data)\n\n switch (data.message_type) {\n case 'private': {\n this.logger.trace(`received private message: ${JSON.stringify(data)}`)\n this.#event.emit('message.private', data)\n this.#event.emit(`message.private.${data.sub_type}`, data)\n\n break\n }\n\n case 'group': {\n this.logger.trace(`received group message: ${JSON.stringify(data)}`)\n this.#event.emit('message.group', data)\n this.#event.emit(`message.group.${data.sub_type}`, data)\n\n break\n }\n\n default: {\n this.logger.debug(`received unknown message type: ${JSON.stringify(data)}`)\n\n break\n }\n }\n\n break\n }\n\n case 'message_sent': {\n this.logger.trace(`received message_sent: ${JSON.stringify(data)}`)\n this.#event.emit('message_sent', data)\n\n if (data.message_type) {\n this.#event.emit(`message_sent.${data.message_type}`, data)\n if (data.sub_type) {\n this.#event.emit(`message_sent.${data.message_type}.${data.sub_type}`, data)\n }\n }\n\n break\n }\n\n case 'notice': {\n this.logger.trace(`received notice: ${JSON.stringify(data)}`)\n\n if (!data.notice_type) {\n this.logger.debug(`received unknown notice type: ${JSON.stringify(data)}`)\n break\n }\n\n const isNotify = data.notice_type === 'notify'\n const isPoke = data.sub_type === 'poke'\n const isGroup = !!data.group_id\n\n const { notice_type, sub_type } = isNotify\n ? isPoke\n ? { notice_type: isGroup ? 'group' : 'friend', sub_type: 'poke' }\n : NAPCAT_NOTICE_NOTIFY_MAP[data.sub_type] || {}\n : NAPCAT_NOTICE_EVENT_MAP[data.notice_type] || {}\n\n data.original_notice_type = data.notice_type\n data.notice_type = notice_type || data.notice_type\n\n if (data.sub_type && data.sub_type !== sub_type) {\n data.action_type = data.sub_type\n }\n\n data.sub_type = sub_type || data.sub_type\n\n if (isGroup) {\n data.group = this.#buildGroup(data.group_id, data.group_name || '')\n } else {\n data.friend = this.#buildFriend(data.user_id, data.nickname || '')\n }\n\n this.#event.emit('notice', data)\n\n if (notice_type) {\n this.#event.emit(`notice.${notice_type}`, data)\n if (sub_type) {\n this.#event.emit(`notice.${notice_type}.${sub_type}`, data)\n }\n }\n\n break\n }\n\n case 'request': {\n this.logger.trace(`received request: ${JSON.stringify(data)}`)\n\n if (data.request_type === 'friend') {\n data.reject = () => this.api('set_friend_request', { flag: data.flag, approve: false })\n data.approve = () => this.api('set_friend_request', { flag: data.flag, approve: true })\n }\n\n if (data.request_type === 'group') {\n data.reject = (reason?: string) =>\n this.api('set_group_add_request', { flag: data.flag, approve: false, reason })\n data.approve = () => this.api('set_group_add_request', { flag: data.flag, approve: true })\n }\n\n this.#event.emit('request', data)\n\n if (data.request_type) {\n this.#event.emit(`request.${data.request_type}`, data)\n if (data.sub_type) {\n this.#event.emit(`request.${data.request_type}.${data.sub_type}`, data)\n }\n }\n\n break\n }\n\n default: {\n this.logger.debug(`received: ${JSON.stringify(data)}`)\n this.#event.emit(data.post_type, data)\n return\n }\n }\n\n return\n }\n }\n\n /** 获取一个群的信息,可以用于发送群消息等操作 */\n async pickGroup(group_id: number): Promise<GroupWithInfo | null> {\n try {\n const groupInfo = await this.api<ReturnType<Group['getInfo']>>('get_group_info', { group_id })\n return this.#buildGroup(group_id, groupInfo.group_name, groupInfo)\n } catch (err: any) {\n this.logger.warn(`Error to pickGroup ${group_id}: ${err?.message || err}`)\n return null\n }\n }\n\n /** 获取一个好友的信息,可以用于发送私聊消息等操作 */\n async pickFriend(user_id: number): Promise<FriendWithInfo | null> {\n try {\n const friendInfo = await this.api<ReturnType<Friend['getInfo']>>('get_stranger_info', { user_id })\n return this.#buildFriend(user_id, friendInfo.nickname, friendInfo)\n } catch (err: any) {\n this.logger.warn(`Error to pickFriend ${user_id}: ${err?.message || err}`)\n // return this.#buildFriend(user_id, '', {}) as FriendWithInfo\n return null\n }\n }\n\n /**\n * 注册一次性事件监听器\n */\n once<T extends keyof EventMap>(type: T, handler: (event: EventMap[NoInfer<T>]) => void): void {\n const onceHandler = (event: EventMap[NoInfer<T>]) => {\n handler(event)\n this.#event.off(type, onceHandler)\n }\n\n this.logger.debug(`registering once: ${String(type)}`)\n this.#event.on(type, onceHandler)\n }\n\n /**\n * 注册事件监听器,支持主类型或者点分子类型\n *\n * 如: `notice`、`message.private`、`request.group.invite` 等\n *\n * 如果需要移除监听器,请调用 `off` 方法\n */\n on<T extends keyof EventMap>(type: T, handler: (event: EventMap[NoInfer<T>]) => void): void {\n this.logger.debug(`registering: ${String(type)}`)\n this.#event.on(type, handler)\n }\n\n /**\n * 移除事件监听器\n */\n off<T extends keyof EventMap>(type: T, handler: (event: EventMap[NoInfer<T>]) => void): void {\n this.logger.debug(`unregistering: ${String(type)}`)\n this.#event.off(type, handler)\n }\n\n /**\n * 调用 NapCat API\n */\n api<T extends any>(action: API | (string & {}), params: Record<string, any> = {}): Promise<T> {\n this.#ensureWsConnection(this.#ws)\n this.logger.debug(`calling api action: ${action} with params: ${JSON.stringify(params)}`)\n const echo = this.#echoId()\n this.#ws.send(JSON.stringify({ echo, action, params }))\n return this.#waitForAction<T>(echo)\n }\n\n /**\n * 发送私聊消息\n */\n sendPrivateMsg(user_id: number, sendable: Sendable | Sendable[]): Promise<{ message_id: number }> {\n return this.api<{ message_id: number }>('send_private_msg', {\n user_id,\n message: this.#normalizeSendable(sendable),\n })\n }\n\n /**\n * 发送群消息\n */\n sendGroupMsg(group_id: number, sendable: Sendable | Sendable[]): Promise<{ message_id: number }> {\n return this.api<{ message_id: number }>('send_group_msg', {\n group_id,\n message: this.#normalizeSendable(sendable),\n })\n }\n\n /**\n * 机器人是否在线\n */\n isOnline(): boolean {\n return this.#ws?.readyState === WebSocket.OPEN && this.#online\n }\n\n /**\n * 计算 GTK 值\n */\n getGTk(pskey: string): number {\n let gkt = 5381\n for (let i = 0, len = pskey.length; i < len; ++i) {\n gkt += (gkt << 5) + pskey.charCodeAt(i)\n }\n return gkt & 0x7fffffff\n }\n\n /**\n * 获取 NapCat 原始 Cookie 相关信息\n */\n getNapCatCookies(domain: string): Promise<{ cookies: string; bkn: string }> {\n return this.api<{ cookies: string; bkn: string }>('get_cookies', { domain })\n }\n\n /**\n * 获取版本信息\n */\n getVersionInfo(): Promise<{ app_name: string; protocol_version: string; app_version: string }> {\n return this.api<{ app_name: string; protocol_version: string; app_version: string }>('get_version_info')\n }\n\n /**\n * 获取登录信息\n */\n getLoginInfo(): Promise<{ user_id: number; nickname: string }> {\n return this.api<{ user_id: number; nickname: string }>('get_login_info')\n }\n\n /**\n * 获取 Cookie 相关信息\n */\n async getCookie(domain: string): Promise<{\n uin: number\n pskey: string\n skey: string\n gtk: string\n bkn: string\n cookie: string\n legacyCookie: string\n }> {\n const cache = this.#cookieCache.get(domain)\n\n if (cache) return cache\n\n const { cookies: cookieString, bkn } = await this.getNapCatCookies(domain)\n\n const skey = cookieString.match(/skey=([^;]*)/)?.[1] || ''\n const pskey = cookieString.match(/pskey=([^;]*)/)?.[1] || ''\n const gtk = this.getGTk(pskey)\n\n const returns = {\n pskey,\n skey,\n uin: this.uin,\n gtk: String(gtk),\n bkn,\n cookie: `uin=${this.uin}; skey=${skey}; p_uin=${this.uin}; p_skey=${pskey};`,\n legacyCookie: `uin=o${this.uin}; skey=${skey}; p_uin=o${this.uin}; p_skey=${pskey};`,\n }\n\n this.#cookieCache.set(domain, returns)\n\n // 1 小时后清除缓存\n setTimeout(\n () => {\n this.#cookieCache.delete(domain)\n },\n 1000 * 60 * 60,\n )\n\n return returns\n }\n\n /**\n * 通过域名获取 Pskey\n */\n async getPskey(domain: string): Promise<string> {\n const { pskey } = await this.getCookie(domain)\n return pskey\n }\n\n /**\n * 获取 Bkn 值\n */\n async getBkn(): Promise<string> {\n const { bkn } = await this.getCookie('vip.qq.com')\n return bkn\n }\n\n /** 启动 NapCat SDK 实例,建立 WebSocket 连接 */\n async run(): Promise<void> {\n const { logger: _, token: __, ...config } = this.#config\n\n this.logger.info(`run with config: ${JSON.stringify(config)}`)\n\n return new Promise<void>((resolve, reject) => {\n const ws = new WebSocket(this.#buildWsUrl())\n\n ws.onmessage = (event) => {\n const data = (() => {\n try {\n return JSON.parse(event.data)\n } catch {\n return null\n }\n })() as any\n\n if (!data) {\n this.logger.warn(`received non-json message: ${event.data}`)\n return\n }\n\n this.#event.emit('ws.message', data)\n this.#bindInternalEvents(data)\n }\n\n ws.onclose = () => {\n this.#online = false\n this.logger.info('closed')\n this.#event.emit('ws.close')\n }\n\n ws.onerror = (error) => {\n this.#online = false\n this.logger.error(`error: ${error}`)\n this.#event.emit('ws.error', error)\n reject(error)\n }\n\n ws.onopen = () => {\n this.logger.info('NapCat connected')\n this.#event.emit('ws.open')\n resolve()\n }\n\n this.#ws = ws\n\n this.logger.trace(`WebSocket instance created: ${this.#ws}`)\n })\n }\n\n /** 销毁 NapCat SDK 实例,关闭 WebSocket 连接 */\n close(): void {\n if (this.#ws) {\n this.logger.info('destroying NapCat SDK instance...')\n this.#ws.close()\n this.#ws = null\n this.logger.info('NapCat SDK instance destroyed.')\n } else {\n this.logger.warn('NapCat SDK instance is not initialized.')\n }\n }\n}\n\n// ==================== 通知事件映射 ====================\n\n/**\n * NapCat 通知类型映射表(notify 类型)\n * @description 将 NapCat 特有的通知类型映射到标准的 notice_type 和 sub_type\n */\nconst NAPCAT_NOTICE_NOTIFY_MAP: Record<string, { notice_type: string; sub_type: string }> = {\n input_status: {\n notice_type: 'friend',\n sub_type: 'input',\n },\n profile_like: {\n notice_type: 'friend',\n sub_type: 'like',\n },\n title: {\n notice_type: 'group',\n sub_type: 'title',\n },\n}\n\n/**\n * NapCat 通知事件映射表(notice 类型)\n * @description 将 NapCat 的原始通知事件类型映射到标准的 notice_type 和 sub_type\n */\nconst NAPCAT_NOTICE_EVENT_MAP: Record<string, { notice_type: string; sub_type: string }> = {\n friend_add: {\n notice_type: 'friend',\n sub_type: 'increase',\n },\n friend_recall: {\n notice_type: 'friend',\n sub_type: 'recall',\n },\n offline_file: {\n notice_type: 'friend',\n sub_type: 'offline_file',\n },\n client_status: {\n notice_type: 'client',\n sub_type: 'status',\n },\n group_admin: {\n notice_type: 'group',\n sub_type: 'admin',\n },\n group_ban: {\n notice_type: 'group',\n sub_type: 'ban',\n },\n group_card: {\n notice_type: 'group',\n sub_type: 'card',\n },\n group_upload: {\n notice_type: 'group',\n sub_type: 'upload',\n },\n group_decrease: {\n notice_type: 'group',\n sub_type: 'decrease',\n },\n group_increase: {\n notice_type: 'group',\n sub_type: 'increase',\n },\n group_msg_emoji_like: {\n notice_type: 'group',\n sub_type: 'reaction',\n },\n essence: {\n notice_type: 'group',\n sub_type: 'essence',\n },\n group_recall: {\n notice_type: 'group',\n sub_type: 'recall',\n },\n}\n"],"mappings":"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"}
|
package/dist/index.d.cts
CHANGED
|
@@ -32,6 +32,11 @@ interface EventMap extends OneBotEventMap {
|
|
|
32
32
|
"ws.error": Event;
|
|
33
33
|
/** 收到 WebSocket 消息 */
|
|
34
34
|
"ws.message": any;
|
|
35
|
+
/** NapCat 连接已建立 */
|
|
36
|
+
"napcat.connected": {
|
|
37
|
+
uin: number;
|
|
38
|
+
ts: number;
|
|
39
|
+
};
|
|
35
40
|
}
|
|
36
41
|
/**
|
|
37
42
|
* 媒体消息的通用属性
|
|
@@ -285,9 +290,7 @@ interface SendNodeContentElement {
|
|
|
285
290
|
/** 发送者昵称(可选) */
|
|
286
291
|
nickname?: string;
|
|
287
292
|
/** 自定义消息内容 */
|
|
288
|
-
content:
|
|
289
|
-
type: "node";
|
|
290
|
-
}>[];
|
|
293
|
+
content: SendElement[];
|
|
291
294
|
}
|
|
292
295
|
/** 发送的合并转发节点消息段 */
|
|
293
296
|
type SendNodeElement = SendNodeRefElement | SendNodeContentElement;
|
|
@@ -418,6 +421,8 @@ interface Group {
|
|
|
418
421
|
group_id: number;
|
|
419
422
|
/** 群名称 */
|
|
420
423
|
group_name: string;
|
|
424
|
+
/** NapCat 实例 */
|
|
425
|
+
napcat: NapCat;
|
|
421
426
|
/** 群签到 */
|
|
422
427
|
doSign: () => Promise<string>;
|
|
423
428
|
/** 获取群信息 */
|
|
@@ -458,6 +463,8 @@ interface Friend {
|
|
|
458
463
|
user_id: number;
|
|
459
464
|
/** 好友昵称 */
|
|
460
465
|
nickname: string;
|
|
466
|
+
/** NapCat 实例 */
|
|
467
|
+
napcat: NapCat;
|
|
461
468
|
/** 发送私聊消息 */
|
|
462
469
|
sendMsg: SendMsg;
|
|
463
470
|
/** 删除好友 */
|
|
@@ -556,6 +563,8 @@ type FriendWithInfo = Friend & Awaited<ReturnType<Friend["getInfo"]>>;
|
|
|
556
563
|
type MessageEventBase<T extends MessageType, U$1 extends object> = EventBase<"message", U$1 & {
|
|
557
564
|
/** 消息 ID */
|
|
558
565
|
message_id: number;
|
|
566
|
+
/** 引用的消息 ID */
|
|
567
|
+
quote_id: string | null;
|
|
559
568
|
/** 消息类型 */
|
|
560
569
|
message_type: T;
|
|
561
570
|
/** 消息序号 */
|
|
@@ -584,6 +593,8 @@ type PrivateMessageEvent = MessageEventBase<"private", {
|
|
|
584
593
|
target_id: number;
|
|
585
594
|
/** 好友信息对象 */
|
|
586
595
|
friend: Friend;
|
|
596
|
+
/** 获取引用的消息 */
|
|
597
|
+
getQuoteMessage: () => Promise<PrivateMessageEvent | null>;
|
|
587
598
|
/** 发送者信息 */
|
|
588
599
|
sender: {
|
|
589
600
|
/** 发送者 QQ 号 */
|
|
@@ -611,6 +622,12 @@ type GroupMessageEvent = MessageEventBase<"group", {
|
|
|
611
622
|
addReaction: ReactionAction;
|
|
612
623
|
/** 删除消息表态的方法 */
|
|
613
624
|
delReaction: ReactionAction;
|
|
625
|
+
/** 获取引用的消息 */
|
|
626
|
+
getQuoteMessage: () => Promise<GroupMessageEvent | null>;
|
|
627
|
+
/** 添加精华消息的方法 */
|
|
628
|
+
addEssence: () => Promise<void>;
|
|
629
|
+
/** 删除精华消息的方法 */
|
|
630
|
+
delEssence: () => Promise<void>;
|
|
614
631
|
/** 群信息对象 */
|
|
615
632
|
group: Group;
|
|
616
633
|
/** 发送者信息 */
|
|
@@ -964,6 +981,8 @@ declare const segment: {
|
|
|
964
981
|
/** 创建一个自定义音乐消息片段 */
|
|
965
982
|
musicCustom: (title: string, audio: string, url: string, options?: Omit<ExtractByType<SendElement, "music">, "type" | "platform" | "url" | "audio" | "title">) => SendElement;
|
|
966
983
|
/** 创建一个合并转发消息片段 */
|
|
984
|
+
node: (options: Partial<ExtractByType<SendElement, "node">>) => SendElement;
|
|
985
|
+
/** 创建一个合并转发消息片段 */
|
|
967
986
|
forward: (id: string) => SendElement;
|
|
968
987
|
/** 创建一个 JSON 消息片段 */
|
|
969
988
|
json: (data: string) => SendElement;
|
|
@@ -988,10 +1007,22 @@ declare class NapCat {
|
|
|
988
1007
|
get logger(): Logger;
|
|
989
1008
|
/** 消息段构建器 */
|
|
990
1009
|
get segment(): typeof segment;
|
|
1010
|
+
/**
|
|
1011
|
+
* 机器人 QQ 号
|
|
1012
|
+
*/
|
|
1013
|
+
get user_id(): number;
|
|
1014
|
+
/**
|
|
1015
|
+
* 机器人 QQ 号
|
|
1016
|
+
*/
|
|
1017
|
+
get uin(): number;
|
|
1018
|
+
/**
|
|
1019
|
+
* 机器人昵称
|
|
1020
|
+
*/
|
|
1021
|
+
get nickname(): string;
|
|
991
1022
|
/** 获取一个群的信息,可以用于发送群消息等操作 */
|
|
992
|
-
pickGroup(group_id: number): Promise<GroupWithInfo>;
|
|
1023
|
+
pickGroup(group_id: number): Promise<GroupWithInfo | null>;
|
|
993
1024
|
/** 获取一个好友的信息,可以用于发送私聊消息等操作 */
|
|
994
|
-
pickFriend(user_id: number): Promise<FriendWithInfo>;
|
|
1025
|
+
pickFriend(user_id: number): Promise<FriendWithInfo | null>;
|
|
995
1026
|
/**
|
|
996
1027
|
* 注册一次性事件监听器
|
|
997
1028
|
*/
|
|
@@ -1008,6 +1039,9 @@ declare class NapCat {
|
|
|
1008
1039
|
* 移除事件监听器
|
|
1009
1040
|
*/
|
|
1010
1041
|
off<T extends keyof EventMap>(type: T, handler: (event: EventMap[NoInfer<T>]) => void): void;
|
|
1042
|
+
/**
|
|
1043
|
+
* 调用 NapCat API
|
|
1044
|
+
*/
|
|
1011
1045
|
api<T extends any>(action: API | (string & {}), params?: Record<string, any>): Promise<T>;
|
|
1012
1046
|
/**
|
|
1013
1047
|
* 发送私聊消息
|
|
@@ -1021,6 +1055,56 @@ declare class NapCat {
|
|
|
1021
1055
|
sendGroupMsg(group_id: number, sendable: Sendable | Sendable[]): Promise<{
|
|
1022
1056
|
message_id: number;
|
|
1023
1057
|
}>;
|
|
1058
|
+
/**
|
|
1059
|
+
* 机器人是否在线
|
|
1060
|
+
*/
|
|
1061
|
+
isOnline(): boolean;
|
|
1062
|
+
/**
|
|
1063
|
+
* 计算 GTK 值
|
|
1064
|
+
*/
|
|
1065
|
+
getGTk(pskey: string): number;
|
|
1066
|
+
/**
|
|
1067
|
+
* 获取 NapCat 原始 Cookie 相关信息
|
|
1068
|
+
*/
|
|
1069
|
+
getNapCatCookies(domain: string): Promise<{
|
|
1070
|
+
cookies: string;
|
|
1071
|
+
bkn: string;
|
|
1072
|
+
}>;
|
|
1073
|
+
/**
|
|
1074
|
+
* 获取版本信息
|
|
1075
|
+
*/
|
|
1076
|
+
getVersionInfo(): Promise<{
|
|
1077
|
+
app_name: string;
|
|
1078
|
+
protocol_version: string;
|
|
1079
|
+
app_version: string;
|
|
1080
|
+
}>;
|
|
1081
|
+
/**
|
|
1082
|
+
* 获取登录信息
|
|
1083
|
+
*/
|
|
1084
|
+
getLoginInfo(): Promise<{
|
|
1085
|
+
user_id: number;
|
|
1086
|
+
nickname: string;
|
|
1087
|
+
}>;
|
|
1088
|
+
/**
|
|
1089
|
+
* 获取 Cookie 相关信息
|
|
1090
|
+
*/
|
|
1091
|
+
getCookie(domain: string): Promise<{
|
|
1092
|
+
uin: number;
|
|
1093
|
+
pskey: string;
|
|
1094
|
+
skey: string;
|
|
1095
|
+
gtk: string;
|
|
1096
|
+
bkn: string;
|
|
1097
|
+
cookie: string;
|
|
1098
|
+
legacyCookie: string;
|
|
1099
|
+
}>;
|
|
1100
|
+
/**
|
|
1101
|
+
* 通过域名获取 Pskey
|
|
1102
|
+
*/
|
|
1103
|
+
getPskey(domain: string): Promise<string>;
|
|
1104
|
+
/**
|
|
1105
|
+
* 获取 Bkn 值
|
|
1106
|
+
*/
|
|
1107
|
+
getBkn(): Promise<string>;
|
|
1024
1108
|
/** 启动 NapCat SDK 实例,建立 WebSocket 连接 */
|
|
1025
1109
|
run(): Promise<void>;
|
|
1026
1110
|
/** 销毁 NapCat SDK 实例,关闭 WebSocket 连接 */
|
package/dist/index.d.mts
CHANGED
|
@@ -32,6 +32,11 @@ interface EventMap extends OneBotEventMap {
|
|
|
32
32
|
"ws.error": Event;
|
|
33
33
|
/** 收到 WebSocket 消息 */
|
|
34
34
|
"ws.message": any;
|
|
35
|
+
/** NapCat 连接已建立 */
|
|
36
|
+
"napcat.connected": {
|
|
37
|
+
uin: number;
|
|
38
|
+
ts: number;
|
|
39
|
+
};
|
|
35
40
|
}
|
|
36
41
|
/**
|
|
37
42
|
* 媒体消息的通用属性
|
|
@@ -285,9 +290,7 @@ interface SendNodeContentElement {
|
|
|
285
290
|
/** 发送者昵称(可选) */
|
|
286
291
|
nickname?: string;
|
|
287
292
|
/** 自定义消息内容 */
|
|
288
|
-
content:
|
|
289
|
-
type: "node";
|
|
290
|
-
}>[];
|
|
293
|
+
content: SendElement[];
|
|
291
294
|
}
|
|
292
295
|
/** 发送的合并转发节点消息段 */
|
|
293
296
|
type SendNodeElement = SendNodeRefElement | SendNodeContentElement;
|
|
@@ -418,6 +421,8 @@ interface Group {
|
|
|
418
421
|
group_id: number;
|
|
419
422
|
/** 群名称 */
|
|
420
423
|
group_name: string;
|
|
424
|
+
/** NapCat 实例 */
|
|
425
|
+
napcat: NapCat;
|
|
421
426
|
/** 群签到 */
|
|
422
427
|
doSign: () => Promise<string>;
|
|
423
428
|
/** 获取群信息 */
|
|
@@ -458,6 +463,8 @@ interface Friend {
|
|
|
458
463
|
user_id: number;
|
|
459
464
|
/** 好友昵称 */
|
|
460
465
|
nickname: string;
|
|
466
|
+
/** NapCat 实例 */
|
|
467
|
+
napcat: NapCat;
|
|
461
468
|
/** 发送私聊消息 */
|
|
462
469
|
sendMsg: SendMsg;
|
|
463
470
|
/** 删除好友 */
|
|
@@ -556,6 +563,8 @@ type FriendWithInfo = Friend & Awaited<ReturnType<Friend["getInfo"]>>;
|
|
|
556
563
|
type MessageEventBase<T extends MessageType, U$1 extends object> = EventBase<"message", U$1 & {
|
|
557
564
|
/** 消息 ID */
|
|
558
565
|
message_id: number;
|
|
566
|
+
/** 引用的消息 ID */
|
|
567
|
+
quote_id: string | null;
|
|
559
568
|
/** 消息类型 */
|
|
560
569
|
message_type: T;
|
|
561
570
|
/** 消息序号 */
|
|
@@ -584,6 +593,8 @@ type PrivateMessageEvent = MessageEventBase<"private", {
|
|
|
584
593
|
target_id: number;
|
|
585
594
|
/** 好友信息对象 */
|
|
586
595
|
friend: Friend;
|
|
596
|
+
/** 获取引用的消息 */
|
|
597
|
+
getQuoteMessage: () => Promise<PrivateMessageEvent | null>;
|
|
587
598
|
/** 发送者信息 */
|
|
588
599
|
sender: {
|
|
589
600
|
/** 发送者 QQ 号 */
|
|
@@ -611,6 +622,12 @@ type GroupMessageEvent = MessageEventBase<"group", {
|
|
|
611
622
|
addReaction: ReactionAction;
|
|
612
623
|
/** 删除消息表态的方法 */
|
|
613
624
|
delReaction: ReactionAction;
|
|
625
|
+
/** 获取引用的消息 */
|
|
626
|
+
getQuoteMessage: () => Promise<GroupMessageEvent | null>;
|
|
627
|
+
/** 添加精华消息的方法 */
|
|
628
|
+
addEssence: () => Promise<void>;
|
|
629
|
+
/** 删除精华消息的方法 */
|
|
630
|
+
delEssence: () => Promise<void>;
|
|
614
631
|
/** 群信息对象 */
|
|
615
632
|
group: Group;
|
|
616
633
|
/** 发送者信息 */
|
|
@@ -964,6 +981,8 @@ declare const segment: {
|
|
|
964
981
|
/** 创建一个自定义音乐消息片段 */
|
|
965
982
|
musicCustom: (title: string, audio: string, url: string, options?: Omit<ExtractByType<SendElement, "music">, "type" | "platform" | "url" | "audio" | "title">) => SendElement;
|
|
966
983
|
/** 创建一个合并转发消息片段 */
|
|
984
|
+
node: (options: Partial<ExtractByType<SendElement, "node">>) => SendElement;
|
|
985
|
+
/** 创建一个合并转发消息片段 */
|
|
967
986
|
forward: (id: string) => SendElement;
|
|
968
987
|
/** 创建一个 JSON 消息片段 */
|
|
969
988
|
json: (data: string) => SendElement;
|
|
@@ -988,10 +1007,22 @@ declare class NapCat {
|
|
|
988
1007
|
get logger(): Logger;
|
|
989
1008
|
/** 消息段构建器 */
|
|
990
1009
|
get segment(): typeof segment;
|
|
1010
|
+
/**
|
|
1011
|
+
* 机器人 QQ 号
|
|
1012
|
+
*/
|
|
1013
|
+
get user_id(): number;
|
|
1014
|
+
/**
|
|
1015
|
+
* 机器人 QQ 号
|
|
1016
|
+
*/
|
|
1017
|
+
get uin(): number;
|
|
1018
|
+
/**
|
|
1019
|
+
* 机器人昵称
|
|
1020
|
+
*/
|
|
1021
|
+
get nickname(): string;
|
|
991
1022
|
/** 获取一个群的信息,可以用于发送群消息等操作 */
|
|
992
|
-
pickGroup(group_id: number): Promise<GroupWithInfo>;
|
|
1023
|
+
pickGroup(group_id: number): Promise<GroupWithInfo | null>;
|
|
993
1024
|
/** 获取一个好友的信息,可以用于发送私聊消息等操作 */
|
|
994
|
-
pickFriend(user_id: number): Promise<FriendWithInfo>;
|
|
1025
|
+
pickFriend(user_id: number): Promise<FriendWithInfo | null>;
|
|
995
1026
|
/**
|
|
996
1027
|
* 注册一次性事件监听器
|
|
997
1028
|
*/
|
|
@@ -1008,6 +1039,9 @@ declare class NapCat {
|
|
|
1008
1039
|
* 移除事件监听器
|
|
1009
1040
|
*/
|
|
1010
1041
|
off<T extends keyof EventMap>(type: T, handler: (event: EventMap[NoInfer<T>]) => void): void;
|
|
1042
|
+
/**
|
|
1043
|
+
* 调用 NapCat API
|
|
1044
|
+
*/
|
|
1011
1045
|
api<T extends any>(action: API | (string & {}), params?: Record<string, any>): Promise<T>;
|
|
1012
1046
|
/**
|
|
1013
1047
|
* 发送私聊消息
|
|
@@ -1021,6 +1055,56 @@ declare class NapCat {
|
|
|
1021
1055
|
sendGroupMsg(group_id: number, sendable: Sendable | Sendable[]): Promise<{
|
|
1022
1056
|
message_id: number;
|
|
1023
1057
|
}>;
|
|
1058
|
+
/**
|
|
1059
|
+
* 机器人是否在线
|
|
1060
|
+
*/
|
|
1061
|
+
isOnline(): boolean;
|
|
1062
|
+
/**
|
|
1063
|
+
* 计算 GTK 值
|
|
1064
|
+
*/
|
|
1065
|
+
getGTk(pskey: string): number;
|
|
1066
|
+
/**
|
|
1067
|
+
* 获取 NapCat 原始 Cookie 相关信息
|
|
1068
|
+
*/
|
|
1069
|
+
getNapCatCookies(domain: string): Promise<{
|
|
1070
|
+
cookies: string;
|
|
1071
|
+
bkn: string;
|
|
1072
|
+
}>;
|
|
1073
|
+
/**
|
|
1074
|
+
* 获取版本信息
|
|
1075
|
+
*/
|
|
1076
|
+
getVersionInfo(): Promise<{
|
|
1077
|
+
app_name: string;
|
|
1078
|
+
protocol_version: string;
|
|
1079
|
+
app_version: string;
|
|
1080
|
+
}>;
|
|
1081
|
+
/**
|
|
1082
|
+
* 获取登录信息
|
|
1083
|
+
*/
|
|
1084
|
+
getLoginInfo(): Promise<{
|
|
1085
|
+
user_id: number;
|
|
1086
|
+
nickname: string;
|
|
1087
|
+
}>;
|
|
1088
|
+
/**
|
|
1089
|
+
* 获取 Cookie 相关信息
|
|
1090
|
+
*/
|
|
1091
|
+
getCookie(domain: string): Promise<{
|
|
1092
|
+
uin: number;
|
|
1093
|
+
pskey: string;
|
|
1094
|
+
skey: string;
|
|
1095
|
+
gtk: string;
|
|
1096
|
+
bkn: string;
|
|
1097
|
+
cookie: string;
|
|
1098
|
+
legacyCookie: string;
|
|
1099
|
+
}>;
|
|
1100
|
+
/**
|
|
1101
|
+
* 通过域名获取 Pskey
|
|
1102
|
+
*/
|
|
1103
|
+
getPskey(domain: string): Promise<string>;
|
|
1104
|
+
/**
|
|
1105
|
+
* 获取 Bkn 值
|
|
1106
|
+
*/
|
|
1107
|
+
getBkn(): Promise<string>;
|
|
1024
1108
|
/** 启动 NapCat SDK 实例,建立 WebSocket 连接 */
|
|
1025
1109
|
run(): Promise<void>;
|
|
1026
1110
|
/** 销毁 NapCat SDK 实例,关闭 WebSocket 连接 */
|
package/dist/index.mjs
CHANGED
|
@@ -23,7 +23,7 @@ const CONSOLE_LOGGER = {
|
|
|
23
23
|
//#endregion
|
|
24
24
|
//#region package.json
|
|
25
25
|
var name$1 = "napcat-sdk";
|
|
26
|
-
var version$1 = "0.1
|
|
26
|
+
var version$1 = "0.2.1";
|
|
27
27
|
|
|
28
28
|
//#endregion
|
|
29
29
|
//#region src/segment.ts
|
|
@@ -71,6 +71,7 @@ const segment = {
|
|
|
71
71
|
title,
|
|
72
72
|
...options
|
|
73
73
|
}),
|
|
74
|
+
node: (options) => createSegment("node", { ...options }),
|
|
74
75
|
forward: (id) => createSegment("forward", { id }),
|
|
75
76
|
json: (data) => createSegment("json", { data }),
|
|
76
77
|
file: (file, options) => createSegment("file", {
|
|
@@ -98,6 +99,14 @@ var NapCat = class {
|
|
|
98
99
|
#event = mitt();
|
|
99
100
|
/** Echo 事件发射器 */
|
|
100
101
|
#echoEvent = mitt();
|
|
102
|
+
/** 机器人 ID */
|
|
103
|
+
#uin = 0;
|
|
104
|
+
/** 机器人昵称 */
|
|
105
|
+
#nickname = "-";
|
|
106
|
+
/** 机器人状态 */
|
|
107
|
+
#online = false;
|
|
108
|
+
/** Cookies 缓存 */
|
|
109
|
+
#cookieCache = /* @__PURE__ */ new Map();
|
|
101
110
|
constructor(options) {
|
|
102
111
|
this.options = options;
|
|
103
112
|
}
|
|
@@ -127,6 +136,24 @@ var NapCat = class {
|
|
|
127
136
|
get segment() {
|
|
128
137
|
return segment;
|
|
129
138
|
}
|
|
139
|
+
/**
|
|
140
|
+
* 机器人 QQ 号
|
|
141
|
+
*/
|
|
142
|
+
get user_id() {
|
|
143
|
+
return this.uin;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* 机器人 QQ 号
|
|
147
|
+
*/
|
|
148
|
+
get uin() {
|
|
149
|
+
return this.#uin;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* 机器人昵称
|
|
153
|
+
*/
|
|
154
|
+
get nickname() {
|
|
155
|
+
return this.#nickname;
|
|
156
|
+
}
|
|
130
157
|
/** 生成唯一的 echo ID */
|
|
131
158
|
#echoId() {
|
|
132
159
|
return crypto.randomBytes(16).toString("hex");
|
|
@@ -189,6 +216,7 @@ var NapCat = class {
|
|
|
189
216
|
...extraInfo,
|
|
190
217
|
group_id,
|
|
191
218
|
group_name,
|
|
219
|
+
napcat: this,
|
|
192
220
|
doSign: () => this.api("set_group_sign", { group_id }),
|
|
193
221
|
getInfo: () => this.api("get_group_info", { group_id }),
|
|
194
222
|
getMemberList: async () => this.api("get_group_member_list", { group_id }),
|
|
@@ -222,6 +250,7 @@ var NapCat = class {
|
|
|
222
250
|
...extraInfo,
|
|
223
251
|
user_id,
|
|
224
252
|
nickname,
|
|
253
|
+
napcat: this,
|
|
225
254
|
delete: (block, both) => this.api("delete_friend", {
|
|
226
255
|
user_id,
|
|
227
256
|
temp_block: block,
|
|
@@ -231,24 +260,37 @@ var NapCat = class {
|
|
|
231
260
|
getInfo: () => this.api("get_stranger_info", { user_id })
|
|
232
261
|
};
|
|
233
262
|
}
|
|
234
|
-
/**
|
|
263
|
+
/** 构建私聊消息事件 */
|
|
235
264
|
#buildPrivateMessageEvent(event) {
|
|
265
|
+
const quote_id = event.message.find((el) => el.type === "reply")?.data?.id || null;
|
|
236
266
|
return {
|
|
237
267
|
...event,
|
|
238
|
-
|
|
268
|
+
quote_id,
|
|
269
|
+
getQuoteMessage: async () => {
|
|
270
|
+
if (!quote_id) return null;
|
|
271
|
+
const event$1 = await this.api("get_msg", { message_id: quote_id });
|
|
272
|
+
return this.#buildPrivateMessageEvent(event$1);
|
|
273
|
+
},
|
|
274
|
+
message: (event.message || []).filter((e) => e.type !== "reply").map((el) => ({
|
|
239
275
|
type: el.type,
|
|
240
276
|
...el.data
|
|
241
277
|
})),
|
|
242
278
|
friend: this.#buildFriend(event.user_id, event.sender?.nickname || ""),
|
|
243
|
-
recall: () => this.api("delete_msg", { message_id: event.message_id }),
|
|
244
279
|
reply: (sendable, reply = false) => this.sendPrivateMsg(event.user_id, this.#wrapReply(sendable, event.message_id, reply))
|
|
245
280
|
};
|
|
246
281
|
}
|
|
247
282
|
/** 构建群消息事件对象 */
|
|
248
283
|
#buildGroupMessageEvent(event) {
|
|
284
|
+
const quote_id = event.message.find((el) => el.type === "reply")?.data?.id || null;
|
|
249
285
|
return {
|
|
250
286
|
...event,
|
|
251
|
-
|
|
287
|
+
quote_id,
|
|
288
|
+
getQuoteMessage: async () => {
|
|
289
|
+
if (!quote_id) return null;
|
|
290
|
+
const event$1 = await this.api("get_msg", { message_id: quote_id });
|
|
291
|
+
return this.#buildGroupMessageEvent(event$1);
|
|
292
|
+
},
|
|
293
|
+
message: (event.message || []).filter((e) => e.type !== "reply").map((el) => ({
|
|
252
294
|
type: el.type,
|
|
253
295
|
...el.data
|
|
254
296
|
})),
|
|
@@ -282,7 +324,20 @@ var NapCat = class {
|
|
|
282
324
|
this.#event.emit("meta_event", data);
|
|
283
325
|
if (data.meta_event_type) {
|
|
284
326
|
this.#event.emit(`meta_event.${data.meta_event_type}`, data);
|
|
285
|
-
if (data.sub_type)
|
|
327
|
+
if (data.sub_type) {
|
|
328
|
+
if (data.sub_type === "connect") {
|
|
329
|
+
this.#uin = data.self_id;
|
|
330
|
+
this.#online = true;
|
|
331
|
+
this.#event.emit("napcat.connected", {
|
|
332
|
+
uin: this.#uin,
|
|
333
|
+
ts: data.time * 1e3
|
|
334
|
+
});
|
|
335
|
+
this.getLoginInfo().then((info) => {
|
|
336
|
+
this.#nickname = info.nickname;
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
this.#event.emit(`meta_event.${data.meta_event_type}.${data.sub_type}`, data);
|
|
340
|
+
}
|
|
286
341
|
}
|
|
287
342
|
break;
|
|
288
343
|
case "message":
|
|
@@ -378,13 +433,23 @@ var NapCat = class {
|
|
|
378
433
|
}
|
|
379
434
|
/** 获取一个群的信息,可以用于发送群消息等操作 */
|
|
380
435
|
async pickGroup(group_id) {
|
|
381
|
-
|
|
382
|
-
|
|
436
|
+
try {
|
|
437
|
+
const groupInfo = await this.api("get_group_info", { group_id });
|
|
438
|
+
return this.#buildGroup(group_id, groupInfo.group_name, groupInfo);
|
|
439
|
+
} catch (err) {
|
|
440
|
+
this.logger.warn(`Error to pickGroup ${group_id}: ${err?.message || err}`);
|
|
441
|
+
return null;
|
|
442
|
+
}
|
|
383
443
|
}
|
|
384
444
|
/** 获取一个好友的信息,可以用于发送私聊消息等操作 */
|
|
385
445
|
async pickFriend(user_id) {
|
|
386
|
-
|
|
387
|
-
|
|
446
|
+
try {
|
|
447
|
+
const friendInfo = await this.api("get_stranger_info", { user_id });
|
|
448
|
+
return this.#buildFriend(user_id, friendInfo.nickname, friendInfo);
|
|
449
|
+
} catch (err) {
|
|
450
|
+
this.logger.warn(`Error to pickFriend ${user_id}: ${err?.message || err}`);
|
|
451
|
+
return null;
|
|
452
|
+
}
|
|
388
453
|
}
|
|
389
454
|
/**
|
|
390
455
|
* 注册一次性事件监听器
|
|
@@ -415,6 +480,9 @@ var NapCat = class {
|
|
|
415
480
|
this.logger.debug(`unregistering: ${String(type)}`);
|
|
416
481
|
this.#event.off(type, handler);
|
|
417
482
|
}
|
|
483
|
+
/**
|
|
484
|
+
* 调用 NapCat API
|
|
485
|
+
*/
|
|
418
486
|
api(action, params = {}) {
|
|
419
487
|
this.#ensureWsConnection(this.#ws);
|
|
420
488
|
this.logger.debug(`calling api action: ${action} with params: ${JSON.stringify(params)}`);
|
|
@@ -444,10 +512,81 @@ var NapCat = class {
|
|
|
444
512
|
message: this.#normalizeSendable(sendable)
|
|
445
513
|
});
|
|
446
514
|
}
|
|
515
|
+
/**
|
|
516
|
+
* 机器人是否在线
|
|
517
|
+
*/
|
|
518
|
+
isOnline() {
|
|
519
|
+
return this.#ws?.readyState === WebSocket.OPEN && this.#online;
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* 计算 GTK 值
|
|
523
|
+
*/
|
|
524
|
+
getGTk(pskey) {
|
|
525
|
+
let gkt = 5381;
|
|
526
|
+
for (let i = 0, len = pskey.length; i < len; ++i) gkt += (gkt << 5) + pskey.charCodeAt(i);
|
|
527
|
+
return gkt & 2147483647;
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* 获取 NapCat 原始 Cookie 相关信息
|
|
531
|
+
*/
|
|
532
|
+
getNapCatCookies(domain) {
|
|
533
|
+
return this.api("get_cookies", { domain });
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* 获取版本信息
|
|
537
|
+
*/
|
|
538
|
+
getVersionInfo() {
|
|
539
|
+
return this.api("get_version_info");
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* 获取登录信息
|
|
543
|
+
*/
|
|
544
|
+
getLoginInfo() {
|
|
545
|
+
return this.api("get_login_info");
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* 获取 Cookie 相关信息
|
|
549
|
+
*/
|
|
550
|
+
async getCookie(domain) {
|
|
551
|
+
const cache = this.#cookieCache.get(domain);
|
|
552
|
+
if (cache) return cache;
|
|
553
|
+
const { cookies: cookieString, bkn } = await this.getNapCatCookies(domain);
|
|
554
|
+
const skey = cookieString.match(/skey=([^;]*)/)?.[1] || "";
|
|
555
|
+
const pskey = cookieString.match(/pskey=([^;]*)/)?.[1] || "";
|
|
556
|
+
const gtk = this.getGTk(pskey);
|
|
557
|
+
const returns = {
|
|
558
|
+
pskey,
|
|
559
|
+
skey,
|
|
560
|
+
uin: this.uin,
|
|
561
|
+
gtk: String(gtk),
|
|
562
|
+
bkn,
|
|
563
|
+
cookie: `uin=${this.uin}; skey=${skey}; p_uin=${this.uin}; p_skey=${pskey};`,
|
|
564
|
+
legacyCookie: `uin=o${this.uin}; skey=${skey}; p_uin=o${this.uin}; p_skey=${pskey};`
|
|
565
|
+
};
|
|
566
|
+
this.#cookieCache.set(domain, returns);
|
|
567
|
+
setTimeout(() => {
|
|
568
|
+
this.#cookieCache.delete(domain);
|
|
569
|
+
}, 1e3 * 60 * 60);
|
|
570
|
+
return returns;
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* 通过域名获取 Pskey
|
|
574
|
+
*/
|
|
575
|
+
async getPskey(domain) {
|
|
576
|
+
const { pskey } = await this.getCookie(domain);
|
|
577
|
+
return pskey;
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* 获取 Bkn 值
|
|
581
|
+
*/
|
|
582
|
+
async getBkn() {
|
|
583
|
+
const { bkn } = await this.getCookie("vip.qq.com");
|
|
584
|
+
return bkn;
|
|
585
|
+
}
|
|
447
586
|
/** 启动 NapCat SDK 实例,建立 WebSocket 连接 */
|
|
448
587
|
async run() {
|
|
449
|
-
const { logger: _, ...config } = this.#config;
|
|
450
|
-
this.logger.info(`
|
|
588
|
+
const { logger: _, token: __, ...config } = this.#config;
|
|
589
|
+
this.logger.info(`run with config: ${JSON.stringify(config)}`);
|
|
451
590
|
return new Promise((resolve, reject) => {
|
|
452
591
|
const ws = new WebSocket(this.#buildWsUrl());
|
|
453
592
|
ws.onmessage = (event) => {
|
|
@@ -466,16 +605,18 @@ var NapCat = class {
|
|
|
466
605
|
this.#bindInternalEvents(data);
|
|
467
606
|
};
|
|
468
607
|
ws.onclose = () => {
|
|
608
|
+
this.#online = false;
|
|
469
609
|
this.logger.info("closed");
|
|
470
610
|
this.#event.emit("ws.close");
|
|
471
611
|
};
|
|
472
612
|
ws.onerror = (error) => {
|
|
613
|
+
this.#online = false;
|
|
473
614
|
this.logger.error(`error: ${error}`);
|
|
474
615
|
this.#event.emit("ws.error", error);
|
|
475
616
|
reject(error);
|
|
476
617
|
};
|
|
477
618
|
ws.onopen = () => {
|
|
478
|
-
this.logger.info("connected");
|
|
619
|
+
this.logger.info("NapCat connected");
|
|
479
620
|
this.#event.emit("ws.open");
|
|
480
621
|
resolve();
|
|
481
622
|
};
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["ABSTRACT_LOGGER: Logger","CONSOLE_LOGGER: Logger","name: string","pkg.name","version: string","pkg.version","DEFAULT_NAPCAT_OPTIONS: Required<OptionalProps<MiokiOptions>>","options: MiokiOptions","#config","#ws","#echoEvent","#buildFriend","#wrapReply","#buildGroup","#event","#buildPrivateMessageEvent","#buildGroupMessageEvent","#ensureWsConnection","#echoId","#waitForAction","#normalizeSendable","#buildWsUrl","#bindInternalEvents","NAPCAT_NOTICE_NOTIFY_MAP: Record<string, { notice_type: string; sub_type: string }>","NAPCAT_NOTICE_EVENT_MAP: Record<string, { notice_type: string; sub_type: string }>"],"sources":["../src/logger.ts","../package.json","../src/segment.ts","../src/napcat.ts"],"sourcesContent":["export type LogLevel = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace'\n\nexport type Logger = Record<LogLevel, (...args: unknown[]) => void>\n\nexport const noop = (): void => {}\n\nexport const ABSTRACT_LOGGER: Logger = {\n fatal: noop,\n error: noop,\n warn: noop,\n info: noop,\n debug: noop,\n trace: noop,\n}\n\nexport const CONSOLE_LOGGER: Logger = {\n fatal: console.error.bind(console, '[FATAL]'),\n error: console.error.bind(console, '[ERROR]'),\n warn: console.warn.bind(console, '[WARN]'),\n info: console.info.bind(console, '[INFO]'),\n debug: console.debug.bind(console, '[DEBUG]'),\n trace: console.trace.bind(console, '[TRACE]'),\n}\n","{\n \"name\": \"napcat-sdk\",\n \"type\": \"module\",\n \"version\": \"0.1.2\",\n \"packageManager\": \"pnpm@10.26.0\",\n \"description\": \"A simple SDK for NapCat OneBot v11.\",\n \"keywords\": [\n \"napcat\",\n \"onebot\",\n \"onebot v11\",\n \"sdk\"\n ],\n \"homepage\": \"https://github.com/vikiboss/mioki#readme\",\n \"files\": [\n \"dist\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/vikiboss/mioki/issues\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/vikiboss/mioki.git\",\n \"directory\": \"packages/napcat-sdk\"\n },\n \"scripts\": {\n \"dev\": \"tsdown -w\",\n \"build\": \"tsdown\"\n },\n \"exports\": {\n \".\": {\n \"require\": \"./dist/index.cjs\",\n \"import\": \"./dist/index.mjs\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"author\": \"Viki <hi@viki.moe> (https://github.com/vikiboss)\",\n \"license\": \"MIT\",\n \"devDependencies\": {\n \"@types/node\": \"catalog:dev\",\n \"tsdown\": \"catalog:dev\",\n \"typescript\": \"catalog:dev\"\n },\n \"dependencies\": {\n \"mitt\": \"^3.0.1\"\n }\n}\n","import type { ExtractByType, SendElement } from './types'\n\nfunction createSegment<T extends SendElement['type'], D>(type: T, data: D): SendElement {\n return { type, ...data } as SendElement\n}\n\n/**\n * 消息片段构造器\n */\nexport const segment = {\n /** 创建一个文本消息片段 */\n text: (text: string): SendElement => createSegment('text', { text }),\n /** 创建一个艾特消息片段 */\n at: (qq: 'all' | (string & {})): SendElement => createSegment('at', { qq }),\n /** 创建一个 QQ 表情消息片段 */\n face: (id: number): SendElement => createSegment('face', { id }),\n /** 创建一个回复消息片段 */\n reply: (id: string): SendElement => createSegment('reply', { id }),\n /** 创建一个图片消息片段 */\n image: (file: string, options?: Omit<ExtractByType<SendElement, 'image'>, 'type' | 'file'>): SendElement =>\n createSegment('image', { file, ...options }),\n /** 创建一个语音消息片段 */\n record: (file: string, options?: Omit<ExtractByType<SendElement, 'record'>, 'type' | 'file'>): SendElement =>\n createSegment('record', { file, ...options }),\n /** 创建一个视频消息片段 */\n video: (file: string, options?: Omit<ExtractByType<SendElement, 'video'>, 'type' | 'file'>): SendElement =>\n createSegment('video', { file, ...options }),\n /** 创建一个动态表情消息片段 */\n mface: (options: Omit<ExtractByType<SendElement, 'mface'>, 'type'>): SendElement =>\n createSegment('mface', { ...options }),\n /** 创建一个大表情消息片段 */\n bface: (id: number): SendElement => createSegment('bface', { id }),\n /** 创建一个 联系人/群 分享消息片段 */\n contact: (type: 'qq' | 'group', id: string): SendElement => createSegment('contact', { id, sub_type: type }),\n /** 创建一个戳一戳消息片段 */\n poke: (): SendElement => createSegment('poke', {}),\n /** 创建一个音乐消息片段 */\n music: (platform: 'qq' | '163' | 'kugou' | 'migu' | 'kuwo', id: string): SendElement =>\n createSegment('music', { platform, id }),\n /** 创建一个自定义音乐消息片段 */\n musicCustom: (\n title: string,\n audio: string,\n url: string,\n options?: Omit<ExtractByType<SendElement, 'music'>, 'type' | 'platform' | 'url' | 'audio' | 'title'>,\n ): SendElement => createSegment('music', { platform: 'custom', url, audio, title, ...options }),\n /** 创建一个合并转发消息片段 */\n forward: (id: string): SendElement => createSegment('forward', { id }),\n /** 创建一个 JSON 消息片段 */\n json: (data: string): SendElement => createSegment('json', { data }),\n /** 创建一个文件消息片段 */\n file: (file: string, options?: Omit<ExtractByType<SendElement, 'file'>, 'type' | 'file'>): SendElement =>\n createSegment('file', { file, ...options }),\n /** 创建一个 Markdown 消息片段 */\n markdown: (): SendElement => createSegment('markdown', {}),\n /** 创建一个轻应用消息片段 */\n lightapp: (): SendElement => createSegment('lightapp', {}),\n}\n","import crypto from 'node:crypto'\nimport mitt from 'mitt'\nimport pkg from '../package.json' with { type: 'json' }\nimport { segment } from './segment'\nimport { ABSTRACT_LOGGER } from './logger'\n\nimport type { Emitter } from 'mitt'\nimport type { Logger } from './logger'\nimport type {\n API,\n EventMap,\n Friend,\n FriendWithInfo,\n Group,\n GroupMessageEvent,\n GroupWithInfo,\n MiokiOptions,\n NormalizedElementToSend,\n OptionalProps,\n PrivateMessageEvent,\n Sendable,\n} from './types'\n\nexport const name: string = pkg.name\nexport const version: string = pkg.version\n\nconst DEFAULT_NAPCAT_OPTIONS: Required<OptionalProps<MiokiOptions>> = {\n protocol: 'ws',\n host: 'localhost',\n port: 3333,\n logger: ABSTRACT_LOGGER,\n}\n\nexport class NapCat {\n /** WebSocket 实例 */\n #ws: WebSocket | null = null\n /** 事件发射器 */\n #event: Emitter<EventMap & Record<string | symbol, unknown>> = mitt()\n /** Echo 事件发射器 */\n #echoEvent: Emitter<Record<string, unknown>> = mitt()\n\n constructor(private readonly options: MiokiOptions) {}\n\n /** 配置项 */\n get #config(): Required<MiokiOptions> {\n return {\n protocol: this.options.protocol || DEFAULT_NAPCAT_OPTIONS.protocol,\n host: this.options.host || DEFAULT_NAPCAT_OPTIONS.host,\n port: this.options.port || DEFAULT_NAPCAT_OPTIONS.port,\n logger: this.options.logger || DEFAULT_NAPCAT_OPTIONS.logger,\n token: this.options.token,\n }\n }\n\n /** WebSocket 实例 */\n get ws(): WebSocket {\n if (!this.#ws) {\n this.logger.error('WebSocket is not connected.')\n throw new Error('WebSocket is not connected.')\n }\n\n return this.#ws\n }\n\n /** 日志记录器 */\n get logger(): Logger {\n return this.#config.logger\n }\n\n /** 消息段构建器 */\n get segment(): typeof segment {\n return segment\n }\n\n /** 生成唯一的 echo ID */\n #echoId() {\n return crypto.randomBytes(16).toString('hex')\n }\n\n /** 构建 WebSocket 连接地址 */\n #buildWsUrl(): string {\n return `${this.#config.protocol}://${this.#config.host}:${this.#config.port}?access_token=${this.#config.token}`\n }\n\n /** 包装回复消息 */\n #wrapReply(sendable: Sendable | Sendable[], message_id?: number, reply?: boolean): Sendable[] {\n const sendableList = typeof sendable === 'string' ? [sendable] : [sendable].flat()\n\n if (reply && message_id) {\n return [segment.reply(String(message_id)), ...sendableList]\n }\n\n return sendableList\n }\n\n /** 确保 WebSocket 已连接 */\n #ensureWsConnection(ws: WebSocket | null): asserts ws is WebSocket {\n if (!ws) {\n this.logger.error('WebSocket is not connected.')\n throw new Error('WebSocket is not connected.')\n }\n\n if (ws.readyState !== WebSocket.OPEN) {\n this.logger.error('WebSocket is not open.')\n throw new Error('WebSocket is not open.')\n }\n }\n\n /** 标准化可发送消息元素 */\n #normalizeSendable(msg: Sendable | Sendable[]): NormalizedElementToSend[] {\n return [msg].flat(2).map((item) => {\n if (typeof item === 'string') {\n return { type: 'text', data: { text: item } }\n }\n if (item.type === 'at') {\n return { type: 'at', data: { qq: String(item.qq) } }\n }\n const { type, ...data } = item\n return { type, data } as NormalizedElementToSend\n })\n }\n\n /** 等待服务器响应操作 */\n #waitForAction<T extends any>(echoId: string) {\n const eventName = `echo#${echoId}`\n\n return new Promise<T>((resolve, reject) => {\n const handle = (data: any) => {\n if (!data || data.echo !== echoId) return\n\n this.#echoEvent.off(eventName, handle)\n\n if (data.retcode === 0) {\n resolve(data.data as T)\n } else {\n reject(`Server Error: ${data.message}`)\n }\n }\n\n this.#echoEvent.on(eventName, handle)\n })\n }\n\n /** 构建群对象 */\n #buildGroup<T extends object>(group_id: number, group_name: string = '', extraInfo: T = {} as T): Group & T {\n return {\n ...extraInfo,\n group_id,\n group_name,\n doSign: () => this.api('set_group_sign', { group_id }),\n getInfo: () => this.api('get_group_info', { group_id }),\n getMemberList: async () => this.api('get_group_member_list', { group_id }),\n getMemberInfo: (user_id: number) => this.api('get_group_member_info', { group_id, user_id }),\n setTitle: (title: string) => this.api('set_group_special_title', { group_id, title }),\n setCard: (user_id: number, card: string) => this.api('set_group_card', { group_id, user_id, card }),\n addEssence: (message_id: string) => this.api('set_essence_msg', { message_id }),\n delEssence: (message_id: string) => this.api('delete_essence_msg', { message_id }),\n recall: (message_id: number) => this.api('delete_msg', { message_id }),\n banMember: (user_id: number, duration: number) => this.api('set_group_ban', { group_id, user_id, duration }),\n sendMsg: (sendable: Sendable | Sendable[]) => this.sendGroupMsg(group_id, sendable),\n }\n }\n\n /** 构建好友对象 */\n #buildFriend<T extends object>(user_id: number, nickname: string = '', extraInfo: T = {} as T): Friend & T {\n return {\n ...extraInfo,\n user_id,\n nickname,\n delete: (block?: boolean, both?: boolean) =>\n this.api('delete_friend', { user_id, temp_block: block, temp_both_del: both }),\n sendMsg: (sendable: Sendable | Sendable[]) => this.sendPrivateMsg(user_id, sendable),\n getInfo: () => this.api('get_stranger_info', { user_id }),\n }\n }\n\n /** 构建群消息事件 */\n #buildPrivateMessageEvent(event: PrivateMessageEvent) {\n return {\n ...event,\n message: (event.message || []).map((el: any) => ({ type: el.type, ...el.data })),\n friend: this.#buildFriend(event.user_id, event.sender?.nickname || ''),\n recall: () => this.api('delete_msg', { message_id: event.message_id }),\n reply: (sendable: Sendable | Sendable[], reply = false) =>\n this.sendPrivateMsg(event.user_id, this.#wrapReply(sendable, event.message_id, reply)),\n }\n }\n\n /** 构建群消息事件对象 */\n #buildGroupMessageEvent(event: GroupMessageEvent) {\n return {\n ...event,\n message: (event.message || []).map((el: any) => ({ type: el.type, ...el.data })),\n group: this.#buildGroup(event.group_id, event.group?.group_name || ''),\n recall: () => this.api('delete_msg', { message_id: event.message_id }),\n addReaction: (id: string) =>\n this.api('set_msg_emoji_like', { message_id: event.message_id, emoji_id: id, set: true }),\n delReaction: (id: string) =>\n this.api('set_msg_emoji_like', { message_id: event.message_id, emoji_id: id, set: false }),\n addEssence: () => this.api('set_essence_msg', { message_id: event.message_id }),\n delEssence: () => this.api('delete_essence_msg', { message_id: event.message_id }),\n reply: (sendable: Sendable | Sendable[], reply = false) =>\n this.sendGroupMsg(event.group_id, this.#wrapReply(sendable, event.message_id, reply)),\n }\n }\n\n /** 绑定内部事件处理器 */\n #bindInternalEvents(data: any) {\n if (data.echo) {\n this.#echoEvent.emit(`echo#${data.echo}`, data)\n return\n }\n\n if (data.post_type) {\n switch (data.post_type) {\n case 'meta_event': {\n this.logger.trace(`received meta_event: ${JSON.stringify(data)}`)\n this.#event.emit('meta_event', data)\n\n if (data.meta_event_type) {\n this.#event.emit(`meta_event.${data.meta_event_type}`, data)\n if (data.sub_type) {\n this.#event.emit(`meta_event.${data.meta_event_type}.${data.sub_type}`, data)\n }\n }\n\n break\n }\n\n case 'message': {\n if (data.message_type === 'private') {\n data = this.#buildPrivateMessageEvent(data)\n } else {\n data = this.#buildGroupMessageEvent(data)\n }\n\n this.#event.emit('message', data)\n\n switch (data.message_type) {\n case 'private': {\n this.logger.trace(`received private message: ${JSON.stringify(data)}`)\n this.#event.emit('message.private', data)\n this.#event.emit(`message.private.${data.sub_type}`, data)\n\n break\n }\n\n case 'group': {\n this.logger.trace(`received group message: ${JSON.stringify(data)}`)\n this.#event.emit('message.group', data)\n this.#event.emit(`message.group.${data.sub_type}`, data)\n\n break\n }\n\n default: {\n this.logger.debug(`received unknown message type: ${JSON.stringify(data)}`)\n\n break\n }\n }\n\n break\n }\n\n case 'message_sent': {\n this.logger.trace(`received message_sent: ${JSON.stringify(data)}`)\n this.#event.emit('message_sent', data)\n\n if (data.message_type) {\n this.#event.emit(`message_sent.${data.message_type}`, data)\n if (data.sub_type) {\n this.#event.emit(`message_sent.${data.message_type}.${data.sub_type}`, data)\n }\n }\n\n break\n }\n\n case 'notice': {\n this.logger.trace(`received notice: ${JSON.stringify(data)}`)\n\n if (!data.notice_type) {\n this.logger.debug(`received unknown notice type: ${JSON.stringify(data)}`)\n break\n }\n\n const isNotify = data.notice_type === 'notify'\n const isPoke = data.sub_type === 'poke'\n const isGroup = !!data.group_id\n\n const { notice_type, sub_type } = isNotify\n ? isPoke\n ? { notice_type: isGroup ? 'group' : 'friend', sub_type: 'poke' }\n : NAPCAT_NOTICE_NOTIFY_MAP[data.sub_type] || {}\n : NAPCAT_NOTICE_EVENT_MAP[data.notice_type] || {}\n\n data.original_notice_type = data.notice_type\n data.notice_type = notice_type || data.notice_type\n\n if (data.sub_type && data.sub_type !== sub_type) {\n data.action_type = data.sub_type\n }\n\n data.sub_type = sub_type || data.sub_type\n\n if (isGroup) {\n data.group = this.#buildGroup(data.group_id, data.group_name || '')\n } else {\n data.friend = this.#buildFriend(data.user_id, data.nickname || '')\n }\n\n this.#event.emit('notice', data)\n\n if (notice_type) {\n this.#event.emit(`notice.${notice_type}`, data)\n if (sub_type) {\n this.#event.emit(`notice.${notice_type}.${sub_type}`, data)\n }\n }\n\n break\n }\n\n case 'request': {\n this.logger.trace(`received request: ${JSON.stringify(data)}`)\n\n if (data.request_type === 'friend') {\n data.reject = () => this.api('set_friend_request', { flag: data.flag, approve: false })\n data.approve = () => this.api('set_friend_request', { flag: data.flag, approve: true })\n }\n\n if (data.request_type === 'group') {\n data.reject = (reason?: string) =>\n this.api('set_group_add_request', { flag: data.flag, approve: false, reason })\n data.approve = () => this.api('set_group_add_request', { flag: data.flag, approve: true })\n }\n\n this.#event.emit('request', data)\n\n if (data.request_type) {\n this.#event.emit(`request.${data.request_type}`, data)\n if (data.sub_type) {\n this.#event.emit(`request.${data.request_type}.${data.sub_type}`, data)\n }\n }\n\n break\n }\n\n default: {\n this.logger.debug(`received: ${JSON.stringify(data)}`)\n this.#event.emit(data.post_type, data)\n return\n }\n }\n\n return\n }\n }\n\n /** 获取一个群的信息,可以用于发送群消息等操作 */\n async pickGroup(group_id: number): Promise<GroupWithInfo> {\n const groupInfo = await this.api<ReturnType<Group['getInfo']>>('get_group_info', { group_id })\n return this.#buildGroup(group_id, groupInfo.group_name, groupInfo)\n }\n\n /** 获取一个好友的信息,可以用于发送私聊消息等操作 */\n async pickFriend(user_id: number): Promise<FriendWithInfo> {\n const friendInfo = await this.api<ReturnType<Friend['getInfo']>>('get_stranger_info', { user_id })\n return this.#buildFriend(user_id, friendInfo.nickname, friendInfo)\n }\n\n /**\n * 注册一次性事件监听器\n */\n once<T extends keyof EventMap>(type: T, handler: (event: EventMap[NoInfer<T>]) => void): void {\n const onceHandler = (event: EventMap[NoInfer<T>]) => {\n handler(event)\n this.#event.off(type, onceHandler)\n }\n\n this.logger.debug(`registering once: ${String(type)}`)\n this.#event.on(type, onceHandler)\n }\n\n /**\n * 注册事件监听器,支持主类型或者点分子类型\n *\n * 如: `notice`、`message.private`、`request.group.invite` 等\n *\n * 如果需要移除监听器,请调用 `off` 方法\n */\n on<T extends keyof EventMap>(type: T, handler: (event: EventMap[NoInfer<T>]) => void): void {\n this.logger.debug(`registering: ${String(type)}`)\n this.#event.on(type, handler)\n }\n\n /**\n * 移除事件监听器\n */\n off<T extends keyof EventMap>(type: T, handler: (event: EventMap[NoInfer<T>]) => void): void {\n this.logger.debug(`unregistering: ${String(type)}`)\n this.#event.off(type, handler)\n }\n\n api<T extends any>(action: API | (string & {}), params: Record<string, any> = {}): Promise<T> {\n this.#ensureWsConnection(this.#ws)\n this.logger.debug(`calling api action: ${action} with params: ${JSON.stringify(params)}`)\n const echo = this.#echoId()\n this.#ws.send(JSON.stringify({ echo, action, params }))\n return this.#waitForAction<T>(echo)\n }\n\n /**\n * 发送私聊消息\n */\n sendPrivateMsg(user_id: number, sendable: Sendable | Sendable[]): Promise<{ message_id: number }> {\n return this.api<{ message_id: number }>('send_private_msg', {\n user_id,\n message: this.#normalizeSendable(sendable),\n })\n }\n\n /**\n * 发送群消息\n */\n sendGroupMsg(group_id: number, sendable: Sendable | Sendable[]): Promise<{ message_id: number }> {\n return this.api<{ message_id: number }>('send_group_msg', {\n group_id,\n message: this.#normalizeSendable(sendable),\n })\n }\n\n /** 启动 NapCat SDK 实例,建立 WebSocket 连接 */\n async run(): Promise<void> {\n const { logger: _, ...config } = this.#config\n\n this.logger.info(`bootstrap with config: ${JSON.stringify(config)}`)\n\n return new Promise<void>((resolve, reject) => {\n const ws = new WebSocket(this.#buildWsUrl())\n\n ws.onmessage = (event) => {\n const data = (() => {\n try {\n return JSON.parse(event.data)\n } catch {\n return null\n }\n })() as any\n\n if (!data) {\n this.logger.warn(`received non-json message: ${event.data}`)\n return\n }\n\n this.#event.emit('ws.message', data)\n this.#bindInternalEvents(data)\n }\n\n ws.onclose = () => {\n this.logger.info('closed')\n this.#event.emit('ws.close')\n }\n\n ws.onerror = (error) => {\n this.logger.error(`error: ${error}`)\n this.#event.emit('ws.error', error)\n reject(error)\n }\n\n ws.onopen = () => {\n this.logger.info('connected')\n this.#event.emit('ws.open')\n resolve()\n }\n\n this.#ws = ws\n\n this.logger.trace(`WebSocket instance created: ${this.#ws}`)\n })\n }\n\n /** 销毁 NapCat SDK 实例,关闭 WebSocket 连接 */\n close(): void {\n if (this.#ws) {\n this.logger.info('destroying NapCat SDK instance...')\n this.#ws.close()\n this.#ws = null\n this.logger.info('NapCat SDK instance destroyed.')\n } else {\n this.logger.warn('NapCat SDK instance is not initialized.')\n }\n }\n}\n\n// ==================== 通知事件映射 ====================\n\n/**\n * NapCat 通知类型映射表(notify 类型)\n * @description 将 NapCat 特有的通知类型映射到标准的 notice_type 和 sub_type\n */\nconst NAPCAT_NOTICE_NOTIFY_MAP: Record<string, { notice_type: string; sub_type: string }> = {\n input_status: {\n notice_type: 'friend',\n sub_type: 'input',\n },\n profile_like: {\n notice_type: 'friend',\n sub_type: 'like',\n },\n title: {\n notice_type: 'group',\n sub_type: 'title',\n },\n}\n\n/**\n * NapCat 通知事件映射表(notice 类型)\n * @description 将 NapCat 的原始通知事件类型映射到标准的 notice_type 和 sub_type\n */\nconst NAPCAT_NOTICE_EVENT_MAP: Record<string, { notice_type: string; sub_type: string }> = {\n friend_add: {\n notice_type: 'friend',\n sub_type: 'increase',\n },\n friend_recall: {\n notice_type: 'friend',\n sub_type: 'recall',\n },\n offline_file: {\n notice_type: 'friend',\n sub_type: 'offline_file',\n },\n client_status: {\n notice_type: 'client',\n sub_type: 'status',\n },\n group_admin: {\n notice_type: 'group',\n sub_type: 'admin',\n },\n group_ban: {\n notice_type: 'group',\n sub_type: 'ban',\n },\n group_card: {\n notice_type: 'group',\n sub_type: 'card',\n },\n group_upload: {\n notice_type: 'group',\n sub_type: 'upload',\n },\n group_decrease: {\n notice_type: 'group',\n sub_type: 'decrease',\n },\n group_increase: {\n notice_type: 'group',\n sub_type: 'increase',\n },\n group_msg_emoji_like: {\n notice_type: 'group',\n sub_type: 'reaction',\n },\n essence: {\n notice_type: 'group',\n sub_type: 'essence',\n },\n group_recall: {\n notice_type: 'group',\n sub_type: 'recall',\n },\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["ABSTRACT_LOGGER: Logger","CONSOLE_LOGGER: Logger","name: string","pkg.name","version: string","pkg.version","DEFAULT_NAPCAT_OPTIONS: Required<OptionalProps<MiokiOptions>>","options: MiokiOptions","#config","#ws","#uin","#nickname","#echoEvent","quote_id: string | null","event","#buildPrivateMessageEvent","#buildFriend","#wrapReply","#buildGroupMessageEvent","#buildGroup","#event","#online","err: any","#ensureWsConnection","#echoId","#waitForAction","#normalizeSendable","#cookieCache","#buildWsUrl","#bindInternalEvents","NAPCAT_NOTICE_NOTIFY_MAP: Record<string, { notice_type: string; sub_type: string }>","NAPCAT_NOTICE_EVENT_MAP: Record<string, { notice_type: string; sub_type: string }>"],"sources":["../src/logger.ts","../package.json","../src/segment.ts","../src/napcat.ts"],"sourcesContent":["export type LogLevel = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace'\n\nexport type Logger = Record<LogLevel, (...args: unknown[]) => void>\n\nexport const noop = (): void => {}\n\nexport const ABSTRACT_LOGGER: Logger = {\n fatal: noop,\n error: noop,\n warn: noop,\n info: noop,\n debug: noop,\n trace: noop,\n}\n\nexport const CONSOLE_LOGGER: Logger = {\n fatal: console.error.bind(console, '[FATAL]'),\n error: console.error.bind(console, '[ERROR]'),\n warn: console.warn.bind(console, '[WARN]'),\n info: console.info.bind(console, '[INFO]'),\n debug: console.debug.bind(console, '[DEBUG]'),\n trace: console.trace.bind(console, '[TRACE]'),\n}\n","{\n \"name\": \"napcat-sdk\",\n \"type\": \"module\",\n \"version\": \"0.2.1\",\n \"packageManager\": \"pnpm@10.26.0\",\n \"description\": \"A simple SDK for NapCat OneBot v11.\",\n \"keywords\": [\n \"napcat\",\n \"onebot\",\n \"onebot v11\",\n \"sdk\"\n ],\n \"homepage\": \"https://github.com/vikiboss/mioki#readme\",\n \"files\": [\n \"dist\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/vikiboss/mioki/issues\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/vikiboss/mioki.git\",\n \"directory\": \"packages/napcat-sdk\"\n },\n \"scripts\": {\n \"dev\": \"tsdown -w\",\n \"build\": \"tsdown\"\n },\n \"exports\": {\n \".\": {\n \"require\": \"./dist/index.cjs\",\n \"import\": \"./dist/index.mjs\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"author\": \"Viki <hi@viki.moe> (https://github.com/vikiboss)\",\n \"license\": \"MIT\",\n \"devDependencies\": {\n \"@types/node\": \"catalog:dev\",\n \"tsdown\": \"catalog:dev\",\n \"typescript\": \"catalog:dev\"\n },\n \"dependencies\": {\n \"mitt\": \"^3.0.1\"\n }\n}\n","import type { ExtractByType, SendElement } from './types'\n\nfunction createSegment<T extends SendElement['type'], D>(type: T, data: D): SendElement {\n return { type, ...data } as SendElement\n}\n\n/**\n * 消息片段构造器\n */\nexport const segment = {\n /** 创建一个文本消息片段 */\n text: (text: string): SendElement => createSegment('text', { text }),\n /** 创建一个艾特消息片段 */\n at: (qq: 'all' | (string & {})): SendElement => createSegment('at', { qq }),\n /** 创建一个 QQ 表情消息片段 */\n face: (id: number): SendElement => createSegment('face', { id }),\n /** 创建一个回复消息片段 */\n reply: (id: string): SendElement => createSegment('reply', { id }),\n /** 创建一个图片消息片段 */\n image: (file: string, options?: Omit<ExtractByType<SendElement, 'image'>, 'type' | 'file'>): SendElement =>\n createSegment('image', { file, ...options }),\n /** 创建一个语音消息片段 */\n record: (file: string, options?: Omit<ExtractByType<SendElement, 'record'>, 'type' | 'file'>): SendElement =>\n createSegment('record', { file, ...options }),\n /** 创建一个视频消息片段 */\n video: (file: string, options?: Omit<ExtractByType<SendElement, 'video'>, 'type' | 'file'>): SendElement =>\n createSegment('video', { file, ...options }),\n /** 创建一个动态表情消息片段 */\n mface: (options: Omit<ExtractByType<SendElement, 'mface'>, 'type'>): SendElement =>\n createSegment('mface', { ...options }),\n /** 创建一个大表情消息片段 */\n bface: (id: number): SendElement => createSegment('bface', { id }),\n /** 创建一个 联系人/群 分享消息片段 */\n contact: (type: 'qq' | 'group', id: string): SendElement => createSegment('contact', { id, sub_type: type }),\n /** 创建一个戳一戳消息片段 */\n poke: (): SendElement => createSegment('poke', {}),\n /** 创建一个音乐消息片段 */\n music: (platform: 'qq' | '163' | 'kugou' | 'migu' | 'kuwo', id: string): SendElement =>\n createSegment('music', { platform, id }),\n /** 创建一个自定义音乐消息片段 */\n musicCustom: (\n title: string,\n audio: string,\n url: string,\n options?: Omit<ExtractByType<SendElement, 'music'>, 'type' | 'platform' | 'url' | 'audio' | 'title'>,\n ): SendElement => createSegment('music', { platform: 'custom', url, audio, title, ...options }),\n /** 创建一个合并转发消息片段 */\n node: (options: Partial<ExtractByType<SendElement, 'node'>>): SendElement => createSegment('node', { ...options }),\n /** 创建一个合并转发消息片段 */\n forward: (id: string): SendElement => createSegment('forward', { id }),\n /** 创建一个 JSON 消息片段 */\n json: (data: string): SendElement => createSegment('json', { data }),\n /** 创建一个文件消息片段 */\n file: (file: string, options?: Omit<ExtractByType<SendElement, 'file'>, 'type' | 'file'>): SendElement =>\n createSegment('file', { file, ...options }),\n /** 创建一个 Markdown 消息片段 */\n markdown: (): SendElement => createSegment('markdown', {}),\n /** 创建一个轻应用消息片段 */\n lightapp: (): SendElement => createSegment('lightapp', {}),\n}\n","import crypto from 'node:crypto'\nimport mitt from 'mitt'\nimport pkg from '../package.json' with { type: 'json' }\nimport { segment } from './segment'\nimport { ABSTRACT_LOGGER } from './logger'\n\nimport type { Emitter } from 'mitt'\nimport type { Logger } from './logger'\nimport type {\n API,\n EventMap,\n Friend,\n FriendWithInfo,\n Group,\n GroupMessageEvent,\n GroupWithInfo,\n MiokiOptions,\n NormalizedElementToSend,\n OptionalProps,\n PrivateMessageEvent,\n Sendable,\n} from './types'\n\nexport const name: string = pkg.name\nexport const version: string = pkg.version\n\nconst DEFAULT_NAPCAT_OPTIONS: Required<OptionalProps<MiokiOptions>> = {\n protocol: 'ws',\n host: 'localhost',\n port: 3333,\n logger: ABSTRACT_LOGGER,\n}\n\nexport class NapCat {\n /** WebSocket 实例 */\n #ws: WebSocket | null = null\n /** 事件发射器 */\n #event: Emitter<EventMap & Record<string | symbol, unknown>> = mitt()\n /** Echo 事件发射器 */\n #echoEvent: Emitter<Record<string, unknown>> = mitt()\n /** 机器人 ID */\n #uin: number = 0\n /** 机器人昵称 */\n #nickname: string = '-'\n /** 机器人状态 */\n #online: boolean = false\n /** Cookies 缓存 */\n #cookieCache = new Map<\n string,\n {\n uin: number\n pskey: string\n skey: string\n gtk: string\n bkn: string\n cookie: string\n legacyCookie: string\n }\n >()\n\n constructor(private readonly options: MiokiOptions) {}\n\n /** 配置项 */\n get #config(): Required<MiokiOptions> {\n return {\n protocol: this.options.protocol || DEFAULT_NAPCAT_OPTIONS.protocol,\n host: this.options.host || DEFAULT_NAPCAT_OPTIONS.host,\n port: this.options.port || DEFAULT_NAPCAT_OPTIONS.port,\n logger: this.options.logger || DEFAULT_NAPCAT_OPTIONS.logger,\n token: this.options.token,\n }\n }\n\n /** WebSocket 实例 */\n get ws(): WebSocket {\n if (!this.#ws) {\n this.logger.error('WebSocket is not connected.')\n throw new Error('WebSocket is not connected.')\n }\n\n return this.#ws\n }\n\n /** 日志记录器 */\n get logger(): Logger {\n return this.#config.logger\n }\n\n /** 消息段构建器 */\n get segment(): typeof segment {\n return segment\n }\n\n /**\n * 机器人 QQ 号\n */\n get user_id(): number {\n return this.uin\n }\n\n /**\n * 机器人 QQ 号\n */\n get uin(): number {\n return this.#uin\n }\n\n /**\n * 机器人昵称\n */\n get nickname(): string {\n return this.#nickname\n }\n\n /** 生成唯一的 echo ID */\n #echoId() {\n return crypto.randomBytes(16).toString('hex')\n }\n\n /** 构建 WebSocket 连接地址 */\n #buildWsUrl(): string {\n return `${this.#config.protocol}://${this.#config.host}:${this.#config.port}?access_token=${this.#config.token}`\n }\n\n /** 包装回复消息 */\n #wrapReply(sendable: Sendable | Sendable[], message_id?: number, reply?: boolean): Sendable[] {\n const sendableList = typeof sendable === 'string' ? [sendable] : [sendable].flat()\n\n if (reply && message_id) {\n return [segment.reply(String(message_id)), ...sendableList]\n }\n\n return sendableList\n }\n\n /** 确保 WebSocket 已连接 */\n #ensureWsConnection(ws: WebSocket | null): asserts ws is WebSocket {\n if (!ws) {\n this.logger.error('WebSocket is not connected.')\n throw new Error('WebSocket is not connected.')\n }\n\n if (ws.readyState !== WebSocket.OPEN) {\n this.logger.error('WebSocket is not open.')\n throw new Error('WebSocket is not open.')\n }\n }\n\n /** 标准化可发送消息元素 */\n #normalizeSendable(msg: Sendable | Sendable[]): NormalizedElementToSend[] {\n return [msg].flat(2).map((item) => {\n if (typeof item === 'string') {\n return { type: 'text', data: { text: item } }\n }\n if (item.type === 'at') {\n return { type: 'at', data: { qq: String(item.qq) } }\n }\n const { type, ...data } = item\n return { type, data } as NormalizedElementToSend\n })\n }\n\n /** 等待服务器响应操作 */\n #waitForAction<T extends any>(echoId: string) {\n const eventName = `echo#${echoId}`\n\n return new Promise<T>((resolve, reject) => {\n const handle = (data: any) => {\n if (!data || data.echo !== echoId) return\n\n this.#echoEvent.off(eventName, handle)\n\n if (data.retcode === 0) {\n resolve(data.data as T)\n } else {\n reject(`Server Error: ${data.message}`)\n }\n }\n\n this.#echoEvent.on(eventName, handle)\n })\n }\n\n /** 构建群对象 */\n #buildGroup<T extends object>(group_id: number, group_name: string = '', extraInfo: T = {} as T): Group & T {\n return {\n ...extraInfo,\n group_id,\n group_name,\n napcat: this,\n doSign: () => this.api('set_group_sign', { group_id }),\n getInfo: () => this.api('get_group_info', { group_id }),\n getMemberList: async () => this.api('get_group_member_list', { group_id }),\n getMemberInfo: (user_id: number) => this.api('get_group_member_info', { group_id, user_id }),\n setTitle: (title: string) => this.api('set_group_special_title', { group_id, title }),\n setCard: (user_id: number, card: string) => this.api('set_group_card', { group_id, user_id, card }),\n addEssence: (message_id: string) => this.api('set_essence_msg', { message_id }),\n delEssence: (message_id: string) => this.api('delete_essence_msg', { message_id }),\n recall: (message_id: number) => this.api('delete_msg', { message_id }),\n banMember: (user_id: number, duration: number) => this.api('set_group_ban', { group_id, user_id, duration }),\n sendMsg: (sendable: Sendable | Sendable[]) => this.sendGroupMsg(group_id, sendable),\n }\n }\n\n /** 构建好友对象 */\n #buildFriend<T extends object>(user_id: number, nickname: string = '', extraInfo: T = {} as T): Friend & T {\n return {\n ...extraInfo,\n user_id,\n nickname,\n napcat: this,\n delete: (block?: boolean, both?: boolean) =>\n this.api('delete_friend', { user_id, temp_block: block, temp_both_del: both }),\n sendMsg: (sendable: Sendable | Sendable[]) => this.sendPrivateMsg(user_id, sendable),\n getInfo: () => this.api('get_stranger_info', { user_id }),\n }\n }\n\n /** 构建私聊消息事件 */\n #buildPrivateMessageEvent(event: Omit<PrivateMessageEvent, 'message'> & { message: any[] }): PrivateMessageEvent {\n const quote_id: string | null = event.message.find((el: any) => el.type === 'reply')?.data?.id || null\n\n return {\n ...event,\n quote_id,\n getQuoteMessage: async (): Promise<PrivateMessageEvent | null> => {\n if (!quote_id) return null\n const event = await this.api<PrivateMessageEvent>('get_msg', { message_id: quote_id })\n return this.#buildPrivateMessageEvent(event)\n },\n message: (event.message || [])\n .filter((e) => e.type !== 'reply')\n .map((el: any) => ({ type: el.type, ...el.data })),\n friend: this.#buildFriend(event.user_id, event.sender?.nickname || ''),\n reply: (sendable: Sendable | Sendable[], reply = false) =>\n this.sendPrivateMsg(event.user_id, this.#wrapReply(sendable, event.message_id, reply)),\n }\n }\n\n /** 构建群消息事件对象 */\n #buildGroupMessageEvent(event: Omit<GroupMessageEvent, 'message'> & { message: any[] }): GroupMessageEvent {\n const quote_id: string | null = event.message.find((el: any) => el.type === 'reply')?.data?.id || null\n\n return {\n ...event,\n quote_id,\n getQuoteMessage: async (): Promise<GroupMessageEvent | null> => {\n if (!quote_id) return null\n const event = await this.api<GroupMessageEvent>('get_msg', { message_id: quote_id })\n return this.#buildGroupMessageEvent(event)\n },\n message: (event.message || [])\n .filter((e) => e.type !== 'reply')\n .map((el: any) => ({ type: el.type, ...el.data })),\n group: this.#buildGroup(event.group_id, event.group?.group_name || ''),\n recall: () => this.api<any>('delete_msg', { message_id: event.message_id }),\n addReaction: (id: string) =>\n this.api('set_msg_emoji_like', { message_id: event.message_id, emoji_id: id, set: true }),\n delReaction: (id: string) =>\n this.api('set_msg_emoji_like', { message_id: event.message_id, emoji_id: id, set: false }),\n addEssence: () => this.api('set_essence_msg', { message_id: event.message_id }),\n delEssence: () => this.api('delete_essence_msg', { message_id: event.message_id }),\n reply: (sendable: Sendable | Sendable[], reply = false) =>\n this.sendGroupMsg(event.group_id, this.#wrapReply(sendable, event.message_id, reply)),\n }\n }\n\n /** 绑定内部事件处理器 */\n #bindInternalEvents(data: any) {\n if (data.echo) {\n this.#echoEvent.emit(`echo#${data.echo}`, data)\n return\n }\n\n if (data.post_type) {\n switch (data.post_type) {\n case 'meta_event': {\n this.logger.trace(`received meta_event: ${JSON.stringify(data)}`)\n this.#event.emit('meta_event', data)\n\n if (data.meta_event_type) {\n this.#event.emit(`meta_event.${data.meta_event_type}`, data)\n if (data.sub_type) {\n if (data.sub_type === 'connect') {\n this.#uin = data.self_id\n this.#online = true\n this.#event.emit('napcat.connected', { uin: this.#uin, ts: data.time * 1000 })\n\n this.getLoginInfo().then((info) => {\n this.#nickname = info.nickname\n })\n }\n\n this.#event.emit(`meta_event.${data.meta_event_type}.${data.sub_type}`, data)\n }\n }\n\n break\n }\n\n case 'message': {\n if (data.message_type === 'private') {\n data = this.#buildPrivateMessageEvent(data)\n } else {\n data = this.#buildGroupMessageEvent(data)\n }\n\n this.#event.emit('message', data)\n\n switch (data.message_type) {\n case 'private': {\n this.logger.trace(`received private message: ${JSON.stringify(data)}`)\n this.#event.emit('message.private', data)\n this.#event.emit(`message.private.${data.sub_type}`, data)\n\n break\n }\n\n case 'group': {\n this.logger.trace(`received group message: ${JSON.stringify(data)}`)\n this.#event.emit('message.group', data)\n this.#event.emit(`message.group.${data.sub_type}`, data)\n\n break\n }\n\n default: {\n this.logger.debug(`received unknown message type: ${JSON.stringify(data)}`)\n\n break\n }\n }\n\n break\n }\n\n case 'message_sent': {\n this.logger.trace(`received message_sent: ${JSON.stringify(data)}`)\n this.#event.emit('message_sent', data)\n\n if (data.message_type) {\n this.#event.emit(`message_sent.${data.message_type}`, data)\n if (data.sub_type) {\n this.#event.emit(`message_sent.${data.message_type}.${data.sub_type}`, data)\n }\n }\n\n break\n }\n\n case 'notice': {\n this.logger.trace(`received notice: ${JSON.stringify(data)}`)\n\n if (!data.notice_type) {\n this.logger.debug(`received unknown notice type: ${JSON.stringify(data)}`)\n break\n }\n\n const isNotify = data.notice_type === 'notify'\n const isPoke = data.sub_type === 'poke'\n const isGroup = !!data.group_id\n\n const { notice_type, sub_type } = isNotify\n ? isPoke\n ? { notice_type: isGroup ? 'group' : 'friend', sub_type: 'poke' }\n : NAPCAT_NOTICE_NOTIFY_MAP[data.sub_type] || {}\n : NAPCAT_NOTICE_EVENT_MAP[data.notice_type] || {}\n\n data.original_notice_type = data.notice_type\n data.notice_type = notice_type || data.notice_type\n\n if (data.sub_type && data.sub_type !== sub_type) {\n data.action_type = data.sub_type\n }\n\n data.sub_type = sub_type || data.sub_type\n\n if (isGroup) {\n data.group = this.#buildGroup(data.group_id, data.group_name || '')\n } else {\n data.friend = this.#buildFriend(data.user_id, data.nickname || '')\n }\n\n this.#event.emit('notice', data)\n\n if (notice_type) {\n this.#event.emit(`notice.${notice_type}`, data)\n if (sub_type) {\n this.#event.emit(`notice.${notice_type}.${sub_type}`, data)\n }\n }\n\n break\n }\n\n case 'request': {\n this.logger.trace(`received request: ${JSON.stringify(data)}`)\n\n if (data.request_type === 'friend') {\n data.reject = () => this.api('set_friend_request', { flag: data.flag, approve: false })\n data.approve = () => this.api('set_friend_request', { flag: data.flag, approve: true })\n }\n\n if (data.request_type === 'group') {\n data.reject = (reason?: string) =>\n this.api('set_group_add_request', { flag: data.flag, approve: false, reason })\n data.approve = () => this.api('set_group_add_request', { flag: data.flag, approve: true })\n }\n\n this.#event.emit('request', data)\n\n if (data.request_type) {\n this.#event.emit(`request.${data.request_type}`, data)\n if (data.sub_type) {\n this.#event.emit(`request.${data.request_type}.${data.sub_type}`, data)\n }\n }\n\n break\n }\n\n default: {\n this.logger.debug(`received: ${JSON.stringify(data)}`)\n this.#event.emit(data.post_type, data)\n return\n }\n }\n\n return\n }\n }\n\n /** 获取一个群的信息,可以用于发送群消息等操作 */\n async pickGroup(group_id: number): Promise<GroupWithInfo | null> {\n try {\n const groupInfo = await this.api<ReturnType<Group['getInfo']>>('get_group_info', { group_id })\n return this.#buildGroup(group_id, groupInfo.group_name, groupInfo)\n } catch (err: any) {\n this.logger.warn(`Error to pickGroup ${group_id}: ${err?.message || err}`)\n return null\n }\n }\n\n /** 获取一个好友的信息,可以用于发送私聊消息等操作 */\n async pickFriend(user_id: number): Promise<FriendWithInfo | null> {\n try {\n const friendInfo = await this.api<ReturnType<Friend['getInfo']>>('get_stranger_info', { user_id })\n return this.#buildFriend(user_id, friendInfo.nickname, friendInfo)\n } catch (err: any) {\n this.logger.warn(`Error to pickFriend ${user_id}: ${err?.message || err}`)\n // return this.#buildFriend(user_id, '', {}) as FriendWithInfo\n return null\n }\n }\n\n /**\n * 注册一次性事件监听器\n */\n once<T extends keyof EventMap>(type: T, handler: (event: EventMap[NoInfer<T>]) => void): void {\n const onceHandler = (event: EventMap[NoInfer<T>]) => {\n handler(event)\n this.#event.off(type, onceHandler)\n }\n\n this.logger.debug(`registering once: ${String(type)}`)\n this.#event.on(type, onceHandler)\n }\n\n /**\n * 注册事件监听器,支持主类型或者点分子类型\n *\n * 如: `notice`、`message.private`、`request.group.invite` 等\n *\n * 如果需要移除监听器,请调用 `off` 方法\n */\n on<T extends keyof EventMap>(type: T, handler: (event: EventMap[NoInfer<T>]) => void): void {\n this.logger.debug(`registering: ${String(type)}`)\n this.#event.on(type, handler)\n }\n\n /**\n * 移除事件监听器\n */\n off<T extends keyof EventMap>(type: T, handler: (event: EventMap[NoInfer<T>]) => void): void {\n this.logger.debug(`unregistering: ${String(type)}`)\n this.#event.off(type, handler)\n }\n\n /**\n * 调用 NapCat API\n */\n api<T extends any>(action: API | (string & {}), params: Record<string, any> = {}): Promise<T> {\n this.#ensureWsConnection(this.#ws)\n this.logger.debug(`calling api action: ${action} with params: ${JSON.stringify(params)}`)\n const echo = this.#echoId()\n this.#ws.send(JSON.stringify({ echo, action, params }))\n return this.#waitForAction<T>(echo)\n }\n\n /**\n * 发送私聊消息\n */\n sendPrivateMsg(user_id: number, sendable: Sendable | Sendable[]): Promise<{ message_id: number }> {\n return this.api<{ message_id: number }>('send_private_msg', {\n user_id,\n message: this.#normalizeSendable(sendable),\n })\n }\n\n /**\n * 发送群消息\n */\n sendGroupMsg(group_id: number, sendable: Sendable | Sendable[]): Promise<{ message_id: number }> {\n return this.api<{ message_id: number }>('send_group_msg', {\n group_id,\n message: this.#normalizeSendable(sendable),\n })\n }\n\n /**\n * 机器人是否在线\n */\n isOnline(): boolean {\n return this.#ws?.readyState === WebSocket.OPEN && this.#online\n }\n\n /**\n * 计算 GTK 值\n */\n getGTk(pskey: string): number {\n let gkt = 5381\n for (let i = 0, len = pskey.length; i < len; ++i) {\n gkt += (gkt << 5) + pskey.charCodeAt(i)\n }\n return gkt & 0x7fffffff\n }\n\n /**\n * 获取 NapCat 原始 Cookie 相关信息\n */\n getNapCatCookies(domain: string): Promise<{ cookies: string; bkn: string }> {\n return this.api<{ cookies: string; bkn: string }>('get_cookies', { domain })\n }\n\n /**\n * 获取版本信息\n */\n getVersionInfo(): Promise<{ app_name: string; protocol_version: string; app_version: string }> {\n return this.api<{ app_name: string; protocol_version: string; app_version: string }>('get_version_info')\n }\n\n /**\n * 获取登录信息\n */\n getLoginInfo(): Promise<{ user_id: number; nickname: string }> {\n return this.api<{ user_id: number; nickname: string }>('get_login_info')\n }\n\n /**\n * 获取 Cookie 相关信息\n */\n async getCookie(domain: string): Promise<{\n uin: number\n pskey: string\n skey: string\n gtk: string\n bkn: string\n cookie: string\n legacyCookie: string\n }> {\n const cache = this.#cookieCache.get(domain)\n\n if (cache) return cache\n\n const { cookies: cookieString, bkn } = await this.getNapCatCookies(domain)\n\n const skey = cookieString.match(/skey=([^;]*)/)?.[1] || ''\n const pskey = cookieString.match(/pskey=([^;]*)/)?.[1] || ''\n const gtk = this.getGTk(pskey)\n\n const returns = {\n pskey,\n skey,\n uin: this.uin,\n gtk: String(gtk),\n bkn,\n cookie: `uin=${this.uin}; skey=${skey}; p_uin=${this.uin}; p_skey=${pskey};`,\n legacyCookie: `uin=o${this.uin}; skey=${skey}; p_uin=o${this.uin}; p_skey=${pskey};`,\n }\n\n this.#cookieCache.set(domain, returns)\n\n // 1 小时后清除缓存\n setTimeout(\n () => {\n this.#cookieCache.delete(domain)\n },\n 1000 * 60 * 60,\n )\n\n return returns\n }\n\n /**\n * 通过域名获取 Pskey\n */\n async getPskey(domain: string): Promise<string> {\n const { pskey } = await this.getCookie(domain)\n return pskey\n }\n\n /**\n * 获取 Bkn 值\n */\n async getBkn(): Promise<string> {\n const { bkn } = await this.getCookie('vip.qq.com')\n return bkn\n }\n\n /** 启动 NapCat SDK 实例,建立 WebSocket 连接 */\n async run(): Promise<void> {\n const { logger: _, token: __, ...config } = this.#config\n\n this.logger.info(`run with config: ${JSON.stringify(config)}`)\n\n return new Promise<void>((resolve, reject) => {\n const ws = new WebSocket(this.#buildWsUrl())\n\n ws.onmessage = (event) => {\n const data = (() => {\n try {\n return JSON.parse(event.data)\n } catch {\n return null\n }\n })() as any\n\n if (!data) {\n this.logger.warn(`received non-json message: ${event.data}`)\n return\n }\n\n this.#event.emit('ws.message', data)\n this.#bindInternalEvents(data)\n }\n\n ws.onclose = () => {\n this.#online = false\n this.logger.info('closed')\n this.#event.emit('ws.close')\n }\n\n ws.onerror = (error) => {\n this.#online = false\n this.logger.error(`error: ${error}`)\n this.#event.emit('ws.error', error)\n reject(error)\n }\n\n ws.onopen = () => {\n this.logger.info('NapCat connected')\n this.#event.emit('ws.open')\n resolve()\n }\n\n this.#ws = ws\n\n this.logger.trace(`WebSocket instance created: ${this.#ws}`)\n })\n }\n\n /** 销毁 NapCat SDK 实例,关闭 WebSocket 连接 */\n close(): void {\n if (this.#ws) {\n this.logger.info('destroying NapCat SDK instance...')\n this.#ws.close()\n this.#ws = null\n this.logger.info('NapCat SDK instance destroyed.')\n } else {\n this.logger.warn('NapCat SDK instance is not initialized.')\n }\n }\n}\n\n// ==================== 通知事件映射 ====================\n\n/**\n * NapCat 通知类型映射表(notify 类型)\n * @description 将 NapCat 特有的通知类型映射到标准的 notice_type 和 sub_type\n */\nconst NAPCAT_NOTICE_NOTIFY_MAP: Record<string, { notice_type: string; sub_type: string }> = {\n input_status: {\n notice_type: 'friend',\n sub_type: 'input',\n },\n profile_like: {\n notice_type: 'friend',\n sub_type: 'like',\n },\n title: {\n notice_type: 'group',\n sub_type: 'title',\n },\n}\n\n/**\n * NapCat 通知事件映射表(notice 类型)\n * @description 将 NapCat 的原始通知事件类型映射到标准的 notice_type 和 sub_type\n */\nconst NAPCAT_NOTICE_EVENT_MAP: Record<string, { notice_type: string; sub_type: string }> = {\n friend_add: {\n notice_type: 'friend',\n sub_type: 'increase',\n },\n friend_recall: {\n notice_type: 'friend',\n sub_type: 'recall',\n },\n offline_file: {\n notice_type: 'friend',\n sub_type: 'offline_file',\n },\n client_status: {\n notice_type: 'client',\n sub_type: 'status',\n },\n group_admin: {\n notice_type: 'group',\n sub_type: 'admin',\n },\n group_ban: {\n notice_type: 'group',\n sub_type: 'ban',\n },\n group_card: {\n notice_type: 'group',\n sub_type: 'card',\n },\n group_upload: {\n notice_type: 'group',\n sub_type: 'upload',\n },\n group_decrease: {\n notice_type: 'group',\n sub_type: 'decrease',\n },\n group_increase: {\n notice_type: 'group',\n sub_type: 'increase',\n },\n group_msg_emoji_like: {\n notice_type: 'group',\n sub_type: 'reaction',\n },\n essence: {\n notice_type: 'group',\n sub_type: 'essence',\n },\n group_recall: {\n notice_type: 'group',\n sub_type: 'recall',\n },\n}\n"],"mappings":"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"}
|