@alemonjs/qq-bot 2.1.35 → 2.1.37
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 +66 -1981
- package/lib/config.d.ts +2 -0
- package/lib/format.d.ts +4 -1
- package/lib/format.js +68 -4
- package/lib/framework-actions.d.ts +75 -0
- package/lib/framework-actions.js +620 -0
- package/lib/framework-events.d.ts +10 -0
- package/lib/framework-events.js +182 -0
- package/lib/hook.d.ts +16 -12
- package/lib/hook.js +5 -9
- package/lib/index.d.ts +5 -1
- package/lib/index.websoket.js +6 -2
- package/lib/message/AUDIO_EVENT.d.ts +20 -0
- package/lib/message/AUDIO_EVENT.js +1 -0
- package/lib/message/FORUM_EVENT.d.ts +33 -0
- package/lib/message/FORUM_EVENT.js +1 -0
- package/lib/message/GUILD_AUDIT.d.ts +14 -0
- package/lib/message/GUILD_AUDIT.js +1 -0
- package/lib/message/INTERACTION_CREATE.d.ts +13 -20
- package/lib/message/MESSAGE_CREATE.d.ts +3 -9
- package/lib/message/MESSAGE_DELETE.d.ts +15 -1
- package/lib/message/group/C2C_MESSAGE_CREATE.d.ts +3 -13
- package/lib/message/group/C2C_MSG_RECEIVE.d.ts +1 -1
- package/lib/message/group/C2C_MSG_REJECT.d.ts +1 -1
- package/lib/message/group/FRIEND_ADD.d.ts +7 -1
- package/lib/message/group/FRIEND_DEL.d.ts +4 -1
- package/lib/message/group/GROUP_AT_MESSAGE_CREATE.d.ts +6 -27
- package/lib/message/group/GROUP_MEMBER_ADD.d.ts +4 -2
- package/lib/message/group/GROUP_MEMBER_REMOVE.d.ts +4 -2
- package/lib/message/group/GROUP_MESSAGE_CREATE.d.ts +6 -27
- package/lib/message/group/GROUP_MSG_RECEIVE.d.ts +1 -1
- package/lib/message/group/GROUP_MSG_REJECT.d.ts +1 -1
- package/lib/message/group/MESSAGE_AUDIT_PASS.d.ts +2 -0
- package/lib/message/group/MESSAGE_AUDIT_REJECT.d.ts +2 -0
- package/lib/message/group/SUBSCRIBE_MESSAGE_STATUS.d.ts +17 -0
- package/lib/message/group/SUBSCRIBE_MESSAGE_STATUS.js +1 -0
- package/lib/register.d.ts +1 -0
- package/lib/register.js +279 -115
- package/lib/sdk/api.d.ts +93 -14
- package/lib/sdk/api.js +241 -45
- package/lib/sdk/client.webhook.js +2 -1
- package/lib/sdk/client.websoket.js +2 -1
- package/lib/sdk/intents.d.ts +1 -0
- package/lib/sdk/intents.js +1 -0
- package/lib/sdk/message.d.ts +1 -1
- package/lib/sdk/message.group.d.ts +4 -2
- package/lib/sdk/message.guild.d.ts +19 -0
- package/lib/sdk/non-channel-types.d.ts +138 -0
- package/lib/sdk/non-channel-types.js +1 -0
- package/lib/sdk/registry.js +2 -2
- package/lib/sdk/typing.d.ts +13 -1
- package/lib/sends.d.ts +3 -3
- package/lib/sends.js +57 -71
- package/lib/upload.js +13 -37
- package/package.json +8 -5
package/lib/sdk/api.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ApiRequestData, FileType, GroupAction, SetMemberMuteState, StreamMessageData, UploadPartFinishData, UploadPrepareData } from "./typing.js";
|
|
2
|
+
import { QQBotBlacklistUser, QQBotGroupMember, QQBotMenu, QQBotMessageResult, QQBotPage, QQBotPanel, QQBotPanelCreate, QQBotPanelRecord, QQBotPanelScope } from "./non-channel-types.js";
|
|
2
3
|
import { QQBotConfig } from "./config.js";
|
|
3
4
|
import { AxiosRequestConfig } from "axios";
|
|
4
5
|
//#region src/sdk/api.d.ts
|
|
@@ -35,7 +36,7 @@ declare class QQBotAPI {
|
|
|
35
36
|
setConnectionStatusListener(listener?: (status: QQBotConnectionStatus, previous: QQBotConnectionStatus) => void): void;
|
|
36
37
|
/** Internal transport hook used by the multi-bot registry to discard stale routes. */
|
|
37
38
|
setStreamLifecycleListener(listener?: (streamId: string) => void): void;
|
|
38
|
-
/** C2C
|
|
39
|
+
/** C2C input indicator; uses the same message protocol as the framework typing action. */
|
|
39
40
|
sendTyping(params: {
|
|
40
41
|
BotId?: string;
|
|
41
42
|
userOpenId: string;
|
|
@@ -45,13 +46,13 @@ declare class QQBotAPI {
|
|
|
45
46
|
streamOpen(params: {
|
|
46
47
|
BotId?: string;
|
|
47
48
|
userOpenId: string;
|
|
48
|
-
msgId
|
|
49
|
+
msgId?: string;
|
|
49
50
|
eventId?: string;
|
|
50
51
|
}): {
|
|
51
52
|
streamId: `${string}-${string}-${string}-${string}-${string}`;
|
|
52
53
|
};
|
|
53
54
|
streamUpdate(streamId: string, fullText: string): Promise<unknown>;
|
|
54
|
-
streamComplete(streamId: string): Promise<
|
|
55
|
+
streamComplete(streamId: string): Promise<unknown>;
|
|
55
56
|
streamCancel(streamId: string): void;
|
|
56
57
|
/** Called by transports during shutdown so C2C streams cannot leak timers. */
|
|
57
58
|
protected cancelStreams(): void;
|
|
@@ -85,10 +86,7 @@ declare class QQBotAPI {
|
|
|
85
86
|
* @returns
|
|
86
87
|
* 0 文本 1 图文 2 md 3 ark 4 embed
|
|
87
88
|
*/
|
|
88
|
-
usersOpenMessages(openid: string, data: ApiRequestData): Promise<
|
|
89
|
-
id: string;
|
|
90
|
-
timestamp: number;
|
|
91
|
-
}>;
|
|
89
|
+
usersOpenMessages(openid: string, data: ApiRequestData): Promise<QQBotMessageResult>;
|
|
92
90
|
/**
|
|
93
91
|
* 得到消息序列
|
|
94
92
|
* @param MessageId
|
|
@@ -101,10 +99,7 @@ declare class QQBotAPI {
|
|
|
101
99
|
* @param data
|
|
102
100
|
* @returns
|
|
103
101
|
*/
|
|
104
|
-
groupOpenMessages(group_openid: string, data: ApiRequestData): Promise<
|
|
105
|
-
id: string;
|
|
106
|
-
timestamp: number;
|
|
107
|
-
}>;
|
|
102
|
+
groupOpenMessages(group_openid: string, data: ApiRequestData): Promise<QQBotMessageResult>;
|
|
108
103
|
/**
|
|
109
104
|
* 发送私聊富媒体文件
|
|
110
105
|
* @param openid
|
|
@@ -164,11 +159,14 @@ declare class QQBotAPI {
|
|
|
164
159
|
size?: number;
|
|
165
160
|
hashes?: QQBotMediaHashes;
|
|
166
161
|
name?: string;
|
|
162
|
+
send?: boolean;
|
|
167
163
|
onProgress?: (uploaded: number, total: number) => void;
|
|
168
164
|
}): Promise<{
|
|
169
165
|
file_uuid: string;
|
|
170
166
|
file_info: string;
|
|
171
167
|
ttl: number;
|
|
168
|
+
id?: string;
|
|
169
|
+
raw_url?: string;
|
|
172
170
|
}>;
|
|
173
171
|
/**
|
|
174
172
|
*
|
|
@@ -189,6 +187,68 @@ declare class QQBotAPI {
|
|
|
189
187
|
* @param message_id 消息 ID
|
|
190
188
|
*/
|
|
191
189
|
grouMessageDelte(group_openid: string, message_id: string): Promise<any>;
|
|
190
|
+
/** 生成添加机器人好友的分享链接。 */
|
|
191
|
+
generateUrlLink(data?: {
|
|
192
|
+
callback_data?: string;
|
|
193
|
+
}): Promise<{
|
|
194
|
+
data: {
|
|
195
|
+
url: string;
|
|
196
|
+
};
|
|
197
|
+
}>;
|
|
198
|
+
menuGet(): Promise<{
|
|
199
|
+
version: number;
|
|
200
|
+
menu?: QQBotMenu;
|
|
201
|
+
}>;
|
|
202
|
+
menuPut(data: {
|
|
203
|
+
menu?: QQBotMenu;
|
|
204
|
+
}): Promise<{
|
|
205
|
+
version: number;
|
|
206
|
+
}>;
|
|
207
|
+
panelsList(params: QQBotPage & {
|
|
208
|
+
scope: QQBotPanelScope;
|
|
209
|
+
}): Promise<{
|
|
210
|
+
records: QQBotPanelRecord[];
|
|
211
|
+
next_cursor: string;
|
|
212
|
+
is_end: boolean;
|
|
213
|
+
}>;
|
|
214
|
+
panelsCreate(data: QQBotPanelCreate): Promise<{
|
|
215
|
+
panel_id: string;
|
|
216
|
+
}>;
|
|
217
|
+
panelsGet(panel_id: string): Promise<QQBotPanelRecord>;
|
|
218
|
+
panelsPut(panel_id: string, data: {
|
|
219
|
+
panel: QQBotPanel;
|
|
220
|
+
}): Promise<{
|
|
221
|
+
version: number;
|
|
222
|
+
}>;
|
|
223
|
+
panelsDelete(panel_id: string): Promise<any>;
|
|
224
|
+
panelsTargetPut(panel_id: string, data: {
|
|
225
|
+
op: 'add' | 'del';
|
|
226
|
+
user_openids?: string[];
|
|
227
|
+
group_openids?: string[];
|
|
228
|
+
}): Promise<any>;
|
|
229
|
+
groupsMembers(group_openid: string, params?: {
|
|
230
|
+
cursor?: string;
|
|
231
|
+
}): Promise<{
|
|
232
|
+
members: QQBotGroupMember[];
|
|
233
|
+
next_cursor: string;
|
|
234
|
+
}>;
|
|
235
|
+
groupsBatchRemoveMembers(group_openid: string, data: {
|
|
236
|
+
member_openids: string[];
|
|
237
|
+
add_to_member_blacklist?: boolean;
|
|
238
|
+
}): Promise<{
|
|
239
|
+
remove_members_result: string;
|
|
240
|
+
add_to_member_blacklist_fail_openids: string[];
|
|
241
|
+
}>;
|
|
242
|
+
groupsMemberBlacklist(group_openid: string, params?: QQBotPage): Promise<{
|
|
243
|
+
users: QQBotBlacklistUser[];
|
|
244
|
+
next_cursor: string;
|
|
245
|
+
}>;
|
|
246
|
+
groupsMemberBlacklistPost(group_openid: string, data: {
|
|
247
|
+
op: 'add' | 'del';
|
|
248
|
+
member_openids: string[];
|
|
249
|
+
}): Promise<{
|
|
250
|
+
fail_openids: string[];
|
|
251
|
+
}>;
|
|
192
252
|
/**
|
|
193
253
|
* 获取群基本信息
|
|
194
254
|
* @param group_openid 群 OpenID
|
|
@@ -595,6 +655,10 @@ declare class QQBotAPI {
|
|
|
595
655
|
* @param 参数包括add和remove两个字段分别表示授予的权限以及删除的权限。要授予用户权限即把add对应位置 1,删除用户权限即把remove对应位置 1。当两个字段同一位都为 1,表现为删除权限。
|
|
596
656
|
*/
|
|
597
657
|
channelsPermissionsPut(channel_id: string, user_id: string, add: string, remove: string): Promise<any>;
|
|
658
|
+
/** 获取子频道身份组权限。 */
|
|
659
|
+
channelsRolePermissions(channel_id: string, role_id: string): Promise<any>;
|
|
660
|
+
/** 修改子频道身份组权限。 */
|
|
661
|
+
channelsRolePermissionsPut(channel_id: string, role_id: string, add: string, remove: string): Promise<any>;
|
|
598
662
|
/**
|
|
599
663
|
* *******
|
|
600
664
|
* 消息api
|
|
@@ -622,7 +686,20 @@ declare class QQBotAPI {
|
|
|
622
686
|
* @param source_guild_id 源频道 id
|
|
623
687
|
* @returns
|
|
624
688
|
*/
|
|
625
|
-
usersMeDms(): Promise<any>;
|
|
689
|
+
usersMeDms(recipient_id: string, source_guild_id: string): Promise<any>;
|
|
690
|
+
/** 申请频道接口权限,并向指定子频道发送授权链接。 */
|
|
691
|
+
guildsApiPermissionDemand(guild_id: string, data: {
|
|
692
|
+
channel_id: string;
|
|
693
|
+
api_identify: {
|
|
694
|
+
path: string;
|
|
695
|
+
method: string;
|
|
696
|
+
};
|
|
697
|
+
desc?: string;
|
|
698
|
+
}): Promise<any>;
|
|
699
|
+
/** @deprecated 2022-03-15 后不保证兼容;请优先使用 channelsPinsPut。 */
|
|
700
|
+
channelsAnnounces(channel_id: string, message_id: string): Promise<any>;
|
|
701
|
+
/** @deprecated 2022-03-15 后不保证兼容;请优先使用 channelsPinsDelete。 */
|
|
702
|
+
channelsAnnouncesDelete(channel_id: string, message_id: string): Promise<any>;
|
|
626
703
|
/**
|
|
627
704
|
* 撤回私信
|
|
628
705
|
* @param guild_id
|
|
@@ -735,7 +812,9 @@ declare class QQBotAPI {
|
|
|
735
812
|
* @param channel_id 子频道id
|
|
736
813
|
* @returns 返回 Schedule 对象数组(详见https://bot.q.qq.com/wiki/develop/api-v2/server-inter/channel/content/schedule/model.html#schedule)
|
|
737
814
|
*/
|
|
738
|
-
channelsSchedules(channel_id: string
|
|
815
|
+
channelsSchedules(channel_id: string, params?: {
|
|
816
|
+
since?: string;
|
|
817
|
+
}): Promise<any>;
|
|
739
818
|
/**
|
|
740
819
|
* 获取频道日程详情
|
|
741
820
|
* @param channel_id 子频道id
|
|
@@ -935,7 +1014,7 @@ declare class QQBotAPI {
|
|
|
935
1014
|
* @param code
|
|
936
1015
|
* @returns
|
|
937
1016
|
*/
|
|
938
|
-
interactionResponse(_mode: 'group' | 'guild',
|
|
1017
|
+
interactionResponse(_mode: 'group' | 'guild', interactionId: string, code?: number): Promise<unknown>;
|
|
939
1018
|
}
|
|
940
1019
|
//#endregion
|
|
941
1020
|
export { API_URL, API_URL_SANDBOX, BOTS_API_RUL, QQBotAPI, QQBotConnectionState, QQBotConnectionStatus, QQBotMediaHashes };
|
package/lib/sdk/api.js
CHANGED
|
@@ -17,6 +17,7 @@ var QQBotAPI = class {
|
|
|
17
17
|
config;
|
|
18
18
|
#msgMap = /* @__PURE__ */ new Map();
|
|
19
19
|
#streams = /* @__PURE__ */ new Map();
|
|
20
|
+
#interactionAcks = /* @__PURE__ */ new Map();
|
|
20
21
|
#onStreamClosed;
|
|
21
22
|
#onConnectionStatusChanged;
|
|
22
23
|
#connectionStatus = {
|
|
@@ -49,26 +50,30 @@ var QQBotAPI = class {
|
|
|
49
50
|
setStreamLifecycleListener(listener) {
|
|
50
51
|
this.#onStreamClosed = listener;
|
|
51
52
|
}
|
|
52
|
-
/** C2C
|
|
53
|
+
/** C2C input indicator; uses the same message protocol as the framework typing action. */
|
|
53
54
|
sendTyping(params) {
|
|
54
55
|
if (!params.userOpenId) throw new Error("userOpenId is required");
|
|
55
56
|
return this.groupService({
|
|
56
|
-
url: `/v2/users/${params.userOpenId}/
|
|
57
|
+
url: `/v2/users/${params.userOpenId}/messages`,
|
|
57
58
|
method: "post",
|
|
58
59
|
data: {
|
|
59
60
|
...params.msgId && { msg_id: params.msgId },
|
|
60
|
-
|
|
61
|
+
msg_type: 6,
|
|
62
|
+
input_notify: {
|
|
63
|
+
input_type: 1,
|
|
64
|
+
input_second: Math.max(1, Math.min(Number(params.durationSec) || 30, 60))
|
|
65
|
+
}
|
|
61
66
|
}
|
|
62
67
|
});
|
|
63
68
|
}
|
|
64
69
|
streamOpen(params) {
|
|
65
|
-
if (!params.userOpenId ||
|
|
70
|
+
if (!params.userOpenId || Boolean(params.msgId) === Boolean(params.eventId)) throw new Error("C2C streaming requires userOpenId and exactly one of msgId or eventId");
|
|
66
71
|
const streamId = randomUUID();
|
|
67
72
|
const stream = {
|
|
68
73
|
userOpenId: params.userOpenId,
|
|
69
74
|
msgId: params.msgId,
|
|
70
|
-
eventId: params.eventId
|
|
71
|
-
msgSeq: this.getMessageSeq(params.msgId),
|
|
75
|
+
eventId: params.eventId,
|
|
76
|
+
msgSeq: this.getMessageSeq(params.msgId || params.eventId),
|
|
72
77
|
index: 0,
|
|
73
78
|
lastSentAt: 0,
|
|
74
79
|
lastSentText: ""
|
|
@@ -80,8 +85,9 @@ var QQBotAPI = class {
|
|
|
80
85
|
async streamUpdate(streamId, fullText) {
|
|
81
86
|
const stream = this.#streams.get(streamId);
|
|
82
87
|
if (!stream) throw new Error("Unknown or expired streamId");
|
|
88
|
+
if (stream.closing) throw new Error("Stream is completing");
|
|
83
89
|
stream.latest = fullText;
|
|
84
|
-
if (
|
|
90
|
+
if (stream.sendTask === void 0) stream.sendTask = (async () => {
|
|
85
91
|
let result;
|
|
86
92
|
while (stream.latest !== void 0 && this.#streams.get(streamId) === stream) {
|
|
87
93
|
const content = stream.latest;
|
|
@@ -94,17 +100,20 @@ var QQBotAPI = class {
|
|
|
94
100
|
url: `/v2/users/${stream.userOpenId}/stream_messages`,
|
|
95
101
|
method: "post",
|
|
96
102
|
data: {
|
|
97
|
-
msg_id: stream.msgId,
|
|
98
|
-
event_id: stream.eventId,
|
|
103
|
+
...stream.msgId ? { msg_id: stream.msgId } : { event_id: stream.eventId },
|
|
99
104
|
msg_seq: stream.msgSeq,
|
|
100
|
-
index: stream.index
|
|
105
|
+
index: stream.index,
|
|
101
106
|
input_mode: "replace",
|
|
102
107
|
input_state: 1,
|
|
103
108
|
content_type: "markdown",
|
|
104
109
|
content_raw: content,
|
|
105
110
|
...stream.streamMessageId && { stream_msg_id: stream.streamMessageId }
|
|
106
111
|
}
|
|
112
|
+
}).catch((error) => {
|
|
113
|
+
stream.latest ??= content;
|
|
114
|
+
throw error;
|
|
107
115
|
});
|
|
116
|
+
stream.index++;
|
|
108
117
|
if (response?.id && !stream.streamMessageId) stream.streamMessageId = response.id;
|
|
109
118
|
stream.lastSentText = content;
|
|
110
119
|
result = response;
|
|
@@ -113,31 +122,40 @@ var QQBotAPI = class {
|
|
|
113
122
|
})().finally(() => {
|
|
114
123
|
if (this.#streams.get(streamId) === stream) stream.sendTask = void 0;
|
|
115
124
|
});
|
|
116
|
-
return stream.sendTask;
|
|
125
|
+
return await stream.sendTask;
|
|
117
126
|
}
|
|
118
127
|
async streamComplete(streamId) {
|
|
119
128
|
const stream = this.#streams.get(streamId);
|
|
120
129
|
if (!stream) throw new Error("Unknown or expired streamId");
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
130
|
+
if (stream.completeTask !== void 0) return await stream.completeTask;
|
|
131
|
+
stream.closing = true;
|
|
132
|
+
stream.completeTask = (async () => {
|
|
133
|
+
try {
|
|
134
|
+
await stream.sendTask;
|
|
135
|
+
if (this.#streams.get(streamId) !== stream) throw new Error("Unknown or expired streamId");
|
|
136
|
+
const response = await this.groupService({
|
|
137
|
+
url: `/v2/users/${stream.userOpenId}/stream_messages`,
|
|
138
|
+
method: "post",
|
|
139
|
+
data: {
|
|
140
|
+
...stream.msgId ? { msg_id: stream.msgId } : { event_id: stream.eventId },
|
|
141
|
+
msg_seq: stream.msgSeq,
|
|
142
|
+
index: stream.index,
|
|
143
|
+
input_mode: "replace",
|
|
144
|
+
input_state: 10,
|
|
145
|
+
content_type: "markdown",
|
|
146
|
+
content_raw: stream.latest ?? stream.lastSentText,
|
|
147
|
+
...stream.streamMessageId && { stream_msg_id: stream.streamMessageId }
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
this.streamCancel(streamId);
|
|
151
|
+
return response;
|
|
152
|
+
} catch (error) {
|
|
153
|
+
stream.closing = false;
|
|
154
|
+
stream.completeTask = void 0;
|
|
155
|
+
throw error;
|
|
156
|
+
}
|
|
157
|
+
})();
|
|
158
|
+
return await stream.completeTask;
|
|
141
159
|
}
|
|
142
160
|
streamCancel(streamId) {
|
|
143
161
|
const stream = this.#streams.get(streamId);
|
|
@@ -347,16 +365,24 @@ var QQBotAPI = class {
|
|
|
347
365
|
data: {
|
|
348
366
|
file_type: params.fileType,
|
|
349
367
|
file_name: params.name || "file",
|
|
350
|
-
file_size: total,
|
|
368
|
+
file_size: String(total),
|
|
351
369
|
md5: hashes.md5,
|
|
352
370
|
sha1: hashes.sha1,
|
|
353
371
|
md5_10m: hashes.md5_10m
|
|
354
372
|
}
|
|
355
373
|
});
|
|
374
|
+
const blockSize = Number(prepared.block_size);
|
|
375
|
+
if (!Number.isSafeInteger(blockSize) || blockSize <= 0 || !Array.isArray(prepared.parts) || prepared.parts.length !== Math.ceil(total / blockSize)) throw new Error("QQ returned an invalid upload partition");
|
|
376
|
+
const indexes = /* @__PURE__ */ new Set();
|
|
377
|
+
for (const part of prepared.parts) {
|
|
378
|
+
const length = Number(part.block_size);
|
|
379
|
+
if (!Number.isSafeInteger(part.index) || part.index < 0 || indexes.has(part.index) || !Number.isSafeInteger(length) || length <= 0 || length !== Math.min(blockSize, total - part.index * blockSize)) throw new Error(`QQ returned invalid upload part index/size: ${part.index}`);
|
|
380
|
+
indexes.add(part.index);
|
|
381
|
+
}
|
|
356
382
|
let uploaded = 0;
|
|
357
383
|
for (const part of prepared.parts || []) {
|
|
358
|
-
const offset =
|
|
359
|
-
const length =
|
|
384
|
+
const offset = part.index * blockSize;
|
|
385
|
+
const length = Number(part.block_size);
|
|
360
386
|
if (length <= 0) throw new Error(`QQ returned invalid upload part index: ${part.index}`);
|
|
361
387
|
const body = hasBuffer ? params.data.subarray(offset, offset + length) : void 0;
|
|
362
388
|
const partMd5 = body ? createHash("md5").update(body).digest("hex") : await this.#getFilePartHash(params.filePath, offset, length);
|
|
@@ -375,7 +401,7 @@ var QQBotAPI = class {
|
|
|
375
401
|
data: {
|
|
376
402
|
upload_id: prepared.upload_id,
|
|
377
403
|
part_index: part.index,
|
|
378
|
-
block_size: length,
|
|
404
|
+
block_size: String(length),
|
|
379
405
|
md5: partMd5
|
|
380
406
|
}
|
|
381
407
|
}));
|
|
@@ -383,9 +409,14 @@ var QQBotAPI = class {
|
|
|
383
409
|
params.onProgress?.(uploaded, total);
|
|
384
410
|
}
|
|
385
411
|
return this.#retry(() => this.groupService({
|
|
386
|
-
url: `${prefix}/
|
|
412
|
+
url: `${prefix}/files`,
|
|
387
413
|
method: "post",
|
|
388
|
-
data: {
|
|
414
|
+
data: {
|
|
415
|
+
upload_id: prepared.upload_id,
|
|
416
|
+
file_type: params.fileType,
|
|
417
|
+
file_name: params.name || "file",
|
|
418
|
+
srv_send_msg: params.send ?? false
|
|
419
|
+
}
|
|
389
420
|
}));
|
|
390
421
|
}
|
|
391
422
|
#getMediaBufferHashes(data) {
|
|
@@ -445,6 +476,95 @@ var QQBotAPI = class {
|
|
|
445
476
|
grouMessageDelte(group_openid, message_id) {
|
|
446
477
|
return this.groupMessageDelete(group_openid, message_id);
|
|
447
478
|
}
|
|
479
|
+
/** 生成添加机器人好友的分享链接。 */
|
|
480
|
+
generateUrlLink(data = {}) {
|
|
481
|
+
return this.groupService({
|
|
482
|
+
url: "/v2/generate_url_link",
|
|
483
|
+
method: "post",
|
|
484
|
+
data
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
menuGet() {
|
|
488
|
+
return this.groupService({
|
|
489
|
+
url: "/v2/menu",
|
|
490
|
+
method: "get"
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
menuPut(data) {
|
|
494
|
+
return this.groupService({
|
|
495
|
+
url: "/v2/menu",
|
|
496
|
+
method: "put",
|
|
497
|
+
data
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
panelsList(params) {
|
|
501
|
+
return this.groupService({
|
|
502
|
+
url: "/v2/panels",
|
|
503
|
+
method: "get",
|
|
504
|
+
params
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
panelsCreate(data) {
|
|
508
|
+
return this.groupService({
|
|
509
|
+
url: "/v2/panels",
|
|
510
|
+
method: "post",
|
|
511
|
+
data
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
panelsGet(panel_id) {
|
|
515
|
+
return this.groupService({
|
|
516
|
+
url: `/v2/panels/${panel_id}`,
|
|
517
|
+
method: "get"
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
panelsPut(panel_id, data) {
|
|
521
|
+
return this.groupService({
|
|
522
|
+
url: `/v2/panels/${panel_id}`,
|
|
523
|
+
method: "put",
|
|
524
|
+
data
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
panelsDelete(panel_id) {
|
|
528
|
+
return this.groupService({
|
|
529
|
+
url: `/v2/panels/${panel_id}`,
|
|
530
|
+
method: "delete"
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
panelsTargetPut(panel_id, data) {
|
|
534
|
+
return this.groupService({
|
|
535
|
+
url: `/v2/panels/${panel_id}/target`,
|
|
536
|
+
method: "put",
|
|
537
|
+
data
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
groupsMembers(group_openid, params) {
|
|
541
|
+
return this.groupService({
|
|
542
|
+
url: `/v2/groups/${group_openid}/members`,
|
|
543
|
+
method: "get",
|
|
544
|
+
params
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
groupsBatchRemoveMembers(group_openid, data) {
|
|
548
|
+
return this.groupService({
|
|
549
|
+
url: `/v2/groups/${group_openid}/batch_remove_members`,
|
|
550
|
+
method: "post",
|
|
551
|
+
data
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
groupsMemberBlacklist(group_openid, params) {
|
|
555
|
+
return this.groupService({
|
|
556
|
+
url: `/v2/groups/${group_openid}/member_blacklist`,
|
|
557
|
+
method: "get",
|
|
558
|
+
params
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
groupsMemberBlacklistPost(group_openid, data) {
|
|
562
|
+
return this.groupService({
|
|
563
|
+
url: `/v2/groups/${group_openid}/member_blacklist`,
|
|
564
|
+
method: "post",
|
|
565
|
+
data
|
|
566
|
+
});
|
|
567
|
+
}
|
|
448
568
|
/**
|
|
449
569
|
* 获取群基本信息
|
|
450
570
|
* @param group_openid 群 OpenID
|
|
@@ -1033,6 +1153,24 @@ var QQBotAPI = class {
|
|
|
1033
1153
|
}
|
|
1034
1154
|
});
|
|
1035
1155
|
}
|
|
1156
|
+
/** 获取子频道身份组权限。 */
|
|
1157
|
+
channelsRolePermissions(channel_id, role_id) {
|
|
1158
|
+
return this.guildServer({
|
|
1159
|
+
method: "GET",
|
|
1160
|
+
url: `/channels/${channel_id}/roles/${role_id}/permissions`
|
|
1161
|
+
});
|
|
1162
|
+
}
|
|
1163
|
+
/** 修改子频道身份组权限。 */
|
|
1164
|
+
channelsRolePermissionsPut(channel_id, role_id, add, remove) {
|
|
1165
|
+
return this.guildServer({
|
|
1166
|
+
method: "PUT",
|
|
1167
|
+
url: `/channels/${channel_id}/roles/${role_id}/permissions`,
|
|
1168
|
+
data: {
|
|
1169
|
+
add,
|
|
1170
|
+
remove
|
|
1171
|
+
}
|
|
1172
|
+
});
|
|
1173
|
+
}
|
|
1036
1174
|
/**
|
|
1037
1175
|
* *******
|
|
1038
1176
|
* 消息api
|
|
@@ -1065,10 +1203,37 @@ var QQBotAPI = class {
|
|
|
1065
1203
|
* @param source_guild_id 源频道 id
|
|
1066
1204
|
* @returns
|
|
1067
1205
|
*/
|
|
1068
|
-
usersMeDms() {
|
|
1206
|
+
usersMeDms(recipient_id, source_guild_id) {
|
|
1207
|
+
return this.guildServer({
|
|
1208
|
+
method: "POST",
|
|
1209
|
+
url: "/users/@me/dms",
|
|
1210
|
+
data: {
|
|
1211
|
+
recipient_id,
|
|
1212
|
+
source_guild_id
|
|
1213
|
+
}
|
|
1214
|
+
});
|
|
1215
|
+
}
|
|
1216
|
+
/** 申请频道接口权限,并向指定子频道发送授权链接。 */
|
|
1217
|
+
guildsApiPermissionDemand(guild_id, data) {
|
|
1218
|
+
return this.guildServer({
|
|
1219
|
+
method: "POST",
|
|
1220
|
+
url: `/guilds/${guild_id}/api_permission/demand`,
|
|
1221
|
+
data
|
|
1222
|
+
});
|
|
1223
|
+
}
|
|
1224
|
+
/** @deprecated 2022-03-15 后不保证兼容;请优先使用 channelsPinsPut。 */
|
|
1225
|
+
channelsAnnounces(channel_id, message_id) {
|
|
1069
1226
|
return this.guildServer({
|
|
1070
1227
|
method: "POST",
|
|
1071
|
-
url:
|
|
1228
|
+
url: `/channels/${channel_id}/announces`,
|
|
1229
|
+
data: { message_id }
|
|
1230
|
+
});
|
|
1231
|
+
}
|
|
1232
|
+
/** @deprecated 2022-03-15 后不保证兼容;请优先使用 channelsPinsDelete。 */
|
|
1233
|
+
channelsAnnouncesDelete(channel_id, message_id) {
|
|
1234
|
+
return this.guildServer({
|
|
1235
|
+
method: "DELETE",
|
|
1236
|
+
url: `/channels/${channel_id}/announces/${message_id}`
|
|
1072
1237
|
});
|
|
1073
1238
|
}
|
|
1074
1239
|
/**
|
|
@@ -1217,10 +1382,11 @@ var QQBotAPI = class {
|
|
|
1217
1382
|
* @param channel_id 子频道id
|
|
1218
1383
|
* @returns 返回 Schedule 对象数组(详见https://bot.q.qq.com/wiki/develop/api-v2/server-inter/channel/content/schedule/model.html#schedule)
|
|
1219
1384
|
*/
|
|
1220
|
-
channelsSchedules(channel_id) {
|
|
1385
|
+
channelsSchedules(channel_id, params) {
|
|
1221
1386
|
return this.guildServer({
|
|
1222
1387
|
method: "GET",
|
|
1223
|
-
url: `/channels/${channel_id}/schedules
|
|
1388
|
+
url: `/channels/${channel_id}/schedules`,
|
|
1389
|
+
params
|
|
1224
1390
|
});
|
|
1225
1391
|
}
|
|
1226
1392
|
/**
|
|
@@ -1470,12 +1636,42 @@ var QQBotAPI = class {
|
|
|
1470
1636
|
* @param code
|
|
1471
1637
|
* @returns
|
|
1472
1638
|
*/
|
|
1473
|
-
interactionResponse(_mode,
|
|
1474
|
-
return
|
|
1639
|
+
interactionResponse(_mode, interactionId, code = 0) {
|
|
1640
|
+
if (!interactionId || !Number.isInteger(code) || code < 0 || code > 5) return Promise.reject(/* @__PURE__ */ new Error("Invalid interaction ID or acknowledgement code"));
|
|
1641
|
+
const now = Date.now();
|
|
1642
|
+
for (const [id, entry] of this.#interactionAcks) if (entry.settled && entry.expiresAt <= now) this.#interactionAcks.delete(id);
|
|
1643
|
+
const existing = this.#interactionAcks.get(interactionId);
|
|
1644
|
+
if (existing) return existing.code === code ? existing.task : Promise.reject(/* @__PURE__ */ new Error("Interaction already acknowledged with a different code"));
|
|
1645
|
+
if (this.#interactionAcks.size >= 1024) {
|
|
1646
|
+
for (const [id, entry] of this.#interactionAcks) if (entry.settled) {
|
|
1647
|
+
this.#interactionAcks.delete(id);
|
|
1648
|
+
break;
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
const entry = {
|
|
1652
|
+
code,
|
|
1653
|
+
task: void 0,
|
|
1654
|
+
settled: false,
|
|
1655
|
+
expiresAt: now + 3e5
|
|
1656
|
+
};
|
|
1657
|
+
entry.task = Promise.resolve().then(() => this.groupService({
|
|
1475
1658
|
method: "PUT",
|
|
1476
|
-
url: `/interactions/${
|
|
1477
|
-
data: { code
|
|
1659
|
+
url: `/interactions/${interactionId}`,
|
|
1660
|
+
data: { code }
|
|
1661
|
+
})).then((response) => {
|
|
1662
|
+
entry.settled = true;
|
|
1663
|
+
entry.expiresAt = Date.now() + 3e5;
|
|
1664
|
+
for (const [id, previous] of this.#interactionAcks) {
|
|
1665
|
+
if (this.#interactionAcks.size <= 1024) break;
|
|
1666
|
+
if (previous.settled) this.#interactionAcks.delete(id);
|
|
1667
|
+
}
|
|
1668
|
+
return response;
|
|
1669
|
+
}, (error) => {
|
|
1670
|
+
this.#interactionAcks.delete(interactionId);
|
|
1671
|
+
throw error;
|
|
1478
1672
|
});
|
|
1673
|
+
this.#interactionAcks.set(interactionId, entry);
|
|
1674
|
+
return entry.task;
|
|
1479
1675
|
}
|
|
1480
1676
|
};
|
|
1481
1677
|
|
|
@@ -9,6 +9,7 @@ import { v4 } from "uuid";
|
|
|
9
9
|
//#region src/sdk/client.webhook.ts
|
|
10
10
|
const normalizeGatewayMessage = (message) => {
|
|
11
11
|
if (!message?.id || !message?.d || typeof message.d !== "object" || Array.isArray(message.d)) return message;
|
|
12
|
+
if (message.t === "INTERACTION_CREATE") message.d.event_id = message.id;
|
|
12
13
|
if (message.d.id === void 0 || message.d.id === null || message.d.id === "") message.d.id = message.id;
|
|
13
14
|
return message;
|
|
14
15
|
};
|
|
@@ -23,7 +24,7 @@ var QQBotClient = class extends QQBotAPI {
|
|
|
23
24
|
* @param opstion
|
|
24
25
|
*/
|
|
25
26
|
constructor(opstion) {
|
|
26
|
-
super(opstion);
|
|
27
|
+
super({ ...opstion });
|
|
27
28
|
}
|
|
28
29
|
/**
|
|
29
30
|
* 注册事件处理程序
|
|
@@ -6,6 +6,7 @@ import WebSocket$1 from "ws";
|
|
|
6
6
|
//#region src/sdk/client.websoket.ts
|
|
7
7
|
const normalizeGatewayMessage = (message) => {
|
|
8
8
|
if (!message?.id || !message?.d || typeof message.d !== "object" || Array.isArray(message.d)) return message;
|
|
9
|
+
if (message.t === "INTERACTION_CREATE") message.d.event_id = message.id;
|
|
9
10
|
if (message.d.id === void 0 || message.d.id === null || message.d.id === "") message.d.id = message.id;
|
|
10
11
|
return message;
|
|
11
12
|
};
|
|
@@ -37,7 +38,7 @@ var QQBotClients = class extends QQBotAPI {
|
|
|
37
38
|
* @param option
|
|
38
39
|
*/
|
|
39
40
|
constructor(option) {
|
|
40
|
-
super(option);
|
|
41
|
+
super({ ...option });
|
|
41
42
|
this.#sessionStore = option.sessionStore || new FileSessionStore();
|
|
42
43
|
}
|
|
43
44
|
async #loadSession() {
|
package/lib/sdk/intents.d.ts
CHANGED
package/lib/sdk/intents.js
CHANGED
package/lib/sdk/message.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { QQBotGroupEventMap } from "./message.group.js";
|
|
2
|
-
import { QQBotGuildEventMap } from "./message.guild.js";
|
|
3
2
|
import { QQBotPublicEventMap } from "./message.public.js";
|
|
3
|
+
import { QQBotGuildEventMap } from "./message.guild.js";
|
|
4
4
|
//#region src/sdk/message.d.ts
|
|
5
5
|
type QQBotEventMap = QQBotGroupEventMap & QQBotGuildEventMap & QQBotPublicEventMap;
|
|
6
6
|
//#endregion
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { SUBSCRIBE_MESSAGE_STATUS_TYPE } from "../message/group/SUBSCRIBE_MESSAGE_STATUS.js";
|
|
2
|
+
import { GROUP_MEMBER_ADD } from "../message/group/GROUP_MEMBER_ADD.js";
|
|
3
|
+
import { GROUP_MEMBER_REMOVE } from "../message/group/GROUP_MEMBER_REMOVE.js";
|
|
1
4
|
import { GROUP_AT_MESSAGE_CREATE_TYPE } from "../message/group/GROUP_AT_MESSAGE_CREATE.js";
|
|
2
5
|
import { GROUP_MESSAGE_CREATE_TYPE } from "../message/group/GROUP_MESSAGE_CREATE.js";
|
|
3
6
|
import { C2C_MESSAGE_CREATE_TYPE } from "../message/group/C2C_MESSAGE_CREATE.js";
|
|
@@ -13,10 +16,9 @@ import { MESSAGE_AUDIT_PASS_TYPE } from "../message/group/MESSAGE_AUDIT_PASS.js"
|
|
|
13
16
|
import { MESSAGE_AUDIT_REJECT_TYPE } from "../message/group/MESSAGE_AUDIT_REJECT.js";
|
|
14
17
|
import { GROUP_JOIN_REQUEST_TYPE } from "../message/group/GROUP_JOIN_REQUEST.js";
|
|
15
18
|
import { ERROR_TYPE } from "../message/ERROR.js";
|
|
16
|
-
import { GROUP_MEMBER_REMOVE } from "../message/group/GROUP_MEMBER_REMOVE.js";
|
|
17
|
-
import { GROUP_MEMBER_ADD } from "../message/group/GROUP_MEMBER_ADD.js";
|
|
18
19
|
//#region src/sdk/message.group.d.ts
|
|
19
20
|
type QQBotGroupEventMap = {
|
|
21
|
+
SUBSCRIBE_MESSAGE_STATUS: SUBSCRIBE_MESSAGE_STATUS_TYPE;
|
|
20
22
|
C2C_MESSAGE_CREATE: C2C_MESSAGE_CREATE_TYPE;
|
|
21
23
|
C2C_MSG_REJECT: C2C_MSG_REJECT_TYPE;
|
|
22
24
|
C2C_MSG_RECEIVE: C2C_MSG_RECEIVE_TYPE;
|