onebots 0.4.20 → 0.4.21
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/service/V11/action/friend.d.ts +1 -1
- package/lib/service/V11/action/friend.js +2 -1
- package/lib/service/V11/action/group.d.ts +1 -1
- package/lib/service/V11/action/group.js +2 -1
- package/lib/service/V11/db_sqlite.d.ts +2 -0
- package/lib/service/V11/db_sqlite.js +20 -8
- package/lib/service/V11/index.d.ts +10 -1
- package/lib/service/V11/index.js +24 -15
- package/lib/service/shareMusicCustom.d.ts +19 -0
- package/lib/service/shareMusicCustom.js +52 -0
- package/lib/types.d.ts +9 -0
- package/lib/types.js +26 -0
- package/package.json +1 -1
|
@@ -8,7 +8,7 @@ export declare class FriendAction {
|
|
|
8
8
|
* @param message {import('icqq').Sendable} 发送的消息
|
|
9
9
|
* @param message_id {string} 引用的消息ID
|
|
10
10
|
*/
|
|
11
|
-
sendPrivateMsg(this: V11, user_id: number, message: string | SegmentElem | SegmentElem[], message_id?: string): Promise<
|
|
11
|
+
sendPrivateMsg(this: V11, user_id: number, message: string | SegmentElem | SegmentElem[], message_id?: string): Promise<any>;
|
|
12
12
|
/**
|
|
13
13
|
* 获取好友列表
|
|
14
14
|
*/
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FriendAction = void 0;
|
|
4
4
|
const utils_1 = require("../../../service/V11/utils");
|
|
5
|
+
const shareMusicCustom_1 = require("../../../service/shareMusicCustom");
|
|
5
6
|
class FriendAction {
|
|
6
7
|
/**
|
|
7
8
|
* 发送私聊消息
|
|
@@ -13,7 +14,7 @@ class FriendAction {
|
|
|
13
14
|
const msg = message_id ? await this.client.getMsg(message_id) : undefined;
|
|
14
15
|
const { element, quote, music, share } = await utils_1.processMessage.apply(this.client, [message, msg]);
|
|
15
16
|
if (music)
|
|
16
|
-
return await this.client.pickFriend(user_id)
|
|
17
|
+
return await shareMusicCustom_1.shareMusic.call(this.client.pickFriend(user_id), music);
|
|
17
18
|
if (share)
|
|
18
19
|
return await this.client.pickFriend(user_id).shareUrl(music.data);
|
|
19
20
|
if (element.length) {
|
|
@@ -7,7 +7,7 @@ export declare class GroupAction {
|
|
|
7
7
|
* @param message {import('icqq').Sendable} 消息
|
|
8
8
|
* @param message_id {string} 引用的消息ID
|
|
9
9
|
*/
|
|
10
|
-
sendGroupMsg(this: V11, group_id: number, message: string | SegmentElem | SegmentElem[], message_id?: string): Promise<
|
|
10
|
+
sendGroupMsg(this: V11, group_id: number, message: string | SegmentElem | SegmentElem[], message_id?: string): Promise<any>;
|
|
11
11
|
/**
|
|
12
12
|
* 群组踢人
|
|
13
13
|
* @param group_id {number} 群id
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.GroupAction = void 0;
|
|
4
4
|
const utils_1 = require("../../../service/V11/utils");
|
|
5
|
+
const shareMusicCustom_1 = require("../../../service/shareMusicCustom");
|
|
5
6
|
class GroupAction {
|
|
6
7
|
/**
|
|
7
8
|
* 发送群聊消息
|
|
@@ -13,7 +14,7 @@ class GroupAction {
|
|
|
13
14
|
const msg = message_id ? await this.client.getMsg(message_id) : undefined;
|
|
14
15
|
const { element, quote, music, share } = await utils_1.processMessage.apply(this.client, [message, msg]);
|
|
15
16
|
if (music)
|
|
16
|
-
return await this.client.pickGroup(group_id)
|
|
17
|
+
return await shareMusicCustom_1.shareMusic.call(this.client.pickGroup(group_id), music);
|
|
17
18
|
if (share)
|
|
18
19
|
return await this.client.pickGroup(group_id).shareUrl(music.data);
|
|
19
20
|
if (element.length) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { MsgEntry } from "./db_entities";
|
|
2
2
|
import { DataSource, Repository } from "typeorm";
|
|
3
3
|
import { Logger } from "log4js";
|
|
4
|
+
import { AsyncLock } from "../../types";
|
|
4
5
|
export declare class Database {
|
|
5
6
|
logger: Logger;
|
|
6
7
|
dbPath: string;
|
|
@@ -11,6 +12,7 @@ export declare class Database {
|
|
|
11
12
|
msgHistoryPreserveDays: number;
|
|
12
13
|
msgHistoryCheckInterval: number;
|
|
13
14
|
msgRepo: Repository<MsgEntry>;
|
|
15
|
+
dbLock: AsyncLock;
|
|
14
16
|
constructor(dbPath: string, logger: Logger);
|
|
15
17
|
initDB(): Promise<void>;
|
|
16
18
|
/**
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Database = void 0;
|
|
4
4
|
const db_entities_1 = require("./db_entities");
|
|
5
5
|
const typeorm_1 = require("typeorm");
|
|
6
|
+
const types_1 = require("../../types");
|
|
6
7
|
class Database {
|
|
7
8
|
constructor(dbPath, logger) {
|
|
8
9
|
/**
|
|
@@ -12,6 +13,7 @@ class Database {
|
|
|
12
13
|
this.msgHistoryCheckInterval = 1 * 24 * 3600 * 1000; // 历史记录检查间隔
|
|
13
14
|
this.dbPath = dbPath;
|
|
14
15
|
this.logger = logger;
|
|
16
|
+
this.dbLock = new types_1.AsyncLock();
|
|
15
17
|
this.dataSource = new typeorm_1.DataSource({
|
|
16
18
|
type: "better-sqlite3",
|
|
17
19
|
database: dbPath,
|
|
@@ -39,15 +41,25 @@ class Database {
|
|
|
39
41
|
* @param msgData
|
|
40
42
|
*/
|
|
41
43
|
async addOrUpdateMsg(msgData) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
msgData.
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
await this.dbLock.lock();
|
|
45
|
+
try {
|
|
46
|
+
let msgDataExists = await this.getMsgByParams(msgData.user_id, msgData.group_id, msgData.seq);
|
|
47
|
+
if (msgDataExists) {
|
|
48
|
+
// send_msg() 返回值和同步的 message 消息哪个先来不确定,send_msg 返回值后来时不允许更新数据库
|
|
49
|
+
if (msgData.content.length == 0) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
msgData.id = msgDataExists.id;
|
|
53
|
+
await this.msgRepo.update({ id: msgData.id }, msgData);
|
|
54
|
+
return msgDataExists.id;
|
|
55
|
+
}
|
|
56
|
+
msgData = await this.msgRepo.save(msgData);
|
|
57
|
+
this.logger.debug(`addMsg with id:${msgData.id}`);
|
|
58
|
+
return msgData.id;
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
this.dbLock.unlock();
|
|
47
62
|
}
|
|
48
|
-
msgData = await this.msgRepo.save(msgData);
|
|
49
|
-
this.logger.debug(`addMsg with id:${msgData.id}`);
|
|
50
|
-
return msgData.id;
|
|
51
63
|
}
|
|
52
64
|
/**
|
|
53
65
|
* 通过 icqq 的 base64 格式的 message_id 获取一个 MsgData 对象
|
|
@@ -39,7 +39,16 @@ export declare class V11 extends EventEmitter implements OneBot.Base {
|
|
|
39
39
|
system_online(data: any): void;
|
|
40
40
|
dispatch(data: any): Promise<void>;
|
|
41
41
|
private _formatEvent;
|
|
42
|
-
private
|
|
42
|
+
private addMsgToDB;
|
|
43
|
+
/**
|
|
44
|
+
* 从 send_msg_xxx() 调用的返回值中提取消息存入数据库(可以让前端在没有收到同步的message数据前就有能力拿到消息对应的base64_id)
|
|
45
|
+
* (也有可能来的比message慢,后来的话会被数据库忽略)
|
|
46
|
+
* @param user_id 发送者
|
|
47
|
+
* @param group_id 群号,私聊为0
|
|
48
|
+
* @param seq 消息序号
|
|
49
|
+
* @param base64_id icqq返回的base64格式的消息id
|
|
50
|
+
*/
|
|
51
|
+
private addMsgToDBFromSendMsgResult;
|
|
43
52
|
private getReplyMsgIdFromDB;
|
|
44
53
|
private _httpRequestHandler;
|
|
45
54
|
/**
|
package/lib/service/V11/index.js
CHANGED
|
@@ -219,7 +219,7 @@ class V11 extends events_1.EventEmitter {
|
|
|
219
219
|
}
|
|
220
220
|
}
|
|
221
221
|
if (data.message_id) {
|
|
222
|
-
data.message_id = await this.
|
|
222
|
+
data.message_id = await this.addMsgToDB(data);
|
|
223
223
|
}
|
|
224
224
|
if (data.post_type == 'notice' && String(data.notice_type).endsWith('_recall')) {
|
|
225
225
|
this.db.markMsgAsRecalled(data.base64_id);
|
|
@@ -292,7 +292,7 @@ class V11 extends events_1.EventEmitter {
|
|
|
292
292
|
return JSON.stringify(data);
|
|
293
293
|
}
|
|
294
294
|
}
|
|
295
|
-
async
|
|
295
|
+
async addMsgToDB(data) {
|
|
296
296
|
if (!data.sender || !('user_id' in data.sender)) { // eg. notice
|
|
297
297
|
return;
|
|
298
298
|
}
|
|
@@ -312,6 +312,24 @@ class V11 extends events_1.EventEmitter {
|
|
|
312
312
|
msg.content = data.cqCode;
|
|
313
313
|
return await this.db.addOrUpdateMsg(msg);
|
|
314
314
|
}
|
|
315
|
+
/**
|
|
316
|
+
* 从 send_msg_xxx() 调用的返回值中提取消息存入数据库(可以让前端在没有收到同步的message数据前就有能力拿到消息对应的base64_id)
|
|
317
|
+
* (也有可能来的比message慢,后来的话会被数据库忽略)
|
|
318
|
+
* @param user_id 发送者
|
|
319
|
+
* @param group_id 群号,私聊为0
|
|
320
|
+
* @param seq 消息序号
|
|
321
|
+
* @param base64_id icqq返回的base64格式的消息id
|
|
322
|
+
*/
|
|
323
|
+
async addMsgToDBFromSendMsgResult(user_id, group_id, seq, base64_id) {
|
|
324
|
+
let msg = new db_entities_1.MsgEntry();
|
|
325
|
+
msg.base64_id = base64_id;
|
|
326
|
+
msg.seq = seq;
|
|
327
|
+
msg.user_id = user_id;
|
|
328
|
+
msg.nickname = '';
|
|
329
|
+
msg.group_id = group_id;
|
|
330
|
+
msg.content = '';
|
|
331
|
+
return await this.db.addOrUpdateMsg(msg);
|
|
332
|
+
}
|
|
315
333
|
async getReplyMsgIdFromDB(data) {
|
|
316
334
|
let group_id = (data.message_type === 'group') ? data.group_id : 0;
|
|
317
335
|
let msg = await this.db.getMsgByParams(data.source.user_id, group_id, data.source.seq);
|
|
@@ -568,19 +586,10 @@ class V11 extends events_1.EventEmitter {
|
|
|
568
586
|
result.data = [...result.data.values()];
|
|
569
587
|
if (result.data?.message)
|
|
570
588
|
result.data.message = (0, icqq_cq_enable_1.toSegment)(result.data.message);
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
* > 但 get_msg 返回的是从数据库获取的message_id,因此是有效的
|
|
576
|
-
*/
|
|
577
|
-
// if (result.data?.message_id && result.data?.seq) {
|
|
578
|
-
// let message_id = result.data?.message_id
|
|
579
|
-
// if(!(typeof message_id == 'number' || /^\d+$/.test(message_id))) {
|
|
580
|
-
// // this.db.set(`KVMap.${result.data.seq}`,result.data.message_id )
|
|
581
|
-
// result.data.message_id = result.data.seq
|
|
582
|
-
// }
|
|
583
|
-
// }
|
|
589
|
+
// send_msg_xxx 时提前把数据写入数据库(也有可能来的比message慢,后来的话会被数据库忽略)
|
|
590
|
+
if (result.status === 'ok' && params.user_id && result.data?.message_id && result.data?.seq) {
|
|
591
|
+
result.data.message_id = await this.addMsgToDBFromSendMsgResult(params.user_id, params.group_id || 0, result.data.seq, result.data.message_id);
|
|
592
|
+
}
|
|
584
593
|
if (echo) {
|
|
585
594
|
result.echo = echo;
|
|
586
595
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Contactable } from "icqq/lib/internal";
|
|
2
|
+
import { MusicElem } from "icqq/lib/message";
|
|
3
|
+
import { Encodable } from "icqq/lib/core/protobuf";
|
|
4
|
+
/** 发送音乐分享(允许自定义参数) */
|
|
5
|
+
export declare function shareMusic(this: Contactable, music: MusicElem): Promise<void>;
|
|
6
|
+
/**
|
|
7
|
+
* 构造频道b77音乐分享
|
|
8
|
+
* @param channel_id {string} 子频道id
|
|
9
|
+
* @param guild_id {string} 频道id
|
|
10
|
+
* @param music 音乐分享数据
|
|
11
|
+
*/
|
|
12
|
+
export declare function buildMusic(channel_id: string, guild_id: string, music: MusicElem): Promise<Encodable>;
|
|
13
|
+
/**
|
|
14
|
+
* 构造b77音乐分享
|
|
15
|
+
* @param target {number} 群id或者好友qq
|
|
16
|
+
* @param bu {0|1} 类型表示:0 为好友 1 为群
|
|
17
|
+
* @param music 音乐分享数据
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildMusic(target: number, bu: 0 | 1, music: MusicElem): Promise<Encodable>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildMusic = exports.shareMusic = void 0;
|
|
4
|
+
const message_1 = require("icqq/lib/message");
|
|
5
|
+
const core_1 = require("icqq/lib/core");
|
|
6
|
+
const process_1 = require("process");
|
|
7
|
+
/** 发送音乐分享(允许自定义参数) */
|
|
8
|
+
async function shareMusic(music) {
|
|
9
|
+
const body = await buildMusic((this.gid || this.uid), this.dm ? 0 : 1, music);
|
|
10
|
+
await this.c.sendOidb("OidbSvc.0xb77_9", core_1.pb.encode(body));
|
|
11
|
+
}
|
|
12
|
+
exports.shareMusic = shareMusic;
|
|
13
|
+
async function buildMusic(target, bu, music) {
|
|
14
|
+
const { appid, package_name, sign, getMusicInfo } = message_1.musicFactory[music.platform];
|
|
15
|
+
let style = 4;
|
|
16
|
+
try {
|
|
17
|
+
let { singer = null, title = null, jumpUrl = null, musicUrl = null, preview = null } = music.id ? await getMusicInfo(music.id) : {};
|
|
18
|
+
singer = music['content'] || music.singer || singer; // 自定义参数优先级高于默认值(gocq的参数名与icqq有区别,做下兼容)
|
|
19
|
+
title = music.title || title;
|
|
20
|
+
jumpUrl = music.jumpUrl || jumpUrl;
|
|
21
|
+
musicUrl = music['url'] || music['voice'] || music.musicUrl || musicUrl;
|
|
22
|
+
preview = music['image'] || music.preview || preview;
|
|
23
|
+
if (!musicUrl)
|
|
24
|
+
style = 0;
|
|
25
|
+
return {
|
|
26
|
+
1: appid,
|
|
27
|
+
2: 1,
|
|
28
|
+
3: style,
|
|
29
|
+
5: {
|
|
30
|
+
1: 1,
|
|
31
|
+
2: "0.0.0",
|
|
32
|
+
3: package_name,
|
|
33
|
+
4: sign
|
|
34
|
+
},
|
|
35
|
+
10: typeof bu === 'string' ? 3 : bu,
|
|
36
|
+
11: target,
|
|
37
|
+
12: {
|
|
38
|
+
10: title,
|
|
39
|
+
11: singer,
|
|
40
|
+
12: "[分享]" + title,
|
|
41
|
+
13: jumpUrl,
|
|
42
|
+
14: preview,
|
|
43
|
+
16: musicUrl,
|
|
44
|
+
},
|
|
45
|
+
19: typeof bu === 'string' ? Number(bu) : undefined
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
throw new Error("unknown music id: " + music.id + ", in platform: " + music.platform + ", with title: " + process_1.title);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.buildMusic = buildMusic;
|
package/lib/types.d.ts
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
1
|
export type LogLevel = "trace" | "debug" | "info" | "warn" | "error" | "fatal" | "mark" | "off";
|
|
2
2
|
export type Dispose = () => any;
|
|
3
3
|
export type MayBeArray<T extends any> = T | T[];
|
|
4
|
+
/**
|
|
5
|
+
* 异步锁---
|
|
6
|
+
*/
|
|
7
|
+
export declare class AsyncLock {
|
|
8
|
+
private _lock;
|
|
9
|
+
private _waitList;
|
|
10
|
+
lock(): Promise<void>;
|
|
11
|
+
unlock(): void;
|
|
12
|
+
}
|
package/lib/types.js
CHANGED
|
@@ -1,2 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AsyncLock = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* 异步锁---
|
|
6
|
+
*/
|
|
7
|
+
class AsyncLock {
|
|
8
|
+
constructor() {
|
|
9
|
+
this._lock = false;
|
|
10
|
+
this._waitList = [];
|
|
11
|
+
}
|
|
12
|
+
async lock() {
|
|
13
|
+
if (this._lock) {
|
|
14
|
+
await new Promise((resolve) => {
|
|
15
|
+
this._waitList.push(resolve);
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
this._lock = true;
|
|
19
|
+
}
|
|
20
|
+
unlock() {
|
|
21
|
+
this._lock = false;
|
|
22
|
+
if (this._waitList.length > 0) {
|
|
23
|
+
let resolve = this._waitList.shift();
|
|
24
|
+
resolve && resolve();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.AsyncLock = AsyncLock;
|