mirai-js 2.8.5 → 2.8.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. package/.fleet/run.json +5 -0
  2. package/dist/browser/mirai-js.js +1 -1
  3. package/dist/node/Bot.d.ts +2 -1
  4. package/dist/node/Bot.js +20 -6
  5. package/dist/node/borwserEntry.js +1 -1
  6. package/dist/node/core/recall.js +7 -1
  7. package/package.json +1 -1
  8. package/src/Bot.d.ts +2 -1
  9. package/src/Bot.js +10 -3
  10. package/src/borwserEntry.js +1 -1
  11. package/src/core/recall.js +7 -3
  12. package/1.mp3 +0 -0
  13. package/demo.ts +0 -29
  14. package/dist/node/lib/index.ts +0 -0
  15. package/index.ts +0 -38
  16. package/src/lib/index.ts +0 -0
  17. package/srcold/BaseType.d.ts +0 -419
  18. package/srcold/Bot.d.ts +0 -567
  19. package/srcold/Bot.js +0 -1208
  20. package/srcold/FileManager.js +0 -270
  21. package/srcold/Message.d.ts +0 -66
  22. package/srcold/Message.js +0 -314
  23. package/srcold/Middleware.d.ts +0 -170
  24. package/srcold/Middleware.js +0 -657
  25. package/srcold/Waiter.d.ts +0 -13
  26. package/srcold/Waiter.js +0 -24
  27. package/srcold/core/anno/deleteAnno.js +0 -43
  28. package/srcold/core/anno/getAnno.js +0 -44
  29. package/srcold/core/anno/publishAnno.js +0 -44
  30. package/srcold/core/auth.js +0 -40
  31. package/srcold/core/fs/deleteGroupFile.js +0 -45
  32. package/srcold/core/fs/getGroupFileInfo.js +0 -46
  33. package/srcold/core/fs/getGroupFileList.js +0 -47
  34. package/srcold/core/fs/makeGroupDir.js +0 -45
  35. package/srcold/core/fs/moveGroupFile.js +0 -47
  36. package/srcold/core/fs/renameGroupFile.js +0 -44
  37. package/srcold/core/fs/uploadGroupFIle.js +0 -58
  38. package/srcold/core/getFriendList.js +0 -37
  39. package/srcold/core/getGroupConfig.js +0 -37
  40. package/srcold/core/getGroupList.js +0 -37
  41. package/srcold/core/getMemberInfo.js +0 -41
  42. package/srcold/core/getMemberList.js +0 -49
  43. package/srcold/core/getSessionConfig.js +0 -39
  44. package/srcold/core/getUserProfile.js +0 -40
  45. package/srcold/core/messageFromId.js +0 -40
  46. package/srcold/core/mute.js +0 -41
  47. package/srcold/core/muteAll.js +0 -39
  48. package/srcold/core/quitGroup.js +0 -40
  49. package/srcold/core/recall.js +0 -39
  50. package/srcold/core/releaseSession.js +0 -41
  51. package/srcold/core/removeFriend.js +0 -40
  52. package/srcold/core/removeMember.js +0 -42
  53. package/srcold/core/responseBotInvitedJoinGroupRequest.js +0 -46
  54. package/srcold/core/responseFirendRequest.js +0 -45
  55. package/srcold/core/responseMemberJoinRequest.js +0 -47
  56. package/srcold/core/sendCommand.js +0 -41
  57. package/srcold/core/sendFriendMessage.js +0 -43
  58. package/srcold/core/sendGroupMessage.js +0 -43
  59. package/srcold/core/sendImageMessage.js +0 -4
  60. package/srcold/core/sendNudge.js +0 -43
  61. package/srcold/core/sendTempMessage.js +0 -55
  62. package/srcold/core/setEssence.js +0 -44
  63. package/srcold/core/setGroupConfig.js +0 -58
  64. package/srcold/core/setMemberAdmin.js +0 -44
  65. package/srcold/core/setMemberInfo.js +0 -48
  66. package/srcold/core/setSessionConfig.js +0 -41
  67. package/srcold/core/startListeningBrowser.js +0 -62
  68. package/srcold/core/startListeningNode.js +0 -74
  69. package/srcold/core/stopListeningBrowser.js +0 -34
  70. package/srcold/core/stopListeningNode.js +0 -34
  71. package/srcold/core/unmute.js +0 -40
  72. package/srcold/core/unmuteAll.js +0 -39
  73. package/srcold/core/uploadImage.js +0 -55
  74. package/srcold/core/uploadVoice.js +0 -54
  75. package/srcold/core/verify.js +0 -41
  76. package/srcold/index.d.ts +0 -10
  77. package/srcold/index.js +0 -21
  78. package/srcold/interface.js +0 -20
  79. package/srcold/polyfill/URL.js +0 -5
  80. package/srcold/polyfill/wsListener.js +0 -6
  81. package/srcold/typeHelpers.d.ts +0 -2
  82. package/srcold/util/errCode.js +0 -23
  83. package/srcold/util/errorHandler.js +0 -24
  84. package/srcold/util/getInvalidParamsString.js +0 -12
  85. package/srcold/util/isBrowserEnv.js +0 -3
  86. package/srcold/util/random.js +0 -6
package/srcold/Bot.js DELETED
@@ -1,1208 +0,0 @@
1
- // 引入核心功能,前缀下划线时为了与方法名区别 (视觉上的区别)
2
- const _releaseSession = require('./core/releaseSession');
3
- const _verify = require('./core/auth');
4
- const _bind = require('./core/verify');
5
- const _sendCommand = require('./core/sendCommand');
6
- const _sendFriendMessage = require('./core/sendFriendMessage');
7
- const _sendGroupMessage = require('./core/sendGroupMessage');
8
- const _sendTempMessage = require('./core/sendTempMessage');
9
- const _sendNudge = require('./core/sendNudge');
10
- const _getSessionConfig = require('./core/getSessionConfig');
11
- const _setSessionConfig = require('./core/setSessionConfig');
12
- const _uploadImage = require('./core/uploadImage');
13
- const _uploadVoice = require('./core/uploadVoice');
14
- const _getFriendList = require('./core/getFriendList');
15
- const _getGroupList = require('./core/getGroupList');
16
- const _getMemberList = require('./core/getMemberList');
17
- const _getMemberInfo = require('./core/getMemberInfo');
18
- const _getUserProfile = require('./core/getUserProfile');
19
- const _setMemberInfo = require('./core/setMemberInfo');
20
- const _setMemberAdmin = require('./core/setMemberAdmin');
21
- const _getAnnoList = require('./core/anno/getAnno');
22
- const _publishAnno = require('./core/anno/publishAnno');
23
- const _deleteAnno = require('./core/anno/deleteAnno');
24
- const _recall = require('./core/recall');
25
- const _mute = require('./core/mute');
26
- const _muteAll = require('./core/muteAll');
27
- const _unmute = require('./core/unmute');
28
- const _unmuteAll = require('./core/unmuteAll');
29
- const _removeMember = require('./core/removeMember');
30
- const _removeFriend = require('./core/removeFriend');
31
- const _quitGroup = require('./core/quitGroup');
32
- const _getGroupConfig = require('./core/getGroupConfig');
33
- const _setGroupConfig = require('./core/setGroupConfig');
34
- const _setEssence = require('./core/setEssence');
35
- const _messageFromId = require('./core/messageFromId');
36
- const { wsStartListening: _startListening, wsStopListening: _stopListening } = require('./polyfill/wsListener');
37
-
38
- // 其他
39
- const random = require('./util/random')(0, 2E16);
40
- const getInvalidParamsString = require('./util/getInvalidParamsString');
41
- const { Waiter } = require('./Waiter');
42
- const { FileManager } = require('./FileManager');
43
- const { errCodeEnum } = require('./util/errCode');
44
- const { isBrowserEnv } = require('./util/isBrowserEnv');
45
-
46
- const fs = isBrowserEnv() ? null : require('fs');
47
- const { promisify } = isBrowserEnv() ? { promisify: null } : require('util');
48
-
49
- // 扩展接口
50
- const { MessageChainGetable, BotConfigGetable } = require('./interface');
51
-
52
- /**
53
- * @field config 包含 baseUrl verifyKey qq
54
- * @field eventProcessorMap 事件处理器 map
55
- * @field wsConnection 建立连接的 WebSocket 实例
56
- * @field waiter 内部类单例,提供同步 io 机制
57
- */
58
- class Bot extends BotConfigGetable {
59
- constructor() {
60
- super();
61
- this.waiter = new Waiter(this);
62
- this.config = undefined;
63
- this.eventProcessorMap = {};
64
- this.wsConnection = undefined;
65
- }
66
-
67
- /**
68
- * 实现 BotConfigGetable 接口
69
- */
70
- getBaseUrl() { return this.config.baseUrl; }
71
- getQQ() { return this.config.qq; }
72
- getVerifyKey() { return this.config.verifyKey; }
73
- getSessionKey() { return this.config.sessionKey; }
74
-
75
- /**
76
- * @description 连接到 mirai-api-http,并开启一个会话,重复调用意为重建会话
77
- * open 方法 1. 建立会话 2. 绑定 qq 3. 与服务端建立 WebSocket 连接
78
- * @param {string} baseUrl 必选,mirai-api-http server 的地址
79
- * @param {string} verifyKey 必选,mirai-api-http server 设置的 verifyKey
80
- * @param {number} qq 必选,欲绑定的 qq 号,需要确保该 qq 号已在 mirai-console 登陆
81
- * @param {boolean} singleMode 可选,mirai-api-http server 是否启用了 singleMode
82
- * @returns {void}
83
- */
84
- async open({ baseUrl, qq, verifyKey, singleMode } = {}) {
85
- // 若 config 存在,则认为该对象已经 open 过
86
- // ,此处应该先令对象回到初始状态,然后重建会话
87
- if (this.config) {
88
- await this.close({ keepProcessor: true, keepConfig: true });
89
- }
90
-
91
- // 设置对象状态
92
- // 若开发者重复调用 open,仅更新已提供的值
93
- this.config = {
94
- baseUrl: this.config?.baseUrl ?? baseUrl,
95
- qq: this.config?.qq ?? qq,
96
- verifyKey: this.config?.verifyKey ?? verifyKey,
97
- sessionKey: this.config?.sessionKey ?? '',
98
- };
99
-
100
- // 事件处理器 map
101
- // 如果重复调用 open 则保留事件处理器
102
- this.eventProcessorMap = this.eventProcessorMap ?? {};
103
-
104
- // 需要使用的参数
105
- ({ baseUrl, qq, verifyKey } = this.config);
106
-
107
- // 检查参数
108
- if (!this.config.baseUrl || !this.config.qq || !this.config.verifyKey) {
109
- throw new Error(`open 缺少必要的 ${getInvalidParamsString({
110
- baseUrl, qq, verifyKey,
111
- })} 参数`);
112
- }
113
-
114
- // 创建会话
115
- const sessionKey = this.config.sessionKey = await _verify({ baseUrl, verifyKey });
116
-
117
- // 绑定到一个 qq, 若开启了 singleMode 则需要跳过绑定
118
- !singleMode && await _bind({ baseUrl, sessionKey, qq });
119
-
120
- // 配置服务端 websocket 状态
121
- // await _setSessionConfig({ baseUrl, sessionKey, enableWebsocket: true });
122
-
123
- // 开始监听事件
124
- await this.__wsListen();
125
-
126
- }
127
-
128
- /**
129
- * @private
130
- * @description 监听 ws 消息
131
- */
132
- async __wsListen() {
133
- const { baseUrl, sessionKey, verifyKey } = this.config;
134
- this.wsConnection = await _startListening({
135
- baseUrl,
136
- sessionKey,
137
- verifyKey,
138
- message: data => {
139
- // 如果当前到达的事件拥有处理器,则依次调用所有该事件的处理器
140
- if (data.type in this.eventProcessorMap) {
141
- data.bot = this;
142
- return Object.values(this.eventProcessorMap[data.type])
143
- .forEach(processor => processor(data));
144
- }
145
- },
146
- error: err => {
147
- const type = 'error';
148
- if (type in this.eventProcessorMap) {
149
- err.bot = this;
150
- return Object.values(this.eventProcessorMap[type])
151
- .forEach(processor => processor(err));
152
- }
153
- try {
154
- console.log(`ws error\n${JSON.stringify(err)}`);
155
- } catch (error) { } // eslint-disable-line no-empty
156
- },
157
- close: (obj) => {
158
- const type = 'close';
159
- if (type in this.eventProcessorMap) {
160
- obj.bot = this;
161
- return Object.values(this.eventProcessorMap[type])
162
- .forEach(processor => processor(obj));
163
- }
164
- try {
165
- console.log(`ws close\n${JSON.stringify(obj)}`);
166
- } catch (error) { }// eslint-disable-line no-empty
167
- },
168
- unexpectedResponse: (obj) => {
169
- const type = 'unexpected-response';
170
- if (type in this.eventProcessorMap) {
171
- obj.bot = this;
172
- return Object.values(this.eventProcessorMap[type])
173
- .forEach(processor => processor(obj));
174
- }
175
- try {
176
- console.log(`ws unexpectedResponse\n${JSON.stringify(obj)}`);
177
- } catch (error) { }// eslint-disable-line no-empty
178
- }
179
- });
180
- }
181
-
182
-
183
- /**
184
- * @description 关闭会话
185
- * @param {boolean} keepProcessor 可选,是否保留事件处理器,默认值为 false,不保留
186
- * @param {boolean} keepConfig 可选,是否保留 session baseUrl qq verifyKey,默认值为 false,不保留
187
- * @returns {void}
188
- */
189
- async close({ keepProcessor = false, keepConfig = false } = {}) {
190
- // 检查对象状态
191
- if (!this.config) {
192
- throw new Error('close 请先调用 open,建立一个会话');
193
- }
194
-
195
- // 需要使用的参数
196
- const { baseUrl, sessionKey, qq } = this.config;
197
-
198
- // 关闭 ws 连接
199
- await _stopListening(this.wsConnection);
200
-
201
- // 释放会话
202
- await _releaseSession({ baseUrl, sessionKey, qq });
203
-
204
- // 初始化对象状态
205
- if (!keepProcessor) {
206
- this.eventProcessorMap = {};
207
- }
208
- if (!keepConfig) {
209
- this.config = undefined;
210
- }
211
- this.wsConnection = undefined;
212
- }
213
-
214
- /**
215
- * ! messageChain 将在未来被移除
216
- * @description 向 qq 好友 或 qq 群发送消息,若同时提供,则优先向好友发送消息
217
- * @param {boolean} temp 可选,是否是临时会话,默认为 false
218
- * @param {number} friend 二选一,好友 qq 号
219
- * @param {number} group 二选一,群号
220
- * @param {number} quote 可选,消息引用,使用发送时返回的 messageId
221
- * @param {Message} message 必选,Message 实例或 MessageType 数组
222
- * @returns {number} messageId
223
- */
224
- async sendMessage({ temp = false, friend, group, quote, message, messageChain }) {
225
- // 检查对象状态
226
- if (!this.config) {
227
- throw new Error('sendMessage 请先调用 open,建立一个会话');
228
- }
229
-
230
- // 检查参数
231
- if (!friend && !group | !message && !messageChain) {
232
- throw new Error(`sendMessage 缺少必要的 ${getInvalidParamsString({
233
- 'friend 或 group': friend || group,
234
- 'message 或 messageChain': message || messageChain,
235
- })} 参数`);
236
- }
237
-
238
- if (messageChain) {
239
- console.log('warning: 现在 sendMessage 方法的 message 参数可以同时接收 Message 实例或 messageChain,messageChain 参数将在未来被移除');
240
- }
241
-
242
- // 需要使用的参数
243
- const { baseUrl, sessionKey } = this.config;
244
-
245
- // 处理 message,兼容存在 messageChain 参数的版本
246
- messageChain = messageChain ?? message;
247
-
248
- if (messageChain instanceof MessageChainGetable) {
249
- messageChain = messageChain.getMessageChain();
250
- } else if (typeof messageChain === 'string') {
251
- messageChain = [{
252
- type: 'Plain',
253
- text: messageChain,
254
- }];
255
- }
256
-
257
- // 根据 temp、friend、group 参数的情况依次调用
258
- if (temp) {
259
- // 临时会话的接口,好友和群是在一起的,在内部做了参数判断并抛出异常
260
- // 而正常的好友和群的发送消息接口是分开的,所以在外面做了参数判断并抛出异常,格式相同
261
- return await _sendTempMessage({
262
- baseUrl, sessionKey, qq: friend, group, quote, messageChain
263
- });
264
- } else {
265
- if (friend) {
266
- return await _sendFriendMessage({
267
- baseUrl, sessionKey, target: friend, quote, messageChain
268
- });
269
- } else if (group) {
270
- return await _sendGroupMessage({
271
- baseUrl, sessionKey, target: group, quote, messageChain
272
- });
273
- } else {
274
- throw { message: 'sendGroupMessage 缺少必要的 qq 或 group 参数' };
275
- }
276
- }
277
- }
278
-
279
- /**
280
- * @description 向好友或群成员发送戳一戳
281
- * 如果提供了 group 参数则忽略 friend
282
- * mirai-api-http-v1.10.1 feature
283
- * @param {number} friend 二选一,好友 qq 号
284
- * @param {number} group 二选一,群成员所在群
285
- * @param {number} target 必选,目标 qq 号
286
- */
287
- async sendNudge({ friend, group, target }) {
288
- // 检查对象状态
289
- if (!this.config) {
290
- throw new Error('sendNudge 请先调用 open,建立一个会话');
291
- }
292
-
293
- // 检查参数
294
- if (!((group || friend) && target)) {
295
- throw new Error(`sendNudge 缺少必要的 ${getInvalidParamsString({
296
- 'group 或 friend': group || friend,
297
- 'target': target,
298
- })} 参数`);
299
- }
300
-
301
- // 需要使用的参数
302
- const { baseUrl, sessionKey } = this.config;
303
-
304
- // 发给群成员
305
- if (group) {
306
- await _sendNudge({
307
- baseUrl, sessionKey,
308
- target,
309
- subject: group,
310
- kind: 'Group',
311
- });
312
- }
313
- // 发给好友
314
- else if (friend) {
315
- await _sendNudge({
316
- baseUrl, sessionKey,
317
- target,
318
- subject: friend,
319
- kind: 'Friend',
320
- });
321
- }
322
- }
323
-
324
- /**
325
- * @description 添加一个事件处理器
326
- * 框架维护的 WebSocket 实例会在 ws 的事件 message 下分发 Mirai http server 的消息
327
- * 回调函数 (data) => void,data 的结构取决于消息类型,详见 mirai-api-http 的文档
328
- * 而对于 ws 的其他事件 error, close, unexpectedResponse,其回调函数分别为
329
- * - 'error': (err: Error) => void
330
- * - 'close': (code: number, message: string) => void
331
- * - 'unexpected-response': (request: http.ClientRequest, response: http.IncomingMessage) => void
332
- * @param {string | string[]} eventType 必选,事件类型
333
- * @param {function} callback 必选,回调函数
334
- * @returns {number | string[]} 事件处理器的标识,用于移除该处理器
335
- */
336
- on(eventType, callback) {
337
- // 检查对象状态
338
- if (!this.config) {
339
- throw new Error('on 请先调用 open,建立一个会话');
340
- }
341
-
342
- // 检查参数
343
- if (!eventType || !callback) {
344
- throw new Error(`on 缺少必要的 ${getInvalidParamsString({ eventType, callback })} 参数`);
345
-
346
- }
347
-
348
- // 适配 eventType 数组
349
- if (Array.isArray(eventType)) {
350
- return eventType.map(event => this.on(event, callback));
351
- }
352
-
353
- // 为没有任何事件处理器的事件生成一个空对象 (空对象 {},而不是 null)
354
- if (!(eventType in this.eventProcessorMap)) {
355
- this.eventProcessorMap[eventType] = {};
356
- }
357
-
358
- // 生成一个唯一的 handle,作为当前
359
- // processor 的标识,用于移除该处理器
360
- let handle = random();
361
- while (handle in this.eventProcessorMap[eventType]) {
362
- handle = random();
363
- }
364
-
365
- // processor
366
- // 每个事件对应多个 processor,这些 processor 和
367
- // handle 分别作为 value 和 key 包含在一个大对象中
368
- let processor = callback;
369
-
370
- // 添加事件处理器
371
- this.eventProcessorMap[eventType][handle] = processor;
372
- return handle;
373
- }
374
-
375
- /**
376
- * @description 添加一个一次性事件处理器,回调一次后自动移除
377
- * @param {string | string[]} eventType 必选,事件类型
378
- * @param {function} callback 必选,回调函数
379
- * @param {boolean} strict 可选,是否严格检测调用,由于消息可能会被中间件拦截
380
- * 当为 true 时,只有开发者的处理器结束后才会移除该处理器
381
- * 当为 false 时,即使消息被拦截,也会移除该处理器
382
- * @returns {void}
383
- */
384
- one(eventType, callback, strict = false) {
385
- // 检查对象状态
386
- if (!this.config) {
387
- throw new Error('one 请先调用 open,建立一个会话');
388
- }
389
-
390
- // 检查参数
391
- if (!eventType || !callback) {
392
- throw new Error(`one 缺少必要的 ${getInvalidParamsString({ eventType, callback })} 参数`);
393
-
394
- }
395
-
396
- // 适配 eventType 数组
397
- if (Array.isArray(eventType)) {
398
- eventType.map(event => this.one(event, callback));
399
- return;
400
- }
401
-
402
- // 为没有任何事件处理器的事件生成一个空对象 (空对象 {},而不是 null)
403
- if (!(eventType in this.eventProcessorMap)) {
404
- this.eventProcessorMap[eventType] = {};
405
- }
406
-
407
- // 生成一个唯一的 handle,作为当前
408
- // processor 的标识,用于移除该处理器
409
- let handle = random();
410
- while (handle in this.eventProcessorMap[eventType]) {
411
- handle = random();
412
- }
413
-
414
- // processor
415
- // 每个事件对应多个 processor,这些 processor 和 h
416
- // andle 分别作为 value 和 key 包含在一个大对象中
417
- const processor = async (data) => {
418
- if (strict) {
419
- // 严格检测回调
420
- // 当开发者的处理器结束后才移除该处理器,这里等待异步回调
421
- await callback(data);
422
- if (handle in this.eventProcessorMap[eventType]) {
423
- delete this.eventProcessorMap[eventType][handle];
424
- }
425
- } else {
426
- // 不严格检测,直接移除处理器
427
- // 从 field eventProcessorMap 中移除 handle 指定的事件处理器
428
- if (handle in this.eventProcessorMap[eventType]) {
429
- delete this.eventProcessorMap[eventType][handle];
430
- }
431
-
432
- // 调用开发者提供的回调
433
- callback(data);
434
- }
435
- };
436
-
437
- // 添加事件处理器
438
- this.eventProcessorMap[eventType][handle] = processor;
439
- }
440
-
441
- /**
442
- * @description 移除一个事件处理器
443
- * @param {string} eventType 必选,事件类型
444
- * @param {number | number[]} handle
445
- * 可选,事件处理器标识(或数组),由 on 方法返回,未提供时将移除该事件下的所有处理器
446
- * @returns {void}
447
- */
448
- off(eventType, handle) {
449
- // 检查对象状态
450
- if (!this.config) {
451
- throw new Error('off 请先调用 open,建立一个会话');
452
- }
453
-
454
- // 检查参数
455
- if (!eventType) {
456
- throw new Error('off 缺少必要的 eventType 参数');
457
- }
458
-
459
-
460
- if (handle) {
461
- // 从 field eventProcessorMap 中移除 handle 指定的事件处理器
462
- if (handle.forEach) {
463
- // 可迭代
464
- handle.forEach(hd => {
465
- if (hd in this.eventProcessorMap[eventType]) {
466
- delete this.eventProcessorMap[eventType][hd];
467
- }
468
- });
469
- } else {
470
- // 不可迭代,认为是单个标识
471
- if (handle in this.eventProcessorMap[eventType]) {
472
- delete this.eventProcessorMap[eventType][handle];
473
- }
474
- }
475
- } else {
476
- // 未提供 handle,移除所有
477
- if (eventType in this.eventProcessorMap) {
478
- delete this.eventProcessorMap[eventType];
479
- }
480
- }
481
-
482
- }
483
-
484
- /**
485
- * @description 移除所有事件处理器
486
- * @param {string | string[]} eventType 可选,事件类型(或数组)
487
- * @returns {void}
488
- */
489
- offAll(eventType) {
490
- // 检查对象状态
491
- if (!this.config) {
492
- throw new Error('offAll 请先调用 open,建立一个会话');
493
- }
494
-
495
- if (eventType) {
496
- // 提供了特定的 eventType 参数
497
- if (eventType.forEach) {
498
- // 可迭代
499
- eventType.forEach(evtType => {
500
- if (evtType in this.eventProcessorMap) {
501
- delete this.eventProcessorMap[evtType];
502
- }
503
- });
504
- } else {
505
- // 不可迭代
506
- if (eventType in this.eventProcessorMap) {
507
- delete this.eventProcessorMap[eventType];
508
- }
509
- }
510
- } else {
511
- // 未提供参数,全部移除
512
- this.eventProcessorMap = {};
513
- }
514
- }
515
-
516
- /**
517
- * @description 获取 config
518
- * @returns {Object} 结构 { cacheSize, enableWebsocket }
519
- */
520
- async getSessionConfig() {
521
- // 检查对象状态
522
- if (!this.config) {
523
- throw new Error('getConfig 请先调用 open,建立一个会话');
524
- }
525
-
526
- const { baseUrl, sessionKey } = this.config;
527
- return await _getSessionConfig({ baseUrl, sessionKey });
528
- }
529
-
530
- /**
531
- * @description 设置 config
532
- * @param {number} cacheSize 可选,插件缓存大小
533
- * @param {boolean} enableWebsocket 可选,websocket 状态
534
- * @returns {void}
535
- */
536
- async setSessionConfig({ cacheSize, enableWebsocket }) {
537
- // 检查对象状态
538
- if (!this.config) {
539
- throw new Error('setConfig 请先调用 open,建立一个会话');
540
- }
541
-
542
- const { baseUrl, sessionKey } = this.config;
543
- await _setSessionConfig({ baseUrl, sessionKey, cacheSize, enableWebsocket });
544
- }
545
-
546
- /**
547
- * @description 撤回由 messageId 确定的消息
548
- * @param {number} messageId 欲撤回消息的 messageId
549
- * @returns {void}
550
- */
551
- async recall({ messageId }) {
552
- // 检查对象状态
553
- if (!this.config) {
554
- throw new Error('recall 请先调用 open,建立一个会话');
555
- }
556
-
557
- // 检查参数
558
- if (!messageId) {
559
- throw new Error('recall 缺少必要的 messageId 参数');
560
- }
561
-
562
- const { baseUrl, sessionKey } = this.config;
563
- // 撤回消息
564
- await _recall({ baseUrl, sessionKey, target: messageId });
565
- }
566
-
567
- /**
568
- * FIXME: type 指定为 'friend' 或 'temp' 时发送的图片显示红色感叹号,无法加载,group 则正常
569
- * @description 上传图片至服务器,返回指定 type 的 imageId,url,及 path
570
- * @param {string} type 可选,"friend" 或 "group" 或 "temp",默认为 "group"
571
- * @param {Buffer} img 二选一,图片二进制数据
572
- * @param {string} filename 二选一,图片文件路径
573
- * @returns {Object} 结构 { imageId, url, path }
574
- */
575
- async uploadImage({ type = 'group', img, filename }) {
576
- if (isBrowserEnv()) { throw new Error('uploadImage 在浏览器环境下不可用'); }
577
- // 检查对象状态
578
- if (!this.config) {
579
- throw new Error('uploadImage 请先调用 open,建立一个会话');
580
- }
581
-
582
- // 检查参数
583
- if (isBrowserEnv() && filename) {
584
- throw new Error('uploadImage 浏览器端不支持 filename 参数');
585
- }
586
- if (!img && !filename) {
587
- throw new Error('uploadImage 缺少必要的 img 或 filename 参数');
588
- }
589
-
590
- // 若传入 filename 则统一转换为 Buffer
591
- if (filename) {
592
- // 优先使用 img 的原值
593
- img = img ?? await promisify(fs.readFile)(filename);
594
- }
595
-
596
- const { baseUrl, sessionKey } = this.config;
597
- return await _uploadImage({ baseUrl, sessionKey, type, img });
598
- }
599
-
600
- /**
601
- * FIXME: 目前该功能返回的 voiceId 无法正常使用,无法
602
- * 发送给好友,提示 message is empty,发到群里则是 1s 的无声语音
603
- * @description 上传语音至服务器,返回 voiceId, url 及 path
604
- * @param {string} type TODO: 目前仅支持 "group",请忽略该参数
605
- * @param {Buffer} voice 二选一,语音二进制数据
606
- * @param {string} filename 二选一,语音文件路径
607
- * @returns {Object} 结构 { voiceId, url, path }
608
- */
609
- async uploadVoice({ type = 'group', voice, filename }) {
610
- if (isBrowserEnv()) { throw new Error('uploadVoice 在浏览器环境下不可用'); }
611
- // 检查对象状态
612
- if (!this.config) {
613
- throw new Error('uploadVoice 请先调用 open,建立一个会话');
614
- }
615
-
616
- // 检查参数
617
- if (isBrowserEnv() && filename) {
618
- throw new Error('uploadVoice 浏览器端不支持 filename 参数');
619
- }
620
- if (!voice && !filename) {
621
- throw new Error('uploadVoice 缺少必要的 voice 或 filename 参数');
622
- }
623
-
624
- // 若传入 filename 则统一转换为 Buffer
625
- if (filename) {
626
- // 优先使用 img 的原值
627
- voice = voice ?? await promisify(fs.readFile)(filename);
628
- }
629
-
630
- const { baseUrl, sessionKey } = this.config;
631
- return await _uploadVoice({ baseUrl, sessionKey, type, voice });
632
- }
633
-
634
- /**
635
- * @description 获取好友列表
636
- * @returns {Object[]} 结构 array[...{ id, name, remark }]
637
- */
638
- async getFriendList() {
639
- // 检查对象状态
640
- if (!this.config) {
641
- throw new Error('getFriendList 请先调用 open,建立一个会话');
642
- }
643
-
644
- const { baseUrl, sessionKey } = this.config;
645
-
646
- // 获取列表
647
- const friendList = await _getFriendList({ baseUrl, sessionKey });
648
-
649
- // 这里希望所有列表应该具有相同的属性名
650
- friendList.map((value) => {
651
- value.name = value.nickname;
652
- delete value.nickname;
653
- });
654
- return friendList;
655
- }
656
-
657
- /**
658
- * @description 获取群列表
659
- * @returns {Object[]} 结构 array[...{ id, name, permission }]
660
- */
661
- async getGroupList() {
662
- // 检查对象状态
663
- if (!this.config) {
664
- throw new Error('getGroupList 请先调用 open,建立一个会话');
665
- }
666
-
667
- const { baseUrl, sessionKey } = this.config;
668
- return await _getGroupList({ baseUrl, sessionKey });
669
- }
670
-
671
- /**
672
- * @description 获取指定群的成员列表
673
- * @param {number} group 必选,欲获取成员列表的群号
674
- * @returns {Object[]} 结构 array[...{ id, name, permission }]
675
- */
676
- async getMemberList({ group }) {
677
- // 检查对象状态
678
- if (!this.config) {
679
- throw new Error('getMemberList 请先调用 open,建立一个会话');
680
- }
681
-
682
- // 检查参数
683
- if (!group) {
684
- throw new Error('getMemberList 缺少必要的 group 参数');
685
- }
686
-
687
- // 获取列表
688
- const { baseUrl, sessionKey } = this.config;
689
- const memberList = await _getMemberList({ baseUrl, sessionKey, target: group });
690
-
691
- // 这里希望所有列表应该具有相同的属性名
692
- memberList.map((value) => {
693
- value.name = value.memberName;
694
- delete value.group;
695
- delete value.memberName;
696
- });
697
- return memberList;
698
- }
699
-
700
- /**
701
- * @description 获取群成员信息
702
- * @param {number} group 必选,群成员所在群号
703
- * @param {number} qq 必选,群成员的 qq 号
704
- * @returns {Object}
705
- */
706
- async getMemberInfo({ group, qq }) {
707
- // 检查对象状态
708
- if (!this.config) {
709
- throw new Error('getMemberInfo 请先调用 open,建立一个会话');
710
- }
711
-
712
- // 检查参数
713
- if (!group || !qq) {
714
- throw new Error(`getMemberInfo 缺少必要的 ${getInvalidParamsString({
715
- group, qq
716
- })} 参数`);
717
- }
718
-
719
- // 获取列表
720
- const { baseUrl, sessionKey } = this.config;
721
- const memberInfo = await _getMemberInfo({
722
- baseUrl, sessionKey, target: group, memberId: qq
723
- });
724
-
725
- // 将 specialTitle 改为 title,在 setMemberInfo 也保持一致
726
- memberInfo.title = memberInfo.specialTitle;
727
- delete memberInfo.specialTitle;
728
-
729
- return memberInfo;
730
- }
731
-
732
- /**
733
- * @description 获取群成员信息
734
- * @param {number} qq 必选,用户的 qq 号
735
- * @returns {Object} 结构 { nickname, email, age, level, sign, sex }
736
- */
737
- async getUserProfile({ qq }) {
738
- // 检查对象状态
739
- if (!this.config) {
740
- throw new Error('getUserProfile 请先调用 open,建立一个会话');
741
- }
742
-
743
- // 检查参数
744
- if (!qq) {
745
- throw new Error('getUserProfile 缺少必要的 qq 参数');
746
- }
747
-
748
- const { baseUrl, sessionKey } = this.config;
749
- return await _getUserProfile({ baseUrl, sessionKey, target: qq });
750
- }
751
-
752
- /**
753
- * @description 设置群成员信息
754
- * @param {number} group 必选,群成员所在群号
755
- * @param {number} qq 必选,群成员的 qq 号
756
- * @param {string} name 可选,要设置的群名片
757
- * @param {string} title 可选,要设置的群头衔
758
- * @param {boolean} permission 可选,要设置的权限,
759
- * 使用枚举值:Bot.Permission.Admin, Bot.Permission.Member
760
- * @returns {void}
761
- */
762
- async setMemberInfo({ group, qq, name, title, permission }) {
763
- // 检查对象状态
764
- if (!this.config) {
765
- throw new Error('setMemberInfo 请先调用 open,建立一个会话');
766
- }
767
-
768
- // 检查参数
769
- if (!group || !qq) {
770
- throw new Error(`setMemberInfo 缺少必要的 ${getInvalidParamsString({
771
- group, qq
772
- })} 参数`);
773
- }
774
- if (permission != undefined
775
- && permission != Bot.groupPermission.ADMINISTRATOR
776
- && permission != Bot.groupPermission.MEMBER) {
777
- throw new Error('setMemberInfo admin 参数只能是 Bot.groupPermission.ADMINISTRATOR 或 Bot.groupPermission.Member');
778
- }
779
-
780
- // setMemberInfo
781
- const { baseUrl, sessionKey } = this.config;
782
- if (name != undefined || title != undefined) {
783
- await _setMemberInfo({
784
- baseUrl, sessionKey, target: group, memberId: qq,
785
- name, specialTitle: title,
786
- });
787
- }
788
-
789
- // setPermission
790
- if (permission != undefined) {
791
- await _setMemberAdmin({
792
- baseUrl, sessionKey, target: group, memberId: qq,
793
- assign: permission == Bot.groupPermission.ADMINISTRATOR ? true : false,
794
- });
795
- }
796
- }
797
-
798
- /**
799
- * @description 获取群公告列表迭代器
800
- * @param {number} group 必选,群号
801
- * @returns 迭代器
802
- */
803
- async *getAnnoIter({ group }) {
804
- // 检查对象状态
805
- if (!this.config) {
806
- throw new Error('getAnno 请先调用 open,建立一个会话');
807
- }
808
-
809
- // 检查参数
810
- if (!group) {
811
- throw new Error('getAnno 缺少必要的 group 参数');
812
- }
813
-
814
- // 获取列表
815
- const { baseUrl, sessionKey } = this.config;
816
- let offset = 0;
817
- let annoList = await _getAnnoList({ baseUrl, sessionKey, id: group, offset, size: 10 });
818
- while (annoList.length > 0) {
819
- for (const anno of annoList) {
820
- yield anno;
821
- }
822
-
823
- // 获取下一页
824
- offset += 10;
825
- annoList = await _getAnnoList({ baseUrl, sessionKey, id: group, offset, size: 10 });
826
- }
827
-
828
- return;
829
- }
830
-
831
- /**
832
- * @description 发布群公告
833
- * @param {number} group 必选,群号
834
- * @param {string} content 必选,公告内容
835
- * @returns {void}
836
- */
837
- async publishAnno({ group, content, pinned }) {
838
- // 检查对象状态
839
- if (!this.config) {
840
- throw new Error('publishAllo 请先调用 open,建立一个会话');
841
- }
842
-
843
- // 检查参数
844
- if (!group || !content) {
845
- throw new Error(`publishAllo 缺少必要的 ${getInvalidParamsString({
846
- group, content
847
- })} 参数`);
848
- }
849
-
850
- // 发布公告
851
- const { baseUrl, sessionKey } = this.config;
852
- await _publishAnno({ baseUrl, sessionKey, target: group, content, pinned });
853
- }
854
-
855
- /**
856
- * @description 删除群公告
857
- * @param {number} group 必选,群号
858
- * @param {string} fid 必选,公告 id
859
- * @reaturns {void}
860
- */
861
- async deleteAnno({ group, fid }) {
862
- // 检查对象状态
863
- if (!this.config) {
864
- throw new Error('deleteAnno 请先调用 open,建立一个会话');
865
- }
866
-
867
- // 检查参数
868
- if (!group || !fid) {
869
- throw new Error(`deleteAnno 缺少必要的 ${getInvalidParamsString({
870
- group, fid
871
- })} 参数`);
872
- }
873
-
874
- // 发布公告
875
- const { baseUrl, sessionKey } = this.config;
876
- await _deleteAnno({ baseUrl, sessionKey, id: group, fid });
877
- }
878
-
879
- /**
880
- * @description 禁言群成员
881
- * @param {number} group 必选,欲禁言成员所在群号
882
- * @param {number} qq 必选,欲禁言成员 qq 号
883
- * @param {number} time 必选,禁言时长,单位: s (秒)
884
- * @returns {void}
885
- */
886
- async mute({ group, qq, time }) {
887
- // 检查对象状态
888
- if (!this.config) {
889
- throw new Error('mute 请先调用 open,建立一个会话');
890
- }
891
-
892
- // 检查参数
893
- if (!group || !qq || !time) {
894
- throw new Error(`mute 缺少必要的 ${getInvalidParamsString({ group, qq, time })} 参数`);
895
- }
896
-
897
- const { baseUrl, sessionKey } = this.config;
898
- // 禁言
899
- await _mute({ baseUrl, sessionKey, target: group, memberId: qq, time });
900
- }
901
-
902
- /**
903
- * @description 全员禁言
904
- * @param {number} group 必选,欲全员禁言的群号
905
- * @returns {void}
906
- */
907
- async muteAll({ group }) {
908
- // 检查对象状态
909
- if (!this.config) {
910
- throw new Error('muteAll 请先调用 open,建立一个会话');
911
- }
912
-
913
- // 检查参数
914
- if (!group) {
915
- throw new Error('muteAll 缺少必要的 group 参数');
916
- }
917
-
918
- const { baseUrl, sessionKey } = this.config;
919
- // 禁言
920
- await _muteAll({ baseUrl, sessionKey, target: group });
921
- }
922
-
923
- /**
924
- * @description 解除禁言
925
- * @param {number} group 必选,欲解除禁言的成员所在群号
926
- * @param {number} qq 必选,欲解除禁言的成员 qq 号
927
- * @returns {void}
928
- */
929
- async unmute({ group, qq }) {
930
- // 检查对象状态
931
- if (!this.config) {
932
- throw new Error('unmute 请先调用 open,建立一个会话');
933
- }
934
-
935
- // 检查参数
936
- if (!group || !qq) {
937
- throw new Error(`unmute 缺少必要的 ${getInvalidParamsString({ group, qq })} 参数`);
938
- }
939
-
940
- const { baseUrl, sessionKey } = this.config;
941
- // 禁言
942
- await _unmute({ baseUrl, sessionKey, target: group, memberId: qq });
943
- }
944
-
945
- /**
946
- * @description 解除全员禁言
947
- * @param {number} group 必选,欲解除全员禁言的群号
948
- * @returns {void}
949
- */
950
- async unmuteAll({ group }) {
951
- // 检查对象状态
952
- if (!this.config) {
953
- throw new Error('unmute 请先调用 open,建立一个会话');
954
- }
955
-
956
- // 检查参数
957
- if (!group) {
958
- throw new Error('unmute 缺少必要的 group 参数');
959
- }
960
-
961
- const { baseUrl, sessionKey } = this.config;
962
- // 禁言
963
- await _unmuteAll({ baseUrl, sessionKey, target: group });
964
- }
965
-
966
- /**
967
- * @description 移除群成员
968
- * @param {number} group 必选,欲移除的成员所在群号
969
- * @param {number} qq 必选,欲移除的成员 qq 号
970
- * @param {string} message 可选,默认为空串 "",信息
971
- * @returns {void}
972
- */
973
- async removeMember({ group, qq, message = '' }) {
974
- // 检查对象状态
975
- if (!this.config) {
976
- throw new Error('removeMember 请先调用 open,建立一个会话');
977
- }
978
-
979
- // 检查参数
980
- if (!group || !qq) {
981
- throw new Error(`removeMember 缺少必要的 ${getInvalidParamsString({ group, qq })} 参数`);
982
- }
983
-
984
- const { baseUrl, sessionKey } = this.config;
985
- // 禁言
986
- await _removeMember({ baseUrl, sessionKey, target: group, memberId: qq, msg: message });
987
- }
988
-
989
- /**
990
- * @description 删除好友
991
- * @param {*} qq 欲删除的好友 qq 号
992
- * @returns {void}
993
- */
994
- async removeFriend({ qq }) {
995
- // 检查对象状态
996
- if (!this.config) {
997
- throw new Error('removeFriend 请先调用 open,建立一个会话');
998
- }
999
-
1000
- // 检查参数
1001
- if (!qq) {
1002
- throw new Error('removeFriend 缺少必要的 qq 参数');
1003
- }
1004
-
1005
- const { baseUrl, sessionKey } = this.config;
1006
-
1007
- // 删除好友
1008
- await _removeFriend({ baseUrl, sessionKey, target: qq });
1009
- }
1010
-
1011
- /**
1012
- * @description 移除群成员
1013
- * @param {number} group 必选,欲移除的成员所在群号
1014
- * @returns {void}
1015
- */
1016
- async quitGroup({ group }) {
1017
- // 检查对象状态
1018
- if (!this.config) {
1019
- throw new Error('quitGroup 请先调用 open,建立一个会话');
1020
- }
1021
-
1022
- // 检查参数
1023
- if (!group) {
1024
- throw new Error('quitGroup 缺少必要的 group 参数');
1025
- }
1026
-
1027
- const { baseUrl, sessionKey } = this.config;
1028
- // 禁言
1029
- await _quitGroup({ baseUrl, sessionKey, target: group });
1030
- }
1031
-
1032
- /**
1033
- * @description 获取群配置
1034
- * @param {number} group 必选,群号
1035
- * @returns {Object}
1036
- */
1037
- async getGroupConfig({ group }) {
1038
- // 检查对象状态
1039
- if (!this.config) {
1040
- throw new Error('getGroupConfig 请先调用 open,建立一个会话');
1041
- }
1042
-
1043
- // 检查参数
1044
- if (!group) {
1045
- throw new Error('getGroupConfig 缺少必要的 group 参数');
1046
- }
1047
-
1048
- const { baseUrl, sessionKey } = this.config;
1049
- return await _getGroupConfig({ baseUrl, sessionKey, target: group });
1050
- }
1051
-
1052
- /**
1053
- * @description 设置群配置
1054
- * @param {number} group 必选,群号
1055
- * @param {string} name 可选,群名
1056
- * @param {string} announcement 可选,群公告
1057
- * @param {boolean} confessTalk 可选,是否开启坦白说
1058
- * @param {boolean} allowMemberInvite 可选,是否允许群员邀请
1059
- * @param {boolean} autoApprove 可选,是否开启自动审批入群
1060
- * @param {boolean} anonymousChat 可选,是否允许匿名聊天
1061
- * @returns {void}
1062
- */
1063
- async setGroupConfig({
1064
- group,
1065
- name, announcement, confessTalk, allowMemberInvite, autoApprove, anonymousChat,
1066
- }) {
1067
- // 检查对象状态
1068
- if (!this.config) {
1069
- throw new Error('setGroupConfig 请先调用 open,建立一个会话');
1070
- }
1071
-
1072
- // 检查参数
1073
- if (!group) {
1074
- throw new Error('setGroupConfig 缺少必要的 group 参数');
1075
- }
1076
-
1077
-
1078
- const { baseUrl, sessionKey } = this.config;
1079
- await _setGroupConfig({
1080
- baseUrl, sessionKey, target: group,
1081
- name, announcement,
1082
- confessTalk,
1083
- allowMemberInvite,
1084
- autoApprove,
1085
- anonymousChat,
1086
- });
1087
- }
1088
-
1089
- /**
1090
- * @description 文件管理器的工厂方法
1091
- * @param {number} group 群号
1092
- * @returns {FileManager} 文件管理器实例
1093
- */
1094
- fileManager({ group }) {
1095
- return new FileManager({ bot: this, group });
1096
- }
1097
-
1098
- /**
1099
- * @description 设置群精华消息
1100
- * @param {number} messageId 必选,消息 id
1101
- * @returns {void}
1102
- */
1103
- async setEssence({ messageId }) {
1104
- // 检查对象状态
1105
- if (!this.config) {
1106
- throw new Error('setEssence 请先调用 open,建立一个会话');
1107
- }
1108
-
1109
- // 检查参数
1110
- if (!messageId) {
1111
- throw new Error('setEssence 缺少必要的 messageId 参数');
1112
- }
1113
-
1114
- const { baseUrl, sessionKey } = this.config;
1115
- await _setEssence({ baseUrl, sessionKey, target: messageId });
1116
- }
1117
-
1118
- /**
1119
- * @description 向 mirai-console 发送指令
1120
- * @param {string[]} command 必选,指令和参数
1121
- * @returns {Object} 结构 { message },注意查看 message 的内容,已知的问题:
1122
- * 'Login failed: Mirai 无法完成滑块验证. 使用协议 ANDROID_PHONE 强制要求滑块验证,
1123
- * 请更换协议后重试. 另请参阅: https://github.com/project-mirai/mirai-login-solver-selenium'
1124
- */
1125
- async sendCommand({ command }) {
1126
- // 检查对象状态
1127
- if (!this.config) {
1128
- throw new Error('setEssence 请先调用 open,建立一个会话');
1129
- }
1130
-
1131
- // 检查参数
1132
- if (!command) {
1133
- throw new Error(`sendCommand 缺少必要的 ${getInvalidParamsString({ command })} 参数`);
1134
- }
1135
-
1136
- const { Message } = require('./Message');
1137
- const { baseUrl, sessionKey } = this.config;
1138
- return await _sendCommand({
1139
- baseUrl, sessionKey,
1140
- command: command
1141
- .map((v) => v?.toString() ?? '')
1142
- .reduce((acc, cur) => acc.addText(cur), new Message)
1143
- .messageChain
1144
- });
1145
- }
1146
-
1147
- /**
1148
- * @description 通过 messageId 获取消息
1149
- * @param {number} target 可选, 目标 qq 号/群号, mah v2.6.0+ 新增该参数
1150
- * @param {number} messageId 必选, 消息 id
1151
- * @returns {Object} 结构 { type, messageChain, sender }
1152
- */
1153
- async getMessageById({ messageId, target }) {
1154
- // 检查对象状态
1155
- if (!this.config) {
1156
- throw new Error('getMessageById 请先调用 open,建立一个会话');
1157
- }
1158
-
1159
- // 检查参数
1160
- if (!messageId) {
1161
- throw new Error('getMessageById 缺少必要的 messageId 参数');
1162
- }
1163
-
1164
- const { baseUrl, sessionKey } = this.config;
1165
- return await _messageFromId({ baseUrl, sessionKey, target, messageId });
1166
- }
1167
-
1168
- /**
1169
- * @description 检测该账号是否已经在 mirai-console 登录
1170
- * @param {string} baseUrl 必选,mirai-api-http server 的地址
1171
- * @param {string} verifyKey 必选,mirai-api-http server 设置的 verifyKey
1172
- * @param {number} qq 必选,qq 号
1173
- * @returns
1174
- */
1175
- static async isBotLoggedIn({ baseUrl, verifyKey, qq }) {
1176
- // 检查参数
1177
- if (!baseUrl || !verifyKey || !qq) {
1178
- throw new Error(`isBotLoggedIn 缺少必要的 ${getInvalidParamsString({ baseUrl, verifyKey, qq })} 参数`);
1179
- }
1180
-
1181
- const sessionKey = await _verify({ baseUrl, verifyKey });
1182
- const { code } = await _bind({ baseUrl, sessionKey, qq, throwable: false });
1183
-
1184
- if (code == errCodeEnum.BOT_NOT_FOUND) {
1185
- return false;
1186
- } else {
1187
- _releaseSession({ baseUrl, sessionKey, qq });
1188
- return true;
1189
- }
1190
- }
1191
-
1192
- }
1193
-
1194
-
1195
- // 静态属性: 群成员的权限
1196
- Bot.groupPermission = {
1197
- get OWNER() {
1198
- return 'OWNER';
1199
- },
1200
- get ADMINISTRATOR() {
1201
- return 'ADMINISTRATOR';
1202
- },
1203
- get MEMBER() {
1204
- return 'MEMBER';
1205
- },
1206
- };
1207
-
1208
- module.exports = { Bot };