@zhin.js/adapter-napcat 7.0.0 → 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 +22 -0
- package/README.md +18 -3
- package/adapters/napcat.js +1 -8
- package/adapters/napcat.ts +1 -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 +5 -6
- package/lib/http-endpoint.js +22 -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 +5 -41
- package/lib/ws-endpoint.js +24 -156
- package/lib/wss-endpoint.d.ts +5 -6
- package/lib/wss-endpoint.js +23 -13
- package/package.json +15 -14
- package/src/client.ts +79 -0
- package/src/http-endpoint.ts +24 -20
- package/src/index.ts +4 -7
- package/src/side-event-dispatch.ts +4 -4
- package/src/ws-endpoint.ts +26 -202
- package/src/wss-endpoint.ts +25 -21
- package/lib/napcat-agent-deps.js +0 -33
- package/src/napcat-agent-deps.ts +0 -95
package/src/wss-endpoint.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Endpoint } from 'zhin.js/adapter';
|
|
1
2
|
/**
|
|
2
3
|
* NapCat reverse WSS endpoint — accepts inbound WebSocket from NapCat.
|
|
3
4
|
*/
|
|
@@ -5,16 +6,13 @@ import { clearInterval } from 'node:timers';
|
|
|
5
6
|
import {
|
|
6
7
|
createRecallEndpointControl,
|
|
7
8
|
type EndpointControl,
|
|
8
|
-
type EndpointInstance,
|
|
9
9
|
type EndpointManagement,
|
|
10
10
|
type EndpointSendRequest,
|
|
11
11
|
} from 'zhin.js/adapter';
|
|
12
|
-
import type { MessageGateway, SideEventGateway } from '@zhin.js/core/runtime';
|
|
13
12
|
import type { HttpHost, WsConnection } from '@zhin.js/host-http';
|
|
14
13
|
import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
|
|
15
14
|
import type { CapabilityId } from 'zhin.js';
|
|
16
15
|
import { createNapCatEndpointManagement } from './endpoint-management.js';
|
|
17
|
-
import { registerNapcatAgentEndpoint } from './napcat-agent-deps.js';
|
|
18
16
|
import {
|
|
19
17
|
InboundMessageDeduper,
|
|
20
18
|
isNapCatBotMentioned,
|
|
@@ -35,6 +33,7 @@ import {
|
|
|
35
33
|
} from './protocol.js';
|
|
36
34
|
import { receiveNapCatSideEvent } from './side-event-dispatch.js';
|
|
37
35
|
import { createNapCatContentPort } from './onebot-get-msg.js';
|
|
36
|
+
import { NapcatClient } from './client.js';
|
|
38
37
|
import {
|
|
39
38
|
callNapCatWsAction,
|
|
40
39
|
handleNapCatWsMessage,
|
|
@@ -50,20 +49,19 @@ import { verifyNapCatAccessToken } from './wss-auth.js';
|
|
|
50
49
|
|
|
51
50
|
export interface NapCatWssEndpointOptions {
|
|
52
51
|
readonly id: CapabilityId;
|
|
53
|
-
readonly gateway: MessageGateway;
|
|
54
|
-
readonly sideEvents?: SideEventGateway;
|
|
55
52
|
readonly http: HttpHost;
|
|
56
53
|
readonly config: NapCatWssConfig;
|
|
57
54
|
}
|
|
58
55
|
|
|
59
|
-
export class NapCatWssEndpoint
|
|
56
|
+
export class NapCatWssEndpoint extends Endpoint<NapcatClient> {
|
|
57
|
+
readonly client = new NapcatClient((action, params) => this.#callApi(action, params));
|
|
60
58
|
readonly #logger!: ReturnType<typeof getAdapterLogger>;
|
|
61
59
|
|
|
62
60
|
readonly #options: NapCatWssEndpointOptions;
|
|
63
61
|
readonly #inboundDeduper = new InboundMessageDeduper();
|
|
64
|
-
readonly management: EndpointManagement = createNapCatEndpointManagement(this);
|
|
62
|
+
readonly management: EndpointManagement = createNapCatEndpointManagement(this.client);
|
|
65
63
|
readonly control: EndpointControl = createRecallEndpointControl((id) => this.recallMessage(id));
|
|
66
|
-
readonly content = createNapCatContentPort((action, params) => this.callApi(action, params));
|
|
64
|
+
readonly content = createNapCatContentPort((action, params) => this.client.callApi(action, params));
|
|
67
65
|
#ws?: NapCatWsSocket;
|
|
68
66
|
#wsRelease?: () => void;
|
|
69
67
|
#heartbeatTimer?: NodeJS.Timeout;
|
|
@@ -71,9 +69,9 @@ export class NapCatWssEndpoint implements EndpointInstance {
|
|
|
71
69
|
#pending = new Map<string, NapCatPendingAction>();
|
|
72
70
|
#open = false;
|
|
73
71
|
#started = false;
|
|
74
|
-
#unregisterAgent?: () => void;
|
|
75
72
|
|
|
76
73
|
constructor(options: NapCatWssEndpointOptions) {
|
|
74
|
+
super();
|
|
77
75
|
this.#logger = getAdapterLogger('napcat', options.config.id);
|
|
78
76
|
this.#options = options;
|
|
79
77
|
}
|
|
@@ -81,10 +79,6 @@ export class NapCatWssEndpoint implements EndpointInstance {
|
|
|
81
79
|
async start(): Promise<void> {
|
|
82
80
|
if (this.#started) return;
|
|
83
81
|
this.#started = true;
|
|
84
|
-
this.#unregisterAgent = registerNapcatAgentEndpoint(
|
|
85
|
-
this.#options.config.id,
|
|
86
|
-
this as unknown as NapCatWsEndpoint,
|
|
87
|
-
);
|
|
88
82
|
const handle = this.#options.http.ws(this.#options.config.path);
|
|
89
83
|
this.#wsRelease = handle.onConnection((connection) => {
|
|
90
84
|
this.#acceptConnection(connection);
|
|
@@ -107,8 +101,6 @@ export class NapCatWssEndpoint implements EndpointInstance {
|
|
|
107
101
|
|
|
108
102
|
async stop(): Promise<void> {
|
|
109
103
|
this.#open = false;
|
|
110
|
-
this.#unregisterAgent?.();
|
|
111
|
-
this.#unregisterAgent = undefined;
|
|
112
104
|
this.#wsRelease?.();
|
|
113
105
|
this.#wsRelease = undefined;
|
|
114
106
|
if (this.#heartbeatTimer) {
|
|
@@ -131,26 +123,32 @@ export class NapCatWssEndpoint implements EndpointInstance {
|
|
|
131
123
|
async send({ conversation, payload }: EndpointSendRequest): Promise<string> {
|
|
132
124
|
const message = formatOutboundSegments(payload);
|
|
133
125
|
const { action, params } = buildSendAction(napcatOutboundTarget(conversation), message);
|
|
134
|
-
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;
|
|
135
127
|
return data?.message_id != null ? String(data.message_id) : '';
|
|
136
128
|
}
|
|
137
129
|
|
|
138
130
|
async recallMessage(messageId: string): Promise<void> {
|
|
139
131
|
if (!messageId) return;
|
|
140
|
-
await this.callApi('delete_msg', { message_id: Number(messageId) });
|
|
132
|
+
await this.client.callApi('delete_msg', { message_id: Number(messageId) });
|
|
141
133
|
}
|
|
142
134
|
|
|
143
|
-
callApi(action: string, params: Record<string, unknown> = {}): Promise<unknown> {
|
|
135
|
+
#callApi(action: string, params: Record<string, unknown> = {}): Promise<unknown> {
|
|
144
136
|
return callNapCatWsAction(this.#ws, this.#pending, this.#requestId, action, params);
|
|
145
137
|
}
|
|
146
138
|
|
|
147
139
|
admit(ev: NapCatEvent): void {
|
|
148
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
|
+
});
|
|
149
147
|
if (!isMessageEvent(ev)) {
|
|
150
148
|
receiveNapCatSideEvent(
|
|
151
|
-
this
|
|
149
|
+
(name, payload) => this.emit(name, payload),
|
|
152
150
|
this.#options.config.id,
|
|
153
|
-
this,
|
|
151
|
+
this.client,
|
|
154
152
|
ev,
|
|
155
153
|
this.#logger,
|
|
156
154
|
);
|
|
@@ -165,7 +163,7 @@ export class NapCatWssEndpoint implements EndpointInstance {
|
|
|
165
163
|
const conversation = napcatInboundConversation(String(this.#options.id), ev);
|
|
166
164
|
const nickname = senderNickname(ev);
|
|
167
165
|
const mentioned = isNapCatBotMentioned(ev);
|
|
168
|
-
void this
|
|
166
|
+
void this.emit('message.receive', {
|
|
169
167
|
conversation,
|
|
170
168
|
message: { conversation, id: msgId },
|
|
171
169
|
content: formatInboundContent(ev),
|
|
@@ -236,3 +234,9 @@ export class NapCatWssEndpoint implements EndpointInstance {
|
|
|
236
234
|
}));
|
|
237
235
|
}
|
|
238
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
|
-
}
|