@zhin.js/adapter-napcat 6.0.14 → 7.0.1
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 +36 -0
- package/README.md +18 -3
- package/adapters/napcat.js +2 -8
- package/adapters/napcat.ts +2 -8
- package/agent/tools/ai_tts.ts +4 -6
- package/agent/tools/del_group_notice.ts +4 -6
- package/agent/tools/delete_essence_msg.ts +4 -6
- package/agent/tools/delete_friend.ts +4 -6
- package/agent/tools/download_file.ts +4 -6
- package/agent/tools/forward_single_msg.ts +4 -8
- package/agent/tools/get_ai_characters.ts +4 -6
- package/agent/tools/get_essence_list.ts +4 -6
- package/agent/tools/get_friend_msg_history.ts +4 -6
- package/agent/tools/get_group_file_url.ts +4 -6
- package/agent/tools/get_group_info_ex.ts +4 -6
- package/agent/tools/get_group_msg_history.ts +4 -6
- package/agent/tools/get_group_notice.ts +4 -6
- package/agent/tools/get_group_root_files.ts +4 -6
- package/agent/tools/get_group_shut_list.ts +4 -6
- package/agent/tools/get_mini_app_ark.ts +4 -6
- package/agent/tools/get_user_status.ts +4 -6
- package/agent/tools/group_sign.ts +4 -6
- package/agent/tools/mark_msg_as_read.ts +4 -6
- package/agent/tools/ocr_image.ts +4 -6
- package/agent/tools/send_forward_msg.ts +4 -8
- package/agent/tools/send_group_notice.ts +4 -6
- package/agent/tools/send_like.ts +4 -6
- package/agent/tools/send_poke.ts +4 -6
- package/agent/tools/set_avatar.ts +4 -6
- package/agent/tools/set_emoji_reaction.ts +4 -6
- package/agent/tools/set_essence_msg.ts +4 -6
- package/agent/tools/set_group_portrait.ts +4 -6
- package/agent/tools/set_online_status.ts +4 -6
- package/agent/tools/set_profile.ts +4 -6
- package/agent/tools/set_signature.ts +4 -6
- package/agent/tools/set_title.ts +4 -6
- package/agent/tools/translate.ts +4 -6
- package/agent/tools/upload_group_file.ts +4 -6
- package/lib/{napcat-agent-deps.d.ts → client.d.ts} +15 -14
- package/lib/client.js +62 -0
- package/lib/http-endpoint.d.ts +6 -6
- package/lib/http-endpoint.js +24 -12
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/napcat-endpoint-commands.d.ts +1 -1
- package/lib/side-event-dispatch.d.ts +2 -2
- package/lib/side-event-dispatch.js +3 -3
- package/lib/ws-endpoint.d.ts +6 -41
- package/lib/ws-endpoint.js +26 -157
- package/lib/wss-endpoint.d.ts +6 -6
- package/lib/wss-endpoint.js +25 -13
- package/package.json +15 -14
- package/src/client.ts +79 -0
- package/src/http-endpoint.ts +31 -20
- package/src/index.ts +4 -7
- package/src/side-event-dispatch.ts +4 -4
- package/src/ws-endpoint.ts +29 -202
- package/src/wss-endpoint.ts +32 -21
- package/lib/napcat-agent-deps.js +0 -33
- package/src/napcat-agent-deps.ts +0 -95
package/src/wss-endpoint.ts
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
+
import { Endpoint } from 'zhin.js/adapter';
|
|
1
2
|
/**
|
|
2
3
|
* NapCat reverse WSS endpoint — accepts inbound WebSocket from NapCat.
|
|
3
4
|
*/
|
|
4
5
|
import { clearInterval } from 'node:timers';
|
|
5
|
-
import
|
|
6
|
-
|
|
6
|
+
import {
|
|
7
|
+
createRecallEndpointControl,
|
|
8
|
+
type EndpointControl,
|
|
9
|
+
type EndpointManagement,
|
|
10
|
+
type EndpointSendRequest,
|
|
11
|
+
} from 'zhin.js/adapter';
|
|
7
12
|
import type { HttpHost, WsConnection } from '@zhin.js/host-http';
|
|
8
13
|
import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
|
|
9
14
|
import type { CapabilityId } from 'zhin.js';
|
|
10
15
|
import { createNapCatEndpointManagement } from './endpoint-management.js';
|
|
11
|
-
import { registerNapcatAgentEndpoint } from './napcat-agent-deps.js';
|
|
12
16
|
import {
|
|
13
17
|
InboundMessageDeduper,
|
|
14
18
|
isNapCatBotMentioned,
|
|
@@ -29,6 +33,7 @@ import {
|
|
|
29
33
|
} from './protocol.js';
|
|
30
34
|
import { receiveNapCatSideEvent } from './side-event-dispatch.js';
|
|
31
35
|
import { createNapCatContentPort } from './onebot-get-msg.js';
|
|
36
|
+
import { NapcatClient } from './client.js';
|
|
32
37
|
import {
|
|
33
38
|
callNapCatWsAction,
|
|
34
39
|
handleNapCatWsMessage,
|
|
@@ -44,19 +49,19 @@ import { verifyNapCatAccessToken } from './wss-auth.js';
|
|
|
44
49
|
|
|
45
50
|
export interface NapCatWssEndpointOptions {
|
|
46
51
|
readonly id: CapabilityId;
|
|
47
|
-
readonly gateway: MessageGateway;
|
|
48
|
-
readonly sideEvents?: SideEventGateway;
|
|
49
52
|
readonly http: HttpHost;
|
|
50
53
|
readonly config: NapCatWssConfig;
|
|
51
54
|
}
|
|
52
55
|
|
|
53
|
-
export class NapCatWssEndpoint
|
|
56
|
+
export class NapCatWssEndpoint extends Endpoint<NapcatClient> {
|
|
57
|
+
readonly client = new NapcatClient((action, params) => this.#callApi(action, params));
|
|
54
58
|
readonly #logger!: ReturnType<typeof getAdapterLogger>;
|
|
55
59
|
|
|
56
60
|
readonly #options: NapCatWssEndpointOptions;
|
|
57
61
|
readonly #inboundDeduper = new InboundMessageDeduper();
|
|
58
|
-
readonly management: EndpointManagement = createNapCatEndpointManagement(this);
|
|
59
|
-
readonly
|
|
62
|
+
readonly management: EndpointManagement = createNapCatEndpointManagement(this.client);
|
|
63
|
+
readonly control: EndpointControl = createRecallEndpointControl((id) => this.recallMessage(id));
|
|
64
|
+
readonly content = createNapCatContentPort((action, params) => this.client.callApi(action, params));
|
|
60
65
|
#ws?: NapCatWsSocket;
|
|
61
66
|
#wsRelease?: () => void;
|
|
62
67
|
#heartbeatTimer?: NodeJS.Timeout;
|
|
@@ -64,9 +69,9 @@ export class NapCatWssEndpoint implements EndpointInstance {
|
|
|
64
69
|
#pending = new Map<string, NapCatPendingAction>();
|
|
65
70
|
#open = false;
|
|
66
71
|
#started = false;
|
|
67
|
-
#unregisterAgent?: () => void;
|
|
68
72
|
|
|
69
73
|
constructor(options: NapCatWssEndpointOptions) {
|
|
74
|
+
super();
|
|
70
75
|
this.#logger = getAdapterLogger('napcat', options.config.id);
|
|
71
76
|
this.#options = options;
|
|
72
77
|
}
|
|
@@ -74,10 +79,6 @@ export class NapCatWssEndpoint implements EndpointInstance {
|
|
|
74
79
|
async start(): Promise<void> {
|
|
75
80
|
if (this.#started) return;
|
|
76
81
|
this.#started = true;
|
|
77
|
-
this.#unregisterAgent = registerNapcatAgentEndpoint(
|
|
78
|
-
this.#options.config.id,
|
|
79
|
-
this as unknown as NapCatWsEndpoint,
|
|
80
|
-
);
|
|
81
82
|
const handle = this.#options.http.ws(this.#options.config.path);
|
|
82
83
|
this.#wsRelease = handle.onConnection((connection) => {
|
|
83
84
|
this.#acceptConnection(connection);
|
|
@@ -100,8 +101,6 @@ export class NapCatWssEndpoint implements EndpointInstance {
|
|
|
100
101
|
|
|
101
102
|
async stop(): Promise<void> {
|
|
102
103
|
this.#open = false;
|
|
103
|
-
this.#unregisterAgent?.();
|
|
104
|
-
this.#unregisterAgent = undefined;
|
|
105
104
|
this.#wsRelease?.();
|
|
106
105
|
this.#wsRelease = undefined;
|
|
107
106
|
if (this.#heartbeatTimer) {
|
|
@@ -124,26 +123,32 @@ export class NapCatWssEndpoint implements EndpointInstance {
|
|
|
124
123
|
async send({ conversation, payload }: EndpointSendRequest): Promise<string> {
|
|
125
124
|
const message = formatOutboundSegments(payload);
|
|
126
125
|
const { action, params } = buildSendAction(napcatOutboundTarget(conversation), message);
|
|
127
|
-
const data = await this.callApi(action, params) as { message_id?: number | string } | undefined;
|
|
126
|
+
const data = await this.client.callApi(action, params) as { message_id?: number | string } | undefined;
|
|
128
127
|
return data?.message_id != null ? String(data.message_id) : '';
|
|
129
128
|
}
|
|
130
129
|
|
|
131
130
|
async recallMessage(messageId: string): Promise<void> {
|
|
132
131
|
if (!messageId) return;
|
|
133
|
-
await this.callApi('delete_msg', { message_id: Number(messageId) });
|
|
132
|
+
await this.client.callApi('delete_msg', { message_id: Number(messageId) });
|
|
134
133
|
}
|
|
135
134
|
|
|
136
|
-
callApi(action: string, params: Record<string, unknown> = {}): Promise<unknown> {
|
|
135
|
+
#callApi(action: string, params: Record<string, unknown> = {}): Promise<unknown> {
|
|
137
136
|
return callNapCatWsAction(this.#ws, this.#pending, this.#requestId, action, params);
|
|
138
137
|
}
|
|
139
138
|
|
|
140
139
|
admit(ev: NapCatEvent): void {
|
|
141
140
|
if (!this.#open) return;
|
|
141
|
+
void this.emitPlatform(napCatPlatformEventName(ev), ev).catch((error) => {
|
|
142
|
+
this.#logger.warn(formatCompact({
|
|
143
|
+
op: 'napcat_platform_event_failed',
|
|
144
|
+
error: error instanceof Error ? error.message : String(error),
|
|
145
|
+
}));
|
|
146
|
+
});
|
|
142
147
|
if (!isMessageEvent(ev)) {
|
|
143
148
|
receiveNapCatSideEvent(
|
|
144
|
-
this
|
|
149
|
+
(name, payload) => this.emit(name, payload),
|
|
145
150
|
this.#options.config.id,
|
|
146
|
-
this,
|
|
151
|
+
this.client,
|
|
147
152
|
ev,
|
|
148
153
|
this.#logger,
|
|
149
154
|
);
|
|
@@ -158,7 +163,7 @@ export class NapCatWssEndpoint implements EndpointInstance {
|
|
|
158
163
|
const conversation = napcatInboundConversation(String(this.#options.id), ev);
|
|
159
164
|
const nickname = senderNickname(ev);
|
|
160
165
|
const mentioned = isNapCatBotMentioned(ev);
|
|
161
|
-
void this
|
|
166
|
+
void this.emit('message.receive', {
|
|
162
167
|
conversation,
|
|
163
168
|
message: { conversation, id: msgId },
|
|
164
169
|
content: formatInboundContent(ev),
|
|
@@ -229,3 +234,9 @@ export class NapCatWssEndpoint implements EndpointInstance {
|
|
|
229
234
|
}));
|
|
230
235
|
}
|
|
231
236
|
}
|
|
237
|
+
|
|
238
|
+
function napCatPlatformEventName(ev: NapCatEvent): string {
|
|
239
|
+
return [ev.post_type, ev.message_type ?? ev.notice_type ?? ev.request_type, ev.sub_type]
|
|
240
|
+
.filter(Boolean)
|
|
241
|
+
.join('.');
|
|
242
|
+
}
|
package/lib/napcat-agent-deps.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent tool deps for napcat.
|
|
3
|
-
* Endpoints register themselves on start; tools look up by config name / endpoint id.
|
|
4
|
-
*/
|
|
5
|
-
const endpoints = new Map();
|
|
6
|
-
let override = null;
|
|
7
|
-
export function registerNapcatAgentEndpoint(endpointKey, endpoint) {
|
|
8
|
-
endpoints.set(endpointKey, endpoint);
|
|
9
|
-
return () => {
|
|
10
|
-
if (endpoints.get(endpointKey) === endpoint) {
|
|
11
|
-
endpoints.delete(endpointKey);
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
/** Optional override used by tests / transitional callers. Pass `null` to clear. */
|
|
16
|
-
export function setNapcatAgentDeps(deps) {
|
|
17
|
-
override = deps;
|
|
18
|
-
}
|
|
19
|
-
function lookup(endpointKey) {
|
|
20
|
-
const registered = endpoints.get(endpointKey);
|
|
21
|
-
if (!registered)
|
|
22
|
-
throw new Error(`Endpoint ${endpointKey} not found`);
|
|
23
|
-
return registered;
|
|
24
|
-
}
|
|
25
|
-
export function getNapcatAgentDeps() {
|
|
26
|
-
if (override)
|
|
27
|
-
return override;
|
|
28
|
-
return { getEndpoint: lookup };
|
|
29
|
-
}
|
|
30
|
-
/** Convenience for agent/tools (unchanged call sites). */
|
|
31
|
-
export function getEndpoint(endpointKey) {
|
|
32
|
-
return getNapcatAgentDeps().getEndpoint(endpointKey);
|
|
33
|
-
}
|
package/src/napcat-agent-deps.ts
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent tool deps for napcat.
|
|
3
|
-
* Endpoints register themselves on start; tools look up by config name / endpoint id.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export interface NapcatAgentEndpoint {
|
|
7
|
-
callApi(action: string, params?: Record<string, unknown>): Promise<unknown>;
|
|
8
|
-
setTitle(groupId: number, userId: number, title: string, duration?: number): Promise<boolean>;
|
|
9
|
-
sendLike(userId: number, times?: number): Promise<unknown>;
|
|
10
|
-
deleteFriend(userId: number): Promise<unknown>;
|
|
11
|
-
markMsgAsRead(messageId: number): Promise<unknown>;
|
|
12
|
-
ocrImage(image: string): Promise<unknown>;
|
|
13
|
-
setQQProfile(
|
|
14
|
-
nickname: string,
|
|
15
|
-
company?: string,
|
|
16
|
-
email?: string,
|
|
17
|
-
college?: string,
|
|
18
|
-
personalNote?: string,
|
|
19
|
-
): Promise<unknown>;
|
|
20
|
-
setGroupPortrait(groupId: number, file: string): Promise<unknown>;
|
|
21
|
-
setEssenceMsg(messageId: number): Promise<unknown>;
|
|
22
|
-
deleteEssenceMsg(messageId: number): Promise<unknown>;
|
|
23
|
-
getEssenceMsgList(groupId: number): Promise<unknown>;
|
|
24
|
-
sendGroupSign(groupId: number): Promise<unknown>;
|
|
25
|
-
sendGroupNotice(groupId: number, content: string, image?: string): Promise<unknown>;
|
|
26
|
-
getGroupNotice(groupId: number): Promise<unknown>;
|
|
27
|
-
deleteGroupNotice(groupId: number, noticeId: string): Promise<unknown>;
|
|
28
|
-
uploadGroupFile(groupId: number, file: string, name: string, folder?: string): Promise<unknown>;
|
|
29
|
-
getGroupRootFiles(groupId: number): Promise<unknown>;
|
|
30
|
-
getGroupFileUrl(groupId: number, fileId: string, busid: number): Promise<unknown>;
|
|
31
|
-
downloadFile(url: string, threadCount?: number, headers?: string[]): Promise<unknown>;
|
|
32
|
-
setOnlineStatus(status: number, extStatus: number): Promise<unknown>;
|
|
33
|
-
setQQAvatar(file: string): Promise<unknown>;
|
|
34
|
-
forwardFriendSingleMsg(userId: number, messageId: number): Promise<unknown>;
|
|
35
|
-
forwardGroupSingleMsg(groupId: number, messageId: number): Promise<unknown>;
|
|
36
|
-
translateEn2Zh(sourceText: string): Promise<unknown>;
|
|
37
|
-
setMsgEmojiLike(messageId: number, emojiId: string): Promise<unknown>;
|
|
38
|
-
sendForwardMsg(messageType: 'private' | 'group', id: number, messages: unknown[]): Promise<unknown>;
|
|
39
|
-
getFriendMsgHistory(userId: number, messageSeq?: number, count?: number): Promise<unknown>;
|
|
40
|
-
getGroupMsgHistory(groupId: number, messageSeq?: number, count?: number): Promise<unknown>;
|
|
41
|
-
setSelfLongnick(longnick: string): Promise<unknown>;
|
|
42
|
-
getGroupInfoEx(groupId: number): Promise<unknown>;
|
|
43
|
-
sendPoke(userId: number, groupId?: number): Promise<unknown>;
|
|
44
|
-
ncGetUserStatus(userId: number): Promise<unknown>;
|
|
45
|
-
getGroupShutList(groupId: number): Promise<unknown>;
|
|
46
|
-
getMiniAppArk(
|
|
47
|
-
type: string,
|
|
48
|
-
title: string,
|
|
49
|
-
desc: string,
|
|
50
|
-
picUrl: string,
|
|
51
|
-
jumpUrl: string,
|
|
52
|
-
): Promise<unknown>;
|
|
53
|
-
getAiCharacters(groupId: number): Promise<unknown>;
|
|
54
|
-
sendGroupAiRecord(groupId: number, characterId: string, text: string): Promise<unknown>;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export interface NapcatAgentDeps {
|
|
58
|
-
getEndpoint: (endpointKey: string) => NapcatAgentEndpoint;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const endpoints = new Map<string, NapcatAgentEndpoint>();
|
|
62
|
-
let override: NapcatAgentDeps | null = null;
|
|
63
|
-
|
|
64
|
-
export function registerNapcatAgentEndpoint(
|
|
65
|
-
endpointKey: string,
|
|
66
|
-
endpoint: NapcatAgentEndpoint,
|
|
67
|
-
): () => void {
|
|
68
|
-
endpoints.set(endpointKey, endpoint);
|
|
69
|
-
return () => {
|
|
70
|
-
if (endpoints.get(endpointKey) === endpoint) {
|
|
71
|
-
endpoints.delete(endpointKey);
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/** Optional override used by tests / transitional callers. Pass `null` to clear. */
|
|
77
|
-
export function setNapcatAgentDeps(deps: NapcatAgentDeps | null): void {
|
|
78
|
-
override = deps;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function lookup(endpointKey: string): NapcatAgentEndpoint {
|
|
82
|
-
const registered = endpoints.get(endpointKey);
|
|
83
|
-
if (!registered) throw new Error(`Endpoint ${endpointKey} not found`);
|
|
84
|
-
return registered;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export function getNapcatAgentDeps(): NapcatAgentDeps {
|
|
88
|
-
if (override) return override;
|
|
89
|
-
return { getEndpoint: lookup };
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/** Convenience for agent/tools (unchanged call sites). */
|
|
93
|
-
export function getEndpoint(endpointKey: string): NapcatAgentEndpoint {
|
|
94
|
-
return getNapcatAgentDeps().getEndpoint(endpointKey);
|
|
95
|
-
}
|