@rdjksp/node-napcat-ts 0.4.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +22 -0
- package/dist/Interfaces.d.ts +2309 -0
- package/dist/Interfaces.js +1 -0
- package/dist/NCEventBus.d.ts +32 -0
- package/dist/NCEventBus.js +336 -0
- package/dist/NCWebsocketApi.d.ts +1793 -0
- package/dist/NCWebsocketApi.js +1011 -0
- package/dist/NCWebsocketBase.d.ts +58 -0
- package/dist/NCWebsocketBase.js +276 -0
- package/dist/Structs.d.ts +379 -0
- package/dist/Structs.js +230 -0
- package/dist/Utils.d.ts +18 -0
- package/dist/Utils.js +65 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/package.json +74 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { EventHandleMap, EventKey, HandlerResMap, NCWebsocketOptions, WSSendParam, WSSendReturn } from './Interfaces.js';
|
|
2
|
+
export declare class NCWebsocketBase {
|
|
3
|
+
#private;
|
|
4
|
+
constructor(NCWebsocketOptions: NCWebsocketOptions, debug?: boolean);
|
|
5
|
+
/**
|
|
6
|
+
* await connect() 等待 ws 连接
|
|
7
|
+
*/
|
|
8
|
+
connect(): Promise<void>;
|
|
9
|
+
disconnect(): void;
|
|
10
|
+
reconnect(): Promise<void>;
|
|
11
|
+
/**
|
|
12
|
+
* 发送API请求
|
|
13
|
+
* @param method API 端点
|
|
14
|
+
* @param params 请求参数
|
|
15
|
+
*/
|
|
16
|
+
send<T extends keyof WSSendParam>(method: T, params: WSSendParam[T]): Promise<WSSendReturn[T]>;
|
|
17
|
+
/**
|
|
18
|
+
* 注册监听方法
|
|
19
|
+
* @param event
|
|
20
|
+
* @param handle
|
|
21
|
+
* @returns 返回自身引用
|
|
22
|
+
*/
|
|
23
|
+
on<T extends EventKey>(event: T, handle: EventHandleMap[T]): this;
|
|
24
|
+
/**
|
|
25
|
+
* 只执行一次
|
|
26
|
+
* @param event
|
|
27
|
+
* @param handle
|
|
28
|
+
* @returns 返回自身引用
|
|
29
|
+
*/
|
|
30
|
+
once<T extends EventKey>(event: T, handle: EventHandleMap[T]): this;
|
|
31
|
+
/**
|
|
32
|
+
* 解除监听方法
|
|
33
|
+
* @param event
|
|
34
|
+
* @param handle
|
|
35
|
+
* @returns 返回自身引用
|
|
36
|
+
*/
|
|
37
|
+
off<T extends EventKey>(event: T, handle: EventHandleMap[T]): this;
|
|
38
|
+
/**
|
|
39
|
+
* effect风格的订阅 效果同on
|
|
40
|
+
* @param event
|
|
41
|
+
* @param handle
|
|
42
|
+
* @returns 返回执行后取消订阅的函数
|
|
43
|
+
*/
|
|
44
|
+
subscribe<T extends EventKey>(event: T, handle: EventHandleMap[T]): () => void;
|
|
45
|
+
/**
|
|
46
|
+
* effect风格的订阅 效果同once
|
|
47
|
+
* @param event
|
|
48
|
+
* @param handle
|
|
49
|
+
* @returns 返回执行后取消订阅的函数
|
|
50
|
+
*/
|
|
51
|
+
subscribeOnce<T extends EventKey>(event: T, handle: EventHandleMap[T]): () => void;
|
|
52
|
+
/**
|
|
53
|
+
* 手动模拟触发某个事件
|
|
54
|
+
* @param type
|
|
55
|
+
* @param context
|
|
56
|
+
*/
|
|
57
|
+
emit<T extends EventKey>(type: T, context: HandlerResMap[T]): this;
|
|
58
|
+
}
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import WebSocket from 'isomorphic-ws';
|
|
2
|
+
import { nanoid } from 'nanoid';
|
|
3
|
+
import { NCEventBus } from './NCEventBus.js';
|
|
4
|
+
import { convertCQCodeToJSON, CQCodeDecode, logger } from './Utils.js';
|
|
5
|
+
export class NCWebsocketBase {
|
|
6
|
+
#debug;
|
|
7
|
+
#baseUrl;
|
|
8
|
+
#accessToken;
|
|
9
|
+
#throwPromise;
|
|
10
|
+
#reconnection;
|
|
11
|
+
#socket;
|
|
12
|
+
#eventBus;
|
|
13
|
+
#echoMap;
|
|
14
|
+
constructor(NCWebsocketOptions, debug = false) {
|
|
15
|
+
this.#accessToken = NCWebsocketOptions.accessToken ?? '';
|
|
16
|
+
this.#throwPromise = NCWebsocketOptions.throwPromise ?? false;
|
|
17
|
+
if ('baseUrl' in NCWebsocketOptions) {
|
|
18
|
+
this.#baseUrl = NCWebsocketOptions.baseUrl;
|
|
19
|
+
}
|
|
20
|
+
else if ('protocol' in NCWebsocketOptions &&
|
|
21
|
+
'host' in NCWebsocketOptions &&
|
|
22
|
+
'port' in NCWebsocketOptions) {
|
|
23
|
+
const { protocol, host, port } = NCWebsocketOptions;
|
|
24
|
+
this.#baseUrl = protocol + '://' + host + ':' + port;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
throw new Error('NCWebsocketOptions must contain either "protocol && host && port" or "baseUrl"');
|
|
28
|
+
}
|
|
29
|
+
// 整理重连参数
|
|
30
|
+
const { enable = true, attempts = 10, delay = 5000 } = NCWebsocketOptions.reconnection ?? {};
|
|
31
|
+
this.#reconnection = { enable, attempts, delay, nowAttempts: 1 };
|
|
32
|
+
this.#debug = debug;
|
|
33
|
+
this.#eventBus = new NCEventBus(this);
|
|
34
|
+
this.#echoMap = new Map();
|
|
35
|
+
}
|
|
36
|
+
// ==================WebSocket操作=============================
|
|
37
|
+
/**
|
|
38
|
+
* await connect() 等待 ws 连接
|
|
39
|
+
*/
|
|
40
|
+
async connect() {
|
|
41
|
+
return new Promise((resolve, reject) => {
|
|
42
|
+
this.#eventBus.emit('socket.connecting', { reconnection: this.#reconnection });
|
|
43
|
+
const socket = new WebSocket(`${this.#baseUrl}?access_token=${this.#accessToken}`);
|
|
44
|
+
socket.onopen = () => {
|
|
45
|
+
this.#eventBus.emit('socket.open', { reconnection: this.#reconnection });
|
|
46
|
+
this.#reconnection.nowAttempts = 1;
|
|
47
|
+
resolve();
|
|
48
|
+
};
|
|
49
|
+
socket.onclose = async (event) => {
|
|
50
|
+
this.#eventBus.emit('socket.close', {
|
|
51
|
+
code: event.code,
|
|
52
|
+
reason: event.reason,
|
|
53
|
+
reconnection: this.#reconnection,
|
|
54
|
+
});
|
|
55
|
+
if (this.#reconnection.enable &&
|
|
56
|
+
this.#reconnection.nowAttempts < this.#reconnection.attempts) {
|
|
57
|
+
this.#reconnection.nowAttempts++;
|
|
58
|
+
setTimeout(async () => {
|
|
59
|
+
try {
|
|
60
|
+
await this.reconnect();
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
reject(error);
|
|
64
|
+
}
|
|
65
|
+
}, this.#reconnection.delay);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
socket.onmessage = (event) => this.#message(event.data);
|
|
69
|
+
socket.onerror = (event) => {
|
|
70
|
+
this.#eventBus.emit('socket.error', {
|
|
71
|
+
reconnection: this.#reconnection,
|
|
72
|
+
error_type: 'connect_error',
|
|
73
|
+
errors: event?.error?.errors ?? [event?.error ?? null],
|
|
74
|
+
});
|
|
75
|
+
if (this.#throwPromise) {
|
|
76
|
+
if (this.#reconnection.enable &&
|
|
77
|
+
this.#reconnection.nowAttempts < this.#reconnection.attempts) {
|
|
78
|
+
// 重连未到最后一次,等待继续重连,不抛出错误
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
reject({
|
|
82
|
+
reconnection: this.#reconnection,
|
|
83
|
+
error_type: 'connect_error',
|
|
84
|
+
errors: event?.error?.errors ?? [event?.error ?? null],
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
this.#socket = socket;
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
disconnect() {
|
|
92
|
+
if (this.#socket) {
|
|
93
|
+
this.#socket.close(1000);
|
|
94
|
+
this.#socket = undefined;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async reconnect() {
|
|
98
|
+
this.disconnect();
|
|
99
|
+
await this.connect();
|
|
100
|
+
}
|
|
101
|
+
#message(data) {
|
|
102
|
+
let strData;
|
|
103
|
+
try {
|
|
104
|
+
strData = data.toString();
|
|
105
|
+
// 检查数据是否看起来像有效的JSON (以 { 或 [ 开头)
|
|
106
|
+
if (!(strData.trim().startsWith('{') || strData.trim().startsWith('['))) {
|
|
107
|
+
logger.warn('[node-napcat-ts]', '[socket]', 'received non-JSON data:', strData);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
let json = JSON.parse(strData);
|
|
111
|
+
if (json.post_type === 'message' || json.post_type === 'message_sent') {
|
|
112
|
+
if (json.message_format === 'string') {
|
|
113
|
+
// 直接处理message字段,而不是整个json对象
|
|
114
|
+
json.message = convertCQCodeToJSON(CQCodeDecode(json.message));
|
|
115
|
+
json.message_format = 'array';
|
|
116
|
+
}
|
|
117
|
+
if (typeof json.raw_message === 'string') {
|
|
118
|
+
json.raw_message = CQCodeDecode(json.raw_message);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (this.#debug) {
|
|
122
|
+
logger.debug('[node-napcat-ts]', '[socket]', 'receive data');
|
|
123
|
+
logger.dir(json);
|
|
124
|
+
}
|
|
125
|
+
if (json.echo) {
|
|
126
|
+
const handler = this.#echoMap.get(json.echo);
|
|
127
|
+
if (handler) {
|
|
128
|
+
if (json.retcode === 0) {
|
|
129
|
+
this.#eventBus.emit('api.response.success', json);
|
|
130
|
+
handler.onSuccess(json);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
this.#eventBus.emit('api.response.failure', json);
|
|
134
|
+
handler.onFailure(json);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
if (json?.status === 'failed' && json?.echo === null) {
|
|
140
|
+
this.#reconnection.enable = false;
|
|
141
|
+
this.#eventBus.emit('socket.error', {
|
|
142
|
+
reconnection: this.#reconnection,
|
|
143
|
+
error_type: 'response_error',
|
|
144
|
+
info: {
|
|
145
|
+
url: this.#baseUrl,
|
|
146
|
+
errno: json.retcode,
|
|
147
|
+
message: json.message,
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
if (this.#throwPromise)
|
|
151
|
+
throw new Error(json.message);
|
|
152
|
+
this.disconnect();
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
this.#eventBus.parseMessage(json);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
logger.warn('[node-napcat-ts]', '[socket]', 'failed to parse JSON');
|
|
160
|
+
logger.dir(error);
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// ==================事件绑定=============================
|
|
165
|
+
/**
|
|
166
|
+
* 发送API请求
|
|
167
|
+
* @param method API 端点
|
|
168
|
+
* @param params 请求参数
|
|
169
|
+
*/
|
|
170
|
+
send(method, params) {
|
|
171
|
+
const echo = nanoid();
|
|
172
|
+
const message = {
|
|
173
|
+
action: method,
|
|
174
|
+
params: params,
|
|
175
|
+
echo,
|
|
176
|
+
};
|
|
177
|
+
if (this.#debug) {
|
|
178
|
+
logger.debug('[node-open-napcat] send request');
|
|
179
|
+
logger.dir(message);
|
|
180
|
+
}
|
|
181
|
+
return new Promise((resolve, reject) => {
|
|
182
|
+
const onSuccess = (response) => {
|
|
183
|
+
this.#echoMap.delete(echo);
|
|
184
|
+
return resolve(response.data);
|
|
185
|
+
};
|
|
186
|
+
const onFailure = (reason) => {
|
|
187
|
+
this.#echoMap.delete(echo);
|
|
188
|
+
return reject(reason);
|
|
189
|
+
};
|
|
190
|
+
this.#echoMap.set(echo, {
|
|
191
|
+
message,
|
|
192
|
+
onSuccess,
|
|
193
|
+
onFailure,
|
|
194
|
+
});
|
|
195
|
+
this.#eventBus.emit('api.preSend', message);
|
|
196
|
+
if (this.#socket === undefined) {
|
|
197
|
+
reject({
|
|
198
|
+
status: 'failed',
|
|
199
|
+
retcode: -1,
|
|
200
|
+
data: null,
|
|
201
|
+
message: 'api socket is not connected',
|
|
202
|
+
echo: '',
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
else if (this.#socket.readyState === WebSocket.CLOSING) {
|
|
206
|
+
reject({
|
|
207
|
+
status: 'failed',
|
|
208
|
+
retcode: -1,
|
|
209
|
+
data: null,
|
|
210
|
+
message: 'api socket is closed',
|
|
211
|
+
echo: '',
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
this.#socket.send(JSON.stringify(message));
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* 注册监听方法
|
|
221
|
+
* @param event
|
|
222
|
+
* @param handle
|
|
223
|
+
* @returns 返回自身引用
|
|
224
|
+
*/
|
|
225
|
+
on(event, handle) {
|
|
226
|
+
this.#eventBus.on(event, handle);
|
|
227
|
+
return this;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* 只执行一次
|
|
231
|
+
* @param event
|
|
232
|
+
* @param handle
|
|
233
|
+
* @returns 返回自身引用
|
|
234
|
+
*/
|
|
235
|
+
once(event, handle) {
|
|
236
|
+
this.#eventBus.once(event, handle);
|
|
237
|
+
return this;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* 解除监听方法
|
|
241
|
+
* @param event
|
|
242
|
+
* @param handle
|
|
243
|
+
* @returns 返回自身引用
|
|
244
|
+
*/
|
|
245
|
+
off(event, handle) {
|
|
246
|
+
this.#eventBus.off(event, handle);
|
|
247
|
+
return this;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* effect风格的订阅 效果同on
|
|
251
|
+
* @param event
|
|
252
|
+
* @param handle
|
|
253
|
+
* @returns 返回执行后取消订阅的函数
|
|
254
|
+
*/
|
|
255
|
+
subscribe(event, handle) {
|
|
256
|
+
return this.#eventBus.subscribe(event, handle);
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* effect风格的订阅 效果同once
|
|
260
|
+
* @param event
|
|
261
|
+
* @param handle
|
|
262
|
+
* @returns 返回执行后取消订阅的函数
|
|
263
|
+
*/
|
|
264
|
+
subscribeOnce(event, handle) {
|
|
265
|
+
return this.#eventBus.subscribeOnce(event, handle);
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* 手动模拟触发某个事件
|
|
269
|
+
* @param type
|
|
270
|
+
* @param context
|
|
271
|
+
*/
|
|
272
|
+
emit(type, context) {
|
|
273
|
+
this.#eventBus.emit(type, context);
|
|
274
|
+
return this;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
export interface UnSafeStruct {
|
|
2
|
+
type: string;
|
|
3
|
+
data: {
|
|
4
|
+
[k: string]: any;
|
|
5
|
+
};
|
|
6
|
+
}
|
|
7
|
+
export interface Receive {
|
|
8
|
+
text: {
|
|
9
|
+
type: 'text';
|
|
10
|
+
data: {
|
|
11
|
+
text: string;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
at: {
|
|
15
|
+
type: 'at';
|
|
16
|
+
data: {
|
|
17
|
+
qq: string | 'all';
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
image: {
|
|
21
|
+
type: 'image';
|
|
22
|
+
data: {
|
|
23
|
+
summary: string;
|
|
24
|
+
file: string;
|
|
25
|
+
sub_type: number;
|
|
26
|
+
url: string;
|
|
27
|
+
file_size: string;
|
|
28
|
+
} | {
|
|
29
|
+
summary: string;
|
|
30
|
+
file: string;
|
|
31
|
+
sub_type: string;
|
|
32
|
+
url: string;
|
|
33
|
+
key: string;
|
|
34
|
+
emoji_id: string;
|
|
35
|
+
emoji_package_id: number;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
file: {
|
|
39
|
+
type: 'file';
|
|
40
|
+
data: {
|
|
41
|
+
file: string;
|
|
42
|
+
file_id: string;
|
|
43
|
+
file_size: string;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
poke: {
|
|
47
|
+
type: 'poke';
|
|
48
|
+
data: {
|
|
49
|
+
type: string;
|
|
50
|
+
id: string;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
dice: {
|
|
54
|
+
type: 'dice';
|
|
55
|
+
data: {
|
|
56
|
+
result: string;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
rps: {
|
|
60
|
+
type: 'rps';
|
|
61
|
+
data: {
|
|
62
|
+
result: string;
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
face: {
|
|
66
|
+
type: 'face';
|
|
67
|
+
data: {
|
|
68
|
+
id: string;
|
|
69
|
+
raw: {
|
|
70
|
+
faceIndex?: number;
|
|
71
|
+
faceText?: string;
|
|
72
|
+
faceType?: number;
|
|
73
|
+
packId?: string;
|
|
74
|
+
stickerId?: string;
|
|
75
|
+
sourceType?: number;
|
|
76
|
+
stickerType?: number;
|
|
77
|
+
resultId?: string;
|
|
78
|
+
surpriseId?: string;
|
|
79
|
+
randomType?: number;
|
|
80
|
+
imageType?: number;
|
|
81
|
+
pokeType?: number;
|
|
82
|
+
spokeSummary?: string;
|
|
83
|
+
doubleHit?: number;
|
|
84
|
+
vaspokeId?: number;
|
|
85
|
+
vaspokeName?: string;
|
|
86
|
+
vaspokeMinver?: number;
|
|
87
|
+
pokeStrength?: number;
|
|
88
|
+
msgType?: number;
|
|
89
|
+
faceBubbleCount?: number;
|
|
90
|
+
oldVersionStr?: string;
|
|
91
|
+
pokeFlag?: number;
|
|
92
|
+
chainCount?: number;
|
|
93
|
+
};
|
|
94
|
+
resultId: string | null;
|
|
95
|
+
chainCount: number | null;
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
reply: {
|
|
99
|
+
type: 'reply';
|
|
100
|
+
data: {
|
|
101
|
+
id: string;
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
video: {
|
|
105
|
+
type: 'video';
|
|
106
|
+
data: {
|
|
107
|
+
file: string;
|
|
108
|
+
url: string;
|
|
109
|
+
file_size: string;
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
record: {
|
|
113
|
+
type: 'record';
|
|
114
|
+
data: {
|
|
115
|
+
file: string;
|
|
116
|
+
file_size: string;
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
forward: {
|
|
120
|
+
type: 'forward';
|
|
121
|
+
data: {
|
|
122
|
+
id: string;
|
|
123
|
+
content?: Receive[keyof Receive][];
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
json: {
|
|
127
|
+
type: 'json';
|
|
128
|
+
data: {
|
|
129
|
+
data: string;
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
markdown: {
|
|
133
|
+
type: 'markdown';
|
|
134
|
+
data: {
|
|
135
|
+
content: string;
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
interface BaseSegment<T extends string, D> {
|
|
140
|
+
type: T;
|
|
141
|
+
data: D;
|
|
142
|
+
}
|
|
143
|
+
export interface TextSegment extends BaseSegment<'text', {
|
|
144
|
+
text: string;
|
|
145
|
+
}> {
|
|
146
|
+
}
|
|
147
|
+
export interface AtSegment extends BaseSegment<'at', {
|
|
148
|
+
qq: string | 'all';
|
|
149
|
+
}> {
|
|
150
|
+
}
|
|
151
|
+
export interface ReplySegment extends BaseSegment<'reply', {
|
|
152
|
+
id: string;
|
|
153
|
+
}> {
|
|
154
|
+
}
|
|
155
|
+
export interface FaceSegment extends BaseSegment<'face', {
|
|
156
|
+
id: string;
|
|
157
|
+
}> {
|
|
158
|
+
}
|
|
159
|
+
export interface MFaceSegment extends BaseSegment<'mface', {
|
|
160
|
+
emoji_id: string;
|
|
161
|
+
emoji_package_id: string;
|
|
162
|
+
key: string;
|
|
163
|
+
summary?: string;
|
|
164
|
+
}> {
|
|
165
|
+
}
|
|
166
|
+
export interface ImageSegment extends BaseSegment<'image', {
|
|
167
|
+
file: string;
|
|
168
|
+
summary?: string;
|
|
169
|
+
sub_type?: string;
|
|
170
|
+
}> {
|
|
171
|
+
}
|
|
172
|
+
export interface FileSegment extends BaseSegment<'file', {
|
|
173
|
+
file: string;
|
|
174
|
+
name?: string;
|
|
175
|
+
}> {
|
|
176
|
+
}
|
|
177
|
+
export interface VideoSegment extends BaseSegment<'video', {
|
|
178
|
+
file: string;
|
|
179
|
+
name?: string;
|
|
180
|
+
thumb?: string;
|
|
181
|
+
}> {
|
|
182
|
+
}
|
|
183
|
+
export interface RecordSegment extends BaseSegment<'record', {
|
|
184
|
+
file: string;
|
|
185
|
+
}> {
|
|
186
|
+
}
|
|
187
|
+
export interface JsonSegment extends BaseSegment<'json', {
|
|
188
|
+
data: string;
|
|
189
|
+
}> {
|
|
190
|
+
}
|
|
191
|
+
export interface DiceSegment extends BaseSegment<'dice', any> {
|
|
192
|
+
}
|
|
193
|
+
export interface RPSSegment extends BaseSegment<'rps', any> {
|
|
194
|
+
}
|
|
195
|
+
export interface MarkdownSegment extends BaseSegment<'markdown', {
|
|
196
|
+
content: string;
|
|
197
|
+
}> {
|
|
198
|
+
}
|
|
199
|
+
export interface CloudMusicSegment extends BaseSegment<'music', {
|
|
200
|
+
type: 'qq' | '163' | 'kugou' | 'kuwo' | 'migu';
|
|
201
|
+
id: string;
|
|
202
|
+
}> {
|
|
203
|
+
}
|
|
204
|
+
export interface MusicSegmentCustom extends BaseSegment<'music', {
|
|
205
|
+
type: 'qq' | '163' | 'kugou' | 'kuwo' | 'migu' | 'custom';
|
|
206
|
+
url: string;
|
|
207
|
+
image: string;
|
|
208
|
+
audio?: string;
|
|
209
|
+
title?: string;
|
|
210
|
+
singer?: string;
|
|
211
|
+
}> {
|
|
212
|
+
}
|
|
213
|
+
export type MusicSegment = CloudMusicSegment | MusicSegmentCustom;
|
|
214
|
+
export interface NodeSegment extends BaseSegment<'node', ({
|
|
215
|
+
content: SendMessageSegment[];
|
|
216
|
+
} | {
|
|
217
|
+
id: string;
|
|
218
|
+
}) & {
|
|
219
|
+
user_id?: string;
|
|
220
|
+
nickname?: string;
|
|
221
|
+
source?: string;
|
|
222
|
+
news?: {
|
|
223
|
+
text: string;
|
|
224
|
+
}[];
|
|
225
|
+
summary?: string;
|
|
226
|
+
prompt?: string;
|
|
227
|
+
time?: string;
|
|
228
|
+
}> {
|
|
229
|
+
}
|
|
230
|
+
export interface ForwardSegment extends BaseSegment<'forward', {
|
|
231
|
+
id: string;
|
|
232
|
+
}> {
|
|
233
|
+
}
|
|
234
|
+
export interface ContactSegment extends BaseSegment<'contact', {
|
|
235
|
+
type: 'qq' | 'group';
|
|
236
|
+
id: string;
|
|
237
|
+
}> {
|
|
238
|
+
}
|
|
239
|
+
export type SendMessageSegment = TextSegment | AtSegment | ReplySegment | FaceSegment | MFaceSegment | ImageSegment | FileSegment | VideoSegment | RecordSegment | JsonSegment | DiceSegment | RPSSegment | MarkdownSegment | MusicSegment | NodeSegment | ForwardSegment | ContactSegment;
|
|
240
|
+
export declare const Structs: {
|
|
241
|
+
/**
|
|
242
|
+
* 发送文字消息
|
|
243
|
+
* @param text 要发送的文字
|
|
244
|
+
* @returns { type: 'text', data: { text } }
|
|
245
|
+
*/
|
|
246
|
+
text: (text: string) => TextSegment;
|
|
247
|
+
/**
|
|
248
|
+
* @某人
|
|
249
|
+
* @param qq at的QQ号
|
|
250
|
+
* @returns { type: 'at', data: { qq } }
|
|
251
|
+
*/
|
|
252
|
+
at: (qq: string | "all" | number) => AtSegment;
|
|
253
|
+
/**
|
|
254
|
+
* 回复消息
|
|
255
|
+
* @param id 回复的消息id
|
|
256
|
+
* @returns { type: 'reply', data: { id } }
|
|
257
|
+
*/
|
|
258
|
+
reply: (id: string | number) => ReplySegment;
|
|
259
|
+
/**
|
|
260
|
+
* 发送QQ表情
|
|
261
|
+
* @param id QQ 表情 ID
|
|
262
|
+
* @returns { type: 'face', data: { id, resultId, chainCount } }
|
|
263
|
+
*/
|
|
264
|
+
face: (id: string | number) => FaceSegment;
|
|
265
|
+
/**
|
|
266
|
+
* 发送QQ表情包
|
|
267
|
+
* @param emoji_id 表情id
|
|
268
|
+
* @param emoji_package_id 表情包id
|
|
269
|
+
* @param key 未知(必要)
|
|
270
|
+
* @param summary 表情简介,可选
|
|
271
|
+
* @returns { type: 'mface', data: { summary, emoji_id, emoji_package_id, key } }
|
|
272
|
+
*/
|
|
273
|
+
mface: (emoji_id: string | number, emoji_package_id: string | number, key: string, summary?: string) => MFaceSegment;
|
|
274
|
+
/**
|
|
275
|
+
* 发送图片
|
|
276
|
+
* @param file 网络图片地址, 文件路径或者Buffer
|
|
277
|
+
* @param name 图片名
|
|
278
|
+
* @param summary 图片简介
|
|
279
|
+
* @param sub_type 图片类型
|
|
280
|
+
* @returns { type: 'image', data: { file, summary, sub_type } }
|
|
281
|
+
*/
|
|
282
|
+
image: (file: string | Buffer, summary?: string, sub_type?: string | number) => ImageSegment;
|
|
283
|
+
/**
|
|
284
|
+
* 发文件
|
|
285
|
+
* @param file 网络文件地址, 文件路径或者Buffer
|
|
286
|
+
* @param name 文件名
|
|
287
|
+
* @returns { type: 'file', data: { file, name } }
|
|
288
|
+
*/
|
|
289
|
+
file: (file: string | Buffer, name?: string) => FileSegment;
|
|
290
|
+
/**
|
|
291
|
+
* 发视频
|
|
292
|
+
* @param file 网络视频地址, 文件路径或者Buffer
|
|
293
|
+
* @param name 视频名
|
|
294
|
+
* @param thumb 预览图
|
|
295
|
+
* @returns { type: 'video', data: { file, name, thumb } }
|
|
296
|
+
*/
|
|
297
|
+
video: (file: string | Buffer, name?: string, thumb?: string) => VideoSegment;
|
|
298
|
+
/**
|
|
299
|
+
* 发语音
|
|
300
|
+
* @param file 网络语音地址, 文件路径或者Buffer
|
|
301
|
+
* @param name 语音备注
|
|
302
|
+
* @returns { type: 'record', data: { file, name } }
|
|
303
|
+
*/
|
|
304
|
+
record: (file: string | Buffer) => RecordSegment;
|
|
305
|
+
/**
|
|
306
|
+
* 发送json消息
|
|
307
|
+
* @param data json信息(序列化后)
|
|
308
|
+
* @returns { type: 'json', data: { data } }
|
|
309
|
+
*/
|
|
310
|
+
json: (data: string) => JsonSegment;
|
|
311
|
+
/**
|
|
312
|
+
* 发送骰子魔法表情
|
|
313
|
+
* @returns { type: 'dice', data: {} }
|
|
314
|
+
*/
|
|
315
|
+
dice: () => DiceSegment;
|
|
316
|
+
/**
|
|
317
|
+
* 发送猜拳魔法
|
|
318
|
+
* @returns { type: 'rps', data: {} }
|
|
319
|
+
*/
|
|
320
|
+
rps: () => RPSSegment;
|
|
321
|
+
/**
|
|
322
|
+
* 发送markdown
|
|
323
|
+
* @param data markdown内容
|
|
324
|
+
* @returns { type: 'markdown', data: {} }
|
|
325
|
+
*/
|
|
326
|
+
markdown: (content: string) => MarkdownSegment;
|
|
327
|
+
/**
|
|
328
|
+
* 音乐分享
|
|
329
|
+
* @param type QQ音乐或网易云音乐QQ音乐
|
|
330
|
+
* @param id 音乐id
|
|
331
|
+
* @returns { type: 'music', data: { type, id } }
|
|
332
|
+
*/
|
|
333
|
+
music: (type: "qq" | "163" | "kugou" | "migu" | "kuwo", id: string | number) => CloudMusicSegment;
|
|
334
|
+
/**
|
|
335
|
+
* 分享非qq、网易云音乐 需要配置签名服务器
|
|
336
|
+
* @param url 点击后跳转目标 URL
|
|
337
|
+
* @param audio 音乐 URL
|
|
338
|
+
* @param title 标题
|
|
339
|
+
* @param image 发送时可选,内容描述
|
|
340
|
+
* @param singer 发送时可选,图片 URL
|
|
341
|
+
* @returns { type: 'music', data: { type: 'custom', url, audio, title, image, singer } }
|
|
342
|
+
*/
|
|
343
|
+
customMusic: (type: "qq" | "163" | "kugou" | "migu" | "kuwo" | "custom", url: string, image: string, audio?: string, title?: string, singer?: string) => MusicSegmentCustom;
|
|
344
|
+
/**
|
|
345
|
+
* 转发消息节点
|
|
346
|
+
* @param id 消息id
|
|
347
|
+
* @param user_id 消息id
|
|
348
|
+
* @param nickname 消息id
|
|
349
|
+
* @param source 消息id
|
|
350
|
+
* @param id 消息id
|
|
351
|
+
* @param id 消息id
|
|
352
|
+
* @returns { type: 'node', data: { id } }
|
|
353
|
+
*/
|
|
354
|
+
node: (id: string | number, user_id?: number | string, nickname?: string, source?: string, news?: {
|
|
355
|
+
text: string;
|
|
356
|
+
}[], summary?: string, prompt?: string, time?: string | number) => NodeSegment;
|
|
357
|
+
/**
|
|
358
|
+
* 自定义转发消息节点
|
|
359
|
+
* @param content 消息内容
|
|
360
|
+
* @returns { type: 'node', data: { content } }
|
|
361
|
+
*/
|
|
362
|
+
customNode: (content: SendMessageSegment[], user_id?: number | string, nickname?: string, source?: string, news?: {
|
|
363
|
+
text: string;
|
|
364
|
+
}[], summary?: string, prompt?: string, time?: string | number) => NodeSegment;
|
|
365
|
+
/**
|
|
366
|
+
* 转发消息
|
|
367
|
+
* @param message_id 消息id
|
|
368
|
+
* @return { type: 'forward', data: { id }}
|
|
369
|
+
*/
|
|
370
|
+
forward: (message_id: number) => ForwardSegment;
|
|
371
|
+
/**
|
|
372
|
+
* 发送名片
|
|
373
|
+
* @param type 名片类型
|
|
374
|
+
* @param id 联系人QQ号
|
|
375
|
+
* @returns { type: 'contact', data: { id } }
|
|
376
|
+
*/
|
|
377
|
+
contact: (type: "qq" | "group", id: number | string) => ContactSegment;
|
|
378
|
+
};
|
|
379
|
+
export {};
|