@zhin.js/adapter-qq 1.1.18 → 1.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -0
- package/README.md +21 -18
- package/adapters/qq/index.js +4 -38
- package/adapters/qq/index.ts +3 -46
- package/agents/qq/conversation.js +1 -1
- package/agents/qq/conversation.ts +1 -1
- package/agents/qq/skills/qq/tools/add_role/index.js +2 -1
- package/agents/qq/skills/qq/tools/add_role/index.ts +2 -1
- package/agents/qq/skills/qq/tools/channel_info/index.js +1 -1
- package/agents/qq/skills/qq/tools/channel_info/index.ts +1 -1
- package/agents/qq/skills/qq/tools/create_role/index.js +1 -1
- package/agents/qq/skills/qq/tools/create_role/index.ts +1 -1
- package/agents/qq/skills/qq/tools/guild_kick_member/index.js +1 -1
- package/agents/qq/skills/qq/tools/guild_kick_member/index.ts +1 -1
- package/agents/qq/skills/qq/tools/guild_mute_member/index.js +1 -1
- package/agents/qq/skills/qq/tools/guild_mute_member/index.ts +1 -1
- package/agents/qq/skills/qq/tools/list_channels/index.js +1 -1
- package/agents/qq/skills/qq/tools/list_channels/index.ts +1 -1
- package/agents/qq/skills/qq/tools/list_roles/index.js +1 -1
- package/agents/qq/skills/qq/tools/list_roles/index.ts +1 -1
- package/agents/qq/skills/qq/tools/member_detail/index.js +1 -1
- package/agents/qq/skills/qq/tools/member_detail/index.ts +1 -1
- package/agents/qq/skills/qq/tools/remove_role/index.js +2 -1
- package/agents/qq/skills/qq/tools/remove_role/index.ts +2 -1
- package/agents/qq/skills/qq-conversation/tools/conversation_info/index.js +1 -1
- package/agents/qq/skills/qq-conversation/tools/conversation_info/index.ts +1 -1
- package/agents/qq/skills/qq-directory/tools/list_guilds/index.js +1 -1
- package/agents/qq/skills/qq-directory/tools/list_guilds/index.ts +1 -1
- package/agents/qq/skills/qq-group-admin/tools/group_kick/index.js +2 -2
- package/agents/qq/skills/qq-group-admin/tools/group_kick/index.ts +2 -2
- package/agents/qq/skills/qq-group-admin/tools/handle_join_request/index.js +1 -1
- package/agents/qq/skills/qq-group-admin/tools/handle_join_request/index.ts +1 -1
- package/agents/qq/skills/qq-group-admin/tools/set_mute/index.js +2 -2
- package/agents/qq/skills/qq-group-admin/tools/set_mute/index.ts +2 -2
- package/agents/qq/skills/qq-group-directory/tools/group_info/index.js +1 -1
- package/agents/qq/skills/qq-group-directory/tools/group_info/index.ts +1 -1
- package/agents/qq/skills/qq-group-directory/tools/group_member_info/index.js +1 -1
- package/agents/qq/skills/qq-group-directory/tools/group_member_info/index.ts +1 -1
- package/agents/qq/skills/qq-group-directory/tools/group_members/index.js +1 -1
- package/agents/qq/skills/qq-group-directory/tools/group_members/index.ts +1 -1
- package/agents/qq/skills/qq-group-state/tools/group_blacklist/index.js +1 -1
- package/agents/qq/skills/qq-group-state/tools/group_blacklist/index.ts +1 -1
- package/agents/qq/skills/qq-group-state/tools/list_join_requests/index.js +1 -1
- package/agents/qq/skills/qq-group-state/tools/list_join_requests/index.ts +1 -1
- package/agents/qq/skills/qq-group-state/tools/list_muted/index.js +1 -1
- package/agents/qq/skills/qq-group-state/tools/list_muted/index.ts +1 -1
- package/commands/qq/endpoint/definition.js +41 -36
- package/commands/qq/endpoint/definition.ts +41 -67
- package/lib/adapter.d.ts +13 -0
- package/lib/adapter.js +27 -0
- package/lib/client.d.ts +7 -9
- package/lib/client.js +1 -2
- package/lib/console.d.ts +1 -6
- package/lib/console.js +29 -20
- package/lib/endpoint.d.ts +8 -27
- package/lib/endpoint.js +218 -165
- package/lib/group-admin.d.ts +14 -9
- package/lib/group-admin.js +21 -20
- package/lib/i18n.js +4 -4
- package/lib/image-size.d.ts +6 -1
- package/lib/image-size.js +2 -3
- package/lib/index.d.ts +5 -4
- package/lib/index.js +3 -3
- package/lib/interaction.js +1 -1
- package/lib/outbound.d.ts +4 -1
- package/lib/outbound.js +3 -2
- package/lib/protocol.d.ts +2 -0
- package/lib/qq-console-spec.js +12 -1
- package/lib/qq-console.d.ts +3 -4
- package/lib/qq-console.js +16 -6
- package/lib/qq-endpoint-write.d.ts +6 -10
- package/lib/qq-endpoint-write.js +5 -32
- package/lib/qq-runtime-state.d.ts +11 -10
- package/lib/qq-runtime-state.js +4 -5
- package/lib/qq-send.d.ts +7 -14
- package/lib/qq-send.js +20 -6
- package/lib/webhook.d.ts +3 -6
- package/lib/webhook.js +6 -49
- package/lib/ws.d.ts +10 -33
- package/lib/ws.js +21 -70
- package/middlewares/bot-kind-reply/index.js +1 -2
- package/middlewares/bot-kind-reply/index.ts +0 -2
- package/package.json +19 -19
- package/plugin.js +5 -5
- package/src/adapter.ts +23 -0
- package/src/client.ts +4 -12
- package/src/console.ts +27 -20
- package/src/endpoint.ts +218 -160
- package/src/group-admin.ts +28 -26
- package/src/i18n.ts +4 -4
- package/src/image-size.ts +7 -3
- package/src/index.ts +5 -5
- package/src/interaction.ts +1 -1
- package/src/outbound.ts +3 -2
- package/src/protocol.ts +2 -0
- package/src/qq-console-spec.ts +12 -1
- package/src/qq-console.ts +14 -8
- package/src/qq-endpoint-write.ts +10 -38
- package/src/qq-runtime-state.ts +11 -16
- package/src/qq-send.ts +28 -12
- package/src/webhook.ts +7 -57
- package/src/ws.ts +27 -105
package/src/ws.ts
CHANGED
|
@@ -42,50 +42,7 @@ export type QqOfficialApi = Pick<Bot,
|
|
|
42
42
|
| 'guild'
|
|
43
43
|
>;
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
export interface QqBotTransport {
|
|
47
|
-
readonly transportState?: EndpointTransportState;
|
|
48
|
-
/** Full qq-official-bot business API; lifecycle remains owned by the Endpoint. */
|
|
49
|
-
readonly api: QqOfficialApi;
|
|
50
|
-
start(): Promise<void>;
|
|
51
|
-
stop(): Promise<void>;
|
|
52
|
-
on(event: string, listener: (...args: unknown[]) => void): void;
|
|
53
|
-
removeAllListeners(): void;
|
|
54
|
-
/** `source` makes it a passive reply; without it the platform treats the message as active. */
|
|
55
|
-
sendPrivateMessage(userId: string, message: QqOutboundMessage, source?: QqReplySource, options?: QqSendOptions): Promise<unknown>;
|
|
56
|
-
sendGroupMessage(groupId: string, message: QqOutboundMessage, source?: QqReplySource, options?: QqSendOptions): Promise<unknown>;
|
|
57
|
-
sendGuildMessage(channelId: string, message: QqOutboundMessage, source?: QqReplySource, options?: QqSendOptions): Promise<unknown>;
|
|
58
|
-
sendDirectMessage?(guildId: string, message: QqOutboundMessage, source?: QqReplySource, options?: QqSendOptions): Promise<unknown>;
|
|
59
|
-
recallPrivateMessage?(userId: string, messageId: string): Promise<unknown>;
|
|
60
|
-
recallGroupMessage?(groupId: string, messageId: string): Promise<unknown>;
|
|
61
|
-
recallGuildMessage?(channelId: string, messageId: string): Promise<unknown>;
|
|
62
|
-
recallDirectMessage?(guildId: string, messageId: string): Promise<unknown>;
|
|
63
|
-
getGuilds(): Promise<unknown[]>;
|
|
64
|
-
getChannels(guildId: string): Promise<unknown[]>;
|
|
65
|
-
getChannelInfo(channelId: string): Promise<unknown>;
|
|
66
|
-
getGuildMember(guildId: string, userId: string): Promise<unknown>;
|
|
67
|
-
getGuildRoles(guildId: string): Promise<unknown[]>;
|
|
68
|
-
createGuildRole(guildId: string, name: string, color?: number): Promise<unknown>;
|
|
69
|
-
addMemberRole(
|
|
70
|
-
guildId: string,
|
|
71
|
-
channelId: string,
|
|
72
|
-
userId: string,
|
|
73
|
-
roleId: string,
|
|
74
|
-
): Promise<boolean>;
|
|
75
|
-
removeMemberRole(
|
|
76
|
-
guildId: string,
|
|
77
|
-
channelId: string,
|
|
78
|
-
userId: string,
|
|
79
|
-
roleId: string,
|
|
80
|
-
): Promise<boolean>;
|
|
81
|
-
approveGroupJoinRequest?(
|
|
82
|
-
groupId: string,
|
|
83
|
-
userId: string,
|
|
84
|
-
options: ApproveJoinRequestOptions,
|
|
85
|
-
): Promise<unknown>;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export type CreateQqBot = (config: ResolvedQqWebsocketConfig) => QqBotTransport;
|
|
45
|
+
export type QqBotTransport = Bot;
|
|
89
46
|
|
|
90
47
|
interface QqOfficialBotLifecycle {
|
|
91
48
|
stop(): Promise<unknown>;
|
|
@@ -134,6 +91,7 @@ export function normalizeQqMessage(raw: unknown): QqInboundMessage | null {
|
|
|
134
91
|
channel_id?: string | number;
|
|
135
92
|
guild_id?: string | number;
|
|
136
93
|
raw_message?: string;
|
|
94
|
+
timestamp?: number;
|
|
137
95
|
message?: unknown;
|
|
138
96
|
sender?: { user_id?: string | number; user_name?: string; roles?: (string | number)[] };
|
|
139
97
|
member?: { roles?: (string | number)[] };
|
|
@@ -186,6 +144,8 @@ export function normalizeQqMessage(raw: unknown): QqInboundMessage | null {
|
|
|
186
144
|
|
|
187
145
|
return {
|
|
188
146
|
id: String(msg.message_id),
|
|
147
|
+
event: raw,
|
|
148
|
+
...(typeof msg.timestamp === 'number' && Number.isFinite(msg.timestamp) ? { platformSentAt: msg.timestamp * 1_000 } : {}),
|
|
189
149
|
content,
|
|
190
150
|
channelKind,
|
|
191
151
|
channelId,
|
|
@@ -286,78 +246,40 @@ function extractTextContent(message: unknown): string {
|
|
|
286
246
|
.join('');
|
|
287
247
|
}
|
|
288
248
|
|
|
289
|
-
export function
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
secret: config.secret,
|
|
294
|
-
mode: ReceiverMode.WEBSOCKET,
|
|
295
|
-
sandbox: config.sandbox,
|
|
296
|
-
dataDir: path.join(process.cwd(), 'data', 'qq'),
|
|
297
|
-
// 关闭 qq-official-bot 内置 log4js,入/出站由 getAdapterLogger('qq', …) 统一格式
|
|
298
|
-
logLevel: 'off',
|
|
249
|
+
export function qqWebsocketBotOptions(config: ResolvedQqWebsocketConfig): ConstructorParameters<typeof Bot<ReceiverMode.WEBSOCKET>>[0] {
|
|
250
|
+
return { handleProcessErrors: false, appid: config.appid, secret: config.secret,
|
|
251
|
+
mode: ReceiverMode.WEBSOCKET, sandbox: config.sandbox,
|
|
252
|
+
dataDir: path.join(process.cwd(), 'data', 'qq'), logLevel: 'off',
|
|
299
253
|
...(config.intents ? { intents: config.intents as never } : {}),
|
|
300
254
|
...(config.accessTokenUrl ? { accessTokenUrl: config.accessTokenUrl } : {}),
|
|
301
255
|
...(config.gatewayUrl ? { gatewayUrl: config.gatewayUrl } : {}),
|
|
302
|
-
}
|
|
256
|
+
};
|
|
257
|
+
}
|
|
303
258
|
|
|
304
|
-
|
|
259
|
+
/** SDK 1.3.3 has no public receiver configuration/state accessor. This seam only reads its verified native fields. */
|
|
260
|
+
export function configureQqWebsocketReceiver(bot: Bot<ReceiverMode.WEBSOCKET>, config: ResolvedQqWebsocketConfig) {
|
|
261
|
+
const receiver = bot.receiver as unknown as {
|
|
262
|
+
config: { autoReconnect: boolean; agent?: import('node:https').Agent };
|
|
263
|
+
isReady?: boolean; isStarted?: boolean; isClosed?: boolean; handler?: { ws?: { readyState: number } };
|
|
264
|
+
};
|
|
305
265
|
receiver.config.autoReconnect = false;
|
|
306
266
|
const agent = config.streamProxy ? createQqStreamAgent(config.streamProxy) : undefined;
|
|
307
267
|
receiver.config.agent = agent;
|
|
308
|
-
const
|
|
309
|
-
|
|
310
|
-
const receiverError = () => {};
|
|
311
|
-
receiver.on('error', receiverError);
|
|
268
|
+
const observeError = () => undefined;
|
|
269
|
+
bot.receiver.on('error', observeError);
|
|
312
270
|
return {
|
|
313
|
-
|
|
314
|
-
const receiver = bot.receiver as unknown as { isReady?: boolean; isStarted?: boolean; isClosed?: boolean; handler?: { ws?: { readyState: number } } };
|
|
271
|
+
state(): EndpointTransportState {
|
|
315
272
|
const state = receiver.handler?.ws?.readyState;
|
|
316
273
|
if (state === 1 && receiver.isReady && receiver.isClosed === false) return 'open';
|
|
317
274
|
if (state === 0) return 'connecting';
|
|
318
|
-
|
|
319
|
-
return 'closed';
|
|
320
|
-
},
|
|
321
|
-
api: bot,
|
|
322
|
-
start: () => bot.start().then(() => undefined),
|
|
323
|
-
stop: async () => {
|
|
324
|
-
try { await stopQqOfficialBot(bot as unknown as QqOfficialBotLifecycle); }
|
|
325
|
-
finally { agent?.destroy(); }
|
|
275
|
+
return receiver.isStarted ? 'reconnecting' : 'closed';
|
|
326
276
|
},
|
|
327
|
-
|
|
328
|
-
if (event === 'transport.close') { receiver.on('close', listener); receiverListeners.push({ event: 'close', listener }); }
|
|
329
|
-
else bot.on(event as never, listener as never);
|
|
330
|
-
},
|
|
331
|
-
removeAllListeners: () => {
|
|
332
|
-
for (const entry of receiverListeners.splice(0)) receiver.removeListener(entry.event, entry.listener);
|
|
333
|
-
bot.removeAllListeners(undefined as never);
|
|
334
|
-
},
|
|
335
|
-
sendPrivateMessage: (userId, message, source, options) => bot.sendPrivateMessage(userId, message as Sendable, source, options),
|
|
336
|
-
sendGroupMessage: (groupId, message, source, options) => bot.sendGroupMessage(groupId, message as Sendable, source, options),
|
|
337
|
-
sendGuildMessage: (channelId, message, source, options) => bot.sendGuildMessage(channelId, message as Sendable, source, options),
|
|
338
|
-
sendDirectMessage: (guildId, message, source, options) => bot.sendDirectMessage(guildId, message as Sendable, source, options),
|
|
339
|
-
recallPrivateMessage: (userId, messageId) => bot.recallPrivateMessage(userId, messageId),
|
|
340
|
-
recallGroupMessage: (groupId, messageId) => bot.recallGroupMessage(groupId, messageId),
|
|
341
|
-
recallGuildMessage: (channelId, messageId) => bot.recallGuildMessage(channelId, messageId),
|
|
342
|
-
recallDirectMessage: (guildId, messageId) => bot.recallDirectMessage(guildId, messageId),
|
|
343
|
-
getGuilds: () => bot.guildService.getList(),
|
|
344
|
-
getChannels: (guildId) => bot.channelService.getList(guildId),
|
|
345
|
-
getChannelInfo: (channelId) => bot.channelService.getInfo(channelId),
|
|
346
|
-
getGuildMember: (guildId, userId) => bot.memberService.getGuildMemberInfo(guildId, userId),
|
|
347
|
-
getGuildRoles: (guildId) => bot.guildService.getRoles(guildId),
|
|
348
|
-
createGuildRole: (guildId, name, color) =>
|
|
349
|
-
bot.guildService.createRole(guildId, { name, color: color || 0, hoist: 0 }),
|
|
350
|
-
addMemberRole: async (guildId, channelId, userId, roleId) => {
|
|
351
|
-
await bot.memberService.addMemberRole(guildId, channelId, userId, roleId);
|
|
352
|
-
return true;
|
|
353
|
-
},
|
|
354
|
-
removeMemberRole: async (guildId, channelId, userId, roleId) => {
|
|
355
|
-
await bot.memberService.removeMemberRole(guildId, channelId, userId, roleId);
|
|
356
|
-
return true;
|
|
357
|
-
},
|
|
358
|
-
approveGroupJoinRequest: (groupId, userId, options) =>
|
|
359
|
-
(bot as { approveGroupJoinRequest?: QqBotTransport['approveGroupJoinRequest'] })
|
|
360
|
-
.approveGroupJoinRequest?.(groupId, userId, options)
|
|
361
|
-
?? Promise.reject(new Error('approveGroupJoinRequest is not available')),
|
|
277
|
+
dispose(): void { bot.receiver.off('error', observeError); agent?.destroy(); },
|
|
362
278
|
};
|
|
363
279
|
}
|
|
280
|
+
|
|
281
|
+
/** Session.stop leaves Auth refresh alive for reconnect; actual instance retirement destroys it. */
|
|
282
|
+
export function disposeQqAuthorization(bot: Bot): void {
|
|
283
|
+
const session = bot.sessionManager as unknown as { authManager: { destroy(): void } };
|
|
284
|
+
session.authManager.destroy();
|
|
285
|
+
}
|