onebots 0.1.4 → 0.1.6

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/lib/onebot.js CHANGED
@@ -22,8 +22,7 @@ class OneBot extends events_1.EventEmitter {
22
22
  super();
23
23
  this.app = app;
24
24
  this.uin = uin;
25
- if (!Array.isArray(config))
26
- config = new Array(config);
25
+ config = [].concat(config);
27
26
  this.config = config.map(c => {
28
27
  if (c.password)
29
28
  this.password = c.password;
@@ -31,9 +30,9 @@ class OneBot extends events_1.EventEmitter {
31
30
  c.version = 'V11';
32
31
  switch (c.version) {
33
32
  case 'V11':
34
- return (0, utils_1.deepMerge)(this.app.config.general.V11, c);
33
+ return (0, utils_1.deepMerge)((0, utils_1.deepClone)(this.app.config.general.V11), c);
35
34
  case 'V12':
36
- return (0, utils_1.deepMerge)(this.app.config.general.V12, c);
35
+ return (0, utils_1.deepMerge)((0, utils_1.deepClone)(this.app.config.general.V12), c);
37
36
  default:
38
37
  throw new Error('不支持的oneBot版本:' + c.version);
39
38
  }
package/lib/server/app.js CHANGED
@@ -123,6 +123,12 @@ class App extends koa_1.default {
123
123
  for (const oneBot of this.oneBots) {
124
124
  oneBot.start();
125
125
  }
126
+ process.on('uncaughtException', (e) => {
127
+ console.error('uncaughtException', e);
128
+ });
129
+ process.on('unhandledRejection', (e) => {
130
+ console.error('unhandledRejection', e);
131
+ });
126
132
  this.httpServer.listen(this.config.port);
127
133
  this.router.get('/list', (ctx) => {
128
134
  ctx.body = this.oneBots.map(bot => {
@@ -31,7 +31,7 @@ export declare class CommonAction {
31
31
  getVersion(this: V12): {
32
32
  impl: string;
33
33
  platform: string;
34
- version: string;
34
+ version: any;
35
35
  onebot_version: string;
36
36
  };
37
37
  callLogin(this: V12, func: string, ...args: any[]): Promise<unknown>;
@@ -2,8 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CommonAction = void 0;
4
4
  const icqq_1 = require("icqq");
5
- const onebot_1 = require("../../../onebot");
6
5
  const utils_1 = require("../../../utils");
6
+ const onebot_1 = require("../../../onebot");
7
+ const utils_2 = require("../../../utils");
7
8
  class CommonAction {
8
9
  sendMessage() { }
9
10
  /**
@@ -51,7 +52,7 @@ class CommonAction {
51
52
  return {
52
53
  impl: 'onebots',
53
54
  platform: 'qq',
54
- version: '0.0.15',
55
+ version: utils_1.version,
55
56
  onebot_version: '12'
56
57
  };
57
58
  }
@@ -114,9 +115,9 @@ class CommonAction {
114
115
  });
115
116
  }
116
117
  getSupportedActions() {
117
- return [...new Set((0, utils_1.getProperties)(this.action))].filter(key => {
118
+ return [...new Set((0, utils_2.getProperties)(this.action))].filter(key => {
118
119
  return key !== 'constructor';
119
- }).map(utils_1.toLine);
120
+ }).map(utils_2.toLine);
120
121
  }
121
122
  }
122
123
  exports.CommonAction = CommonAction;
@@ -1,8 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FriendAction = void 0;
4
- const index_1 = require("../index");
5
- const utils_1 = require("../../../utils");
4
+ const utils_1 = require("../../../service/V12/action/utils");
6
5
  class FriendAction {
7
6
  getUserInfo(user_id) {
8
7
  return this.client.getStrangerInfo(user_id);
@@ -17,25 +16,11 @@ class FriendAction {
17
16
  * @param message_id {string} 引用的消息ID
18
17
  */
19
18
  async sendPrivateMsg(user_id, message, message_id) {
20
- const forward = message.find(e => e.type === 'node');
21
- if (forward)
22
- (0, utils_1.remove)(message, forward);
23
- let quote = message.find(e => e.type === 'reply');
24
- if (quote)
25
- (0, utils_1.remove)(message, quote);
26
- const element = index_1.V12.fromSegment(message);
27
- if (forward)
28
- element.unshift(await this.client.makeForwardMsg(forward.data.message.map(segment => {
29
- return {
30
- message: index_1.V12.fromSegment([segment]),
31
- user_id: forward.data.user_id,
32
- nickname: forward.data.user_name,
33
- time: forward.data.time
34
- };
35
- })));
36
- if (quote && !message_id)
37
- message_id = quote.data.message_id;
38
- return await this.client.sendPrivateMsg(user_id, element, message_id ? await this.client.getMsg(message_id) : undefined);
19
+ let { element, quote_id } = await utils_1.processMessage.apply(this.client, [message, message_id]);
20
+ element = await utils_1.processMusic.apply(this.client, ['friend', user_id, element]);
21
+ if (!element.length)
22
+ return;
23
+ return await this.client.sendPrivateMsg(user_id, element, quote_id ? await this.client.getMsg(quote_id) : undefined);
39
24
  }
40
25
  }
41
26
  exports.FriendAction = FriendAction;
@@ -14,6 +14,16 @@ export declare class GroupAction {
14
14
  * @param reject_add_request {boolean} 是否禁止此人加群请求
15
15
  */
16
16
  setGroupKick(this: V12, group_id: number, user_id: number, reject_add_request?: boolean): Promise<boolean>;
17
+ /**
18
+ * 设置群精华
19
+ * @param message_id
20
+ */
21
+ setEssenceMessage(this: V12, message_id: string): Promise<string>;
22
+ /**
23
+ * 移除群精华
24
+ * @param message_id
25
+ */
26
+ deleteEssenceMessage(this: V12, message_id: string): Promise<string>;
17
27
  /**
18
28
  * 群禁言指定人
19
29
  * @param group_id {number} 群id
@@ -1,8 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GroupAction = void 0;
4
- const index_1 = require("../index");
5
- const utils_1 = require("../../../utils");
4
+ const utils_1 = require("../../../service/V12/action/utils");
6
5
  class GroupAction {
7
6
  /**
8
7
  * 发送群聊消息
@@ -11,25 +10,11 @@ class GroupAction {
11
10
  * @param message_id {string} 引用的消息ID
12
11
  */
13
12
  async sendGroupMsg(group_id, message, message_id) {
14
- const forward = message.find(e => e.type === 'node');
15
- if (forward)
16
- (0, utils_1.remove)(message, forward);
17
- let quote = message.find(e => e.type === 'reply');
18
- if (quote)
19
- (0, utils_1.remove)(message, quote);
20
- const element = index_1.V12.fromSegment(message);
21
- if (forward)
22
- element.unshift(await this.client.makeForwardMsg(forward.data.message.map(segment => {
23
- return {
24
- message: index_1.V12.fromSegment([segment]),
25
- user_id: forward.data.user_id,
26
- nickname: forward.data.user_name,
27
- time: forward.data.time
28
- };
29
- })));
30
- if (quote && !message_id)
31
- message_id = quote.data.message_id;
32
- return await this.client.sendGroupMsg(group_id, element, message_id ? await this.client.getMsg(message_id) : undefined);
13
+ let { element, quote_id } = await utils_1.processMessage.apply(this.client, [message, message_id]);
14
+ element = await utils_1.processMusic.apply(this.client, ['group', group_id, element]);
15
+ if (!element.length)
16
+ return;
17
+ return await this.client.sendGroupMsg(group_id, element, quote_id ? await this.client.getMsg(quote_id) : undefined);
33
18
  }
34
19
  /**
35
20
  * 群组踢人
@@ -40,6 +25,20 @@ class GroupAction {
40
25
  setGroupKick(group_id, user_id, reject_add_request) {
41
26
  return this.client.setGroupKick(group_id, user_id, reject_add_request);
42
27
  }
28
+ /**
29
+ * 设置群精华
30
+ * @param message_id
31
+ */
32
+ setEssenceMessage(message_id) {
33
+ return this.client.setEssenceMessage(message_id);
34
+ }
35
+ /**
36
+ * 移除群精华
37
+ * @param message_id
38
+ */
39
+ deleteEssenceMessage(message_id) {
40
+ return this.client.removeEssenceMessage(message_id);
41
+ }
43
42
  /**
44
43
  * 群禁言指定人
45
44
  * @param group_id {number} 群id
@@ -1,8 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GuildAction = void 0;
4
- const V12_1 = require("../../../service/V12");
5
- const utils_1 = require("../../../utils");
4
+ const utils_1 = require("../../../service/V12/action/utils");
6
5
  class GuildAction {
7
6
  getGuildList() {
8
7
  return this.client.getGuildList();
@@ -14,22 +13,9 @@ class GuildAction {
14
13
  return this.client.getGuildMemberList(guild_id);
15
14
  }
16
15
  async sendGuildMsg(guild_id, channel_id, message) {
17
- const forward = message.find(e => e.type === 'node');
18
- if (forward)
19
- (0, utils_1.remove)(message, forward);
20
- let quote = message.find(e => e.type === 'reply');
21
- if (quote)
22
- (0, utils_1.remove)(message, quote);
23
- const element = V12_1.V12.fromSegment(message);
24
- // if(forward) element.unshift(await this.client.makeForwardMsg(forward.data.message.map(segment=>{
25
- // return {
26
- // message:V12.fromSegment([segment]),
27
- // user_id:forward.data.user_id,
28
- // nickname:forward.data.user_name,
29
- // time:forward.data.time
30
- // }
31
- // })))
32
- // if(quote && !message_id) message_id=quote.data.message_id
16
+ const { element } = await utils_1.processMessage.apply(this.client, [message]);
17
+ if (!element.length)
18
+ return;
33
19
  return await this.client.sendGuildMsg(guild_id, channel_id, element);
34
20
  }
35
21
  }
@@ -0,0 +1,7 @@
1
+ import { Client, MessageElem } from "icqq";
2
+ import { V12 } from "../../../service/V12";
3
+ export declare function processMusic(this: Client, target_type: 'group' | 'friend', target_id: number, element: any): Promise<any>;
4
+ export declare function processMessage(this: Client, message: V12.SegmentElem[], quote_id?: string): Promise<{
5
+ element: MessageElem[];
6
+ quote_id?: string;
7
+ }>;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.processMessage = exports.processMusic = void 0;
4
+ const V12_1 = require("../../../service/V12");
5
+ const utils_1 = require("../../../utils");
6
+ async function processMusic(target_type, target_id, element) {
7
+ const musicList = element.filter(e => e.type === 'music');
8
+ element = element.filter(e => !musicList.includes(e));
9
+ const target = target_type === 'group' ? this.pickGroup(target_id) : this.pickFriend(target_id);
10
+ if (musicList.length)
11
+ await Promise.all(musicList.map(async (music) => {
12
+ return await target.shareMusic(music.platform, music.id);
13
+ }));
14
+ return element;
15
+ }
16
+ exports.processMusic = processMusic;
17
+ async function processMessage(message, quote_id) {
18
+ const forward = message.find(e => e.type === 'node');
19
+ if (forward)
20
+ (0, utils_1.remove)(message, forward);
21
+ let quote = message.find(e => e.type === 'reply');
22
+ if (quote)
23
+ (0, utils_1.remove)(message, quote);
24
+ const element = V12_1.V12.fromSegment(message);
25
+ if (forward)
26
+ element.unshift(
27
+ // 构造抓发消息
28
+ await this.makeForwardMsg(await Promise.all(
29
+ // 处理转发消息段
30
+ forward.data.message.map(async (segment) => {
31
+ return {
32
+ // 转发套转发处理
33
+ message: (await processMessage.apply(this, [V12_1.V12.fromSegment([segment])])).element,
34
+ user_id: forward.data.user_id,
35
+ nickname: forward.data.user_name,
36
+ time: forward.data.time
37
+ };
38
+ }))));
39
+ if (quote && !quote_id)
40
+ quote_id = quote.data.message_id;
41
+ return { element, quote_id };
42
+ }
43
+ exports.processMessage = processMessage;
@@ -81,6 +81,13 @@ export declare namespace V12 {
81
81
  file: {
82
82
  file_id: string;
83
83
  };
84
+ music: {
85
+ type: "163" | 'qq' | 'xm' | 'custom';
86
+ id?: string;
87
+ url?: string;
88
+ audio?: string;
89
+ title?: string;
90
+ };
84
91
  location: {
85
92
  latitude: number;
86
93
  longitude: number;
@@ -93,6 +100,12 @@ export declare namespace V12 {
93
100
  user_name?: string;
94
101
  message: SegmentElem[];
95
102
  };
103
+ share: {
104
+ url: string;
105
+ title: string;
106
+ content?: string;
107
+ image?: string;
108
+ };
96
109
  reply: {
97
110
  message_id: string;
98
111
  };
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.V12 = void 0;
7
7
  const icqq_1 = require("icqq");
8
+ const utils_1 = require("../../utils");
8
9
  const path_1 = require("path");
9
10
  const onebot_1 = require("../../onebot");
10
11
  const action_1 = require("./action");
@@ -13,7 +14,7 @@ const url_1 = require("url");
13
14
  const http_1 = __importDefault(require("http"));
14
15
  const https_1 = __importDefault(require("https"));
15
16
  const ws_1 = require("ws");
16
- const utils_1 = require("../../utils");
17
+ const utils_2 = require("../../utils");
17
18
  const db_1 = require("../../db");
18
19
  const app_1 = require("../../server/app");
19
20
  const fs_1 = require("fs");
@@ -116,7 +117,7 @@ class V12 extends events_1.EventEmitter {
116
117
  timeout: config.timeout || this.config.request_timeout,
117
118
  headers: {
118
119
  "Content-Type": "application/json",
119
- "User-Agent": "OneBot/12 (qq) Node-onebots/0.0.15",
120
+ "User-Agent": "OneBot/12 (qq) Node-onebots/" + utils_1.version,
120
121
  "X-OneBot-Version": 12,
121
122
  "X-Impl": "icqq_onebot",
122
123
  },
@@ -317,7 +318,7 @@ class V12 extends events_1.EventEmitter {
317
318
  }
318
319
  dispatch(data) {
319
320
  const payload = {
320
- id: (0, utils_1.uuid)(),
321
+ id: (0, utils_2.uuid)(),
321
322
  impl: 'icqq_onebot',
322
323
  version: 12,
323
324
  platform: 'qq',
@@ -325,7 +326,7 @@ class V12 extends events_1.EventEmitter {
325
326
  platform: 'qq',
326
327
  user_id: `${this.oneBot.uin}`
327
328
  },
328
- ...(0, utils_1.transformObj)(data, (key, value) => {
329
+ ...(0, utils_2.transformObj)(data, (key, value) => {
329
330
  if (!['user_id', 'group_id', 'discuss_id', 'member_id', 'channel_id', 'guild_id'].includes(key))
330
331
  return value;
331
332
  return value + '';
@@ -335,7 +336,7 @@ class V12 extends events_1.EventEmitter {
335
336
  }
336
337
  async apply(req) {
337
338
  let { action, params, echo } = req;
338
- action = (0, utils_1.toLine)(action);
339
+ action = (0, utils_2.toLine)(action);
339
340
  let is_async = action.includes("_async");
340
341
  if (is_async)
341
342
  action = action.replace("_async", "");
@@ -354,7 +355,7 @@ class V12 extends events_1.EventEmitter {
354
355
  else
355
356
  throw new Error('required detail_type or input (user_id/group_id/(guild_id and channel_id))');
356
357
  }
357
- const method = (0, utils_1.toHump)(action);
358
+ const method = (0, utils_2.toHump)(action);
358
359
  if (Reflect.has(this.action, method)) {
359
360
  const ARGS = String(Reflect.get(this.action, method)).match(/\(.*\)/)?.[0]
360
361
  .replace("(", "")
@@ -365,10 +366,9 @@ class V12 extends events_1.EventEmitter {
365
366
  for (let k of ARGS) {
366
367
  if (Reflect.has(params, k)) {
367
368
  if (onebot_1.BOOLS.includes(k))
368
- params[k] = (0, utils_1.toBool)(params[k]);
369
+ params[k] = (0, utils_2.toBool)(params[k]);
369
370
  if (k === 'message') {
370
371
  params[k] = V12.fromSegment(params[k]);
371
- params['message_id'] = params[k].find(e => e.type === 'reply')?.message_id;
372
372
  }
373
373
  args.push(params[k]);
374
374
  }
@@ -484,12 +484,12 @@ class V12 extends events_1.EventEmitter {
484
484
  const headers = {
485
485
  "X-Self-ID": String(this.oneBot.uin),
486
486
  "X-Client-Role": "Universal",
487
- "User-Agent": "OneBot/12 (qq) Node-onebots/0.0.15",
488
- "Sec-WebSocket-Protocol": "12.onebots.v0.0.15"
487
+ "User-Agent": "OneBot/12 (qq) Node-onebots/" + utils_1.version,
488
+ "Sec-WebSocket-Protocol": "12.onebots.v" + utils_1.version
489
489
  };
490
490
  if (config.access_token)
491
491
  headers.Authorization = "Bearer " + config.access_token;
492
- const ws = new ws_1.WebSocket(url, '12.onebots.v0.0.15', { headers });
492
+ const ws = new ws_1.WebSocket(url, '12.onebots.v' + utils_1.version, { headers });
493
493
  ws.on("error", (err) => {
494
494
  this.logger.error(err.message);
495
495
  });
@@ -564,6 +564,7 @@ class V12 extends events_1.EventEmitter {
564
564
  }
565
565
  exports.V12 = V12;
566
566
  (function (V12) {
567
+ const fileTypes = ['image', "file", 'record', 'video', 'flash'];
567
568
  function fromSegment(msgList) {
568
569
  msgList = [].concat(msgList);
569
570
  return msgList.map((msg) => {
@@ -572,9 +573,17 @@ exports.V12 = V12;
572
573
  if (typeof msg === 'string') {
573
574
  return { type: 'text', text: msg };
574
575
  }
575
- const { type, data, ...other } = msg;
576
+ const { type, data = {}, ...other } = msg;
577
+ Object.assign(data, other);
578
+ if (type === 'music' && !data['platform']) {
579
+ data['platform'] = data['type'];
580
+ delete data['type'];
581
+ }
576
582
  if (type === 'mention')
577
583
  data['qq'] = Number(data['user_id']);
584
+ if (fileTypes.includes(type) && !data['file']) {
585
+ data['file'] = data['file_id'];
586
+ }
578
587
  return {
579
588
  type: type.replace('mention', 'at').replace('at_all', 'at'),
580
589
  ...other,
@@ -589,6 +598,8 @@ exports.V12 = V12;
589
598
  if (typeof msg === 'string')
590
599
  return { type: 'text', data: { text: msg } };
591
600
  let { type, ...other } = msg;
601
+ if (fileTypes.includes(type))
602
+ other['file_id'] = other['file'];
592
603
  return {
593
604
  type: type === 'at' ? other['qq'] ? 'mention' : "mention_all" : type,
594
605
  data: {
package/lib/utils.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- export declare function deepMerge<T extends any>(base: T, ...from: T[]): T;
1
+ export declare const version: any;
2
+ export declare function deepMerge(base: any, ...from: any[]): any;
2
3
  export declare function transformObj(obj: any, callback: any): any;
3
4
  export declare function deepClone<T extends any>(obj: T): T;
4
5
  export declare function pick<T extends object, K extends keyof T>(source: T, keys?: Iterable<K>, forced?: boolean): Pick<T, K>;
package/lib/utils.js CHANGED
@@ -23,10 +23,14 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.getProperties = exports.protectedFields = exports.uuid = exports.toBool = exports.toLine = exports.remove = exports.toHump = exports.Mixin = exports.omit = exports.pick = exports.deepClone = exports.transformObj = exports.deepMerge = void 0;
26
+ exports.getProperties = exports.protectedFields = exports.uuid = exports.toBool = exports.toLine = exports.remove = exports.toHump = exports.Mixin = exports.omit = exports.pick = exports.deepClone = exports.transformObj = exports.deepMerge = exports.version = void 0;
27
27
  const crypto = __importStar(require("crypto"));
28
+ const packageJson = require('../package.json');
29
+ exports.version = packageJson.version;
28
30
  // 合并对象/数组
29
31
  function deepMerge(base, ...from) {
32
+ if (base === null || base === undefined)
33
+ base = from.shift();
30
34
  if (from.length === 0) {
31
35
  return base;
32
36
  }
@@ -34,22 +38,19 @@ function deepMerge(base, ...from) {
34
38
  return base;
35
39
  }
36
40
  if (Array.isArray(base)) {
37
- return base.concat(...from);
41
+ return Array.from(new Set(base.concat(...from)));
38
42
  }
39
43
  for (const item of from) {
40
44
  for (const key in item) {
41
45
  if (base.hasOwnProperty(key)) {
42
46
  if (typeof base[key] === 'object') {
43
- // @ts-ignore
44
47
  base[key] = deepMerge(base[key], item[key]);
45
48
  }
46
49
  else {
47
- // @ts-ignore
48
50
  base[key] = item[key];
49
51
  }
50
52
  }
51
53
  else {
52
- // @ts-ignore
53
54
  base[key] = item[key];
54
55
  }
55
56
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "onebots",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "基于icqq的多例oneBot实现",
5
5
  "engines": {
6
6
  "node": ">=16"
@@ -50,7 +50,7 @@
50
50
  ],
51
51
  "dependencies": {
52
52
  "@koa/router": "^10.1.1",
53
- "icqq": "^0.0.13-6",
53
+ "icqq": "^0.0.13-7",
54
54
  "icqq-cq-enable": "^1.0.0",
55
55
  "js-yaml": "^4.1.0",
56
56
  "koa": "^2.13.4",