@zhin.js/adapter-wecom 5.0.0 → 5.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 +1 -1
- package/adapters/wecom.js +0 -3
- package/adapters/wecom.ts +0 -3
- package/agent/tools/get_dept_users.ts +4 -6
- package/agent/tools/get_user.ts +4 -6
- package/agent/tools/list_departments.ts +4 -6
- package/agent/tools/send_text.ts +4 -6
- package/lib/client.d.ts +12 -0
- package/lib/client.js +2 -0
- package/lib/endpoint.d.ts +20 -10
- package/lib/endpoint.js +33 -12
- package/lib/index.d.ts +2 -2
- package/lib/index.js +2 -2
- package/lib/protocol.d.ts +1 -1
- package/lib/protocol.js +1 -1
- package/lib/side-event-dispatch.d.ts +2 -2
- package/lib/side-event-dispatch.js +4 -4
- package/lib/wecom-endpoint-commands.d.ts +1 -1
- package/package.json +15 -14
- package/src/client.ts +16 -0
- package/src/endpoint.ts +38 -16
- package/src/index.ts +3 -7
- package/src/protocol.ts +1 -1
- package/src/side-event-dispatch.ts +5 -5
- package/lib/wecom-agent-deps.d.ts +0 -17
- package/lib/wecom-agent-deps.js +0 -30
- package/src/wecom-agent-deps.ts +0 -46
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @zhin.js/adapter-wecom
|
|
2
2
|
|
|
3
|
+
## 5.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 1fc78bc: Unify native platform Client access behind the literal `adapter` discriminant. Handlers infer both native events and Clients, while command, inbound/outbound middleware, and both Agent tool authoring surfaces expose the exact operation-scoped Client through a lazy `$client` getter. Definitions without `adapter` keep `$client` typed as `unknown`, and runtime dispatch rejects adapter mismatches before resolving the Client. Bundled platform tools now use this single path instead of model-provided endpoint ids and adapter-specific dependency wrappers. Every adapter registers one Client/EventMap contract, and protocol adapters including NapCat, Milky, OneBot and Satori now produce transport-independent Client objects rather than letting Endpoint instances impersonate Clients.
|
|
8
|
+
- Updated dependencies [e9c6a73]
|
|
9
|
+
- Updated dependencies [4e8117c]
|
|
10
|
+
- Updated dependencies [902fa35]
|
|
11
|
+
- Updated dependencies [54bfd6b]
|
|
12
|
+
- Updated dependencies [12025ee]
|
|
13
|
+
- Updated dependencies [09b14d6]
|
|
14
|
+
- Updated dependencies [1fc78bc]
|
|
15
|
+
- @zhin.js/agent@1.1.16
|
|
16
|
+
- @zhin.js/adapter@1.2.1
|
|
17
|
+
- @zhin.js/core@1.5.14
|
|
18
|
+
- @zhin.js/host-http@1.0.13
|
|
19
|
+
- @zhin.js/command@1.0.16
|
|
20
|
+
- @zhin.js/logger@1.0.77
|
|
21
|
+
- zhin.js@6.0.14
|
|
22
|
+
- @zhin.js/feature-kit@1.0.13
|
|
23
|
+
- @zhin.js/permission@1.0.4
|
|
24
|
+
|
|
3
25
|
## 5.0.0
|
|
4
26
|
|
|
5
27
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ pnpm add @zhin.js/adapter-wecom
|
|
|
18
18
|
## Plugin Runtime
|
|
19
19
|
|
|
20
20
|
- `@zhin.js/adapter` — 约定式 `adapters/wecom.ts`(`defineAdapter`)
|
|
21
|
-
- `@zhin.js/core` — `
|
|
21
|
+
- `@zhin.js/core` — `Endpoint.emit(...)` 入站、`outboundMessageToken` 出站
|
|
22
22
|
- `@zhin.js/host-http` — `httpHostToken` 注册 Webhook 路由(**非** legacy host-router/Koa)
|
|
23
23
|
- `zhin.js` — `plugin.ts`(`definePlugin`)
|
|
24
24
|
- 配置经插件 `schema.json` 落到 `plugins.<instanceKey>`
|
package/adapters/wecom.js
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
* Implementation lives under `src/` (endpoint / webhook / protocol).
|
|
5
5
|
*/
|
|
6
6
|
import { defineAdapter } from 'zhin.js/adapter';
|
|
7
|
-
import { messageGatewayToken, sideEventGatewayToken } from '@zhin.js/core/runtime';
|
|
8
7
|
import { httpHostToken } from '@zhin.js/host-http';
|
|
9
8
|
import { WecomEndpoint } from "../lib/endpoint.js";
|
|
10
9
|
import { resolveWecomConfig, } from "../lib/protocol.js";
|
|
@@ -28,8 +27,6 @@ export default defineAdapter({
|
|
|
28
27
|
});
|
|
29
28
|
return new WecomEndpoint({
|
|
30
29
|
id: context.id,
|
|
31
|
-
gateway: context.use(messageGatewayToken),
|
|
32
|
-
sideEvents: context.use(sideEventGatewayToken),
|
|
33
30
|
http: context.use(httpHostToken),
|
|
34
31
|
config,
|
|
35
32
|
});
|
package/adapters/wecom.ts
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
* Implementation lives under `src/` (endpoint / webhook / protocol).
|
|
4
4
|
*/
|
|
5
5
|
import { defineAdapter } from 'zhin.js/adapter';
|
|
6
|
-
import { messageGatewayToken, sideEventGatewayToken } from '@zhin.js/core/runtime';
|
|
7
6
|
import { httpHostToken } from '@zhin.js/host-http';
|
|
8
7
|
import { WecomEndpoint } from '../src/endpoint.js';
|
|
9
8
|
import {
|
|
@@ -33,8 +32,6 @@ export default defineAdapter<WecomAdapterConfig>({
|
|
|
33
32
|
});
|
|
34
33
|
return new WecomEndpoint({
|
|
35
34
|
id: context.id,
|
|
36
|
-
gateway: context.use(messageGatewayToken),
|
|
37
|
-
sideEvents: context.use(sideEventGatewayToken),
|
|
38
35
|
http: context.use(httpHostToken),
|
|
39
36
|
config,
|
|
40
37
|
});
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { defineAgentTool } from '@zhin.js/agent/tools';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
|
|
4
|
-
export default defineAgentTool<{ endpoint_id: string; dept_id: string }>({
|
|
3
|
+
export default defineAgentTool<{ dept_id: string }>({
|
|
5
4
|
description: '获取企业微信部门用户列表',
|
|
6
5
|
inputSchema: z.object({
|
|
7
|
-
endpoint_id: z.string().describe('Endpoint 名称'),
|
|
8
6
|
dept_id: z.string().describe('部门 ID'),
|
|
9
7
|
}),
|
|
10
|
-
|
|
8
|
+
adapter: 'wecom',
|
|
11
9
|
tags: ['wecom'],
|
|
12
|
-
async execute({
|
|
13
|
-
const endpoint =
|
|
10
|
+
async execute({ dept_id }: { dept_id: string }, context) {
|
|
11
|
+
const endpoint = context.$client;
|
|
14
12
|
const users = await endpoint.getDepartmentUsers(Number(dept_id));
|
|
15
13
|
return { users, count: users.length };
|
|
16
14
|
},
|
package/agent/tools/get_user.ts
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { defineAgentTool } from '@zhin.js/agent/tools';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
|
|
4
|
-
export default defineAgentTool<{ endpoint_id: string; user_id: string }>({
|
|
3
|
+
export default defineAgentTool<{ user_id: string }>({
|
|
5
4
|
description: '获取企业微信用户信息',
|
|
6
5
|
inputSchema: z.object({
|
|
7
|
-
endpoint_id: z.string().describe('Endpoint 名称'),
|
|
8
6
|
user_id: z.string().describe('用户 ID'),
|
|
9
7
|
}),
|
|
10
|
-
|
|
8
|
+
adapter: 'wecom',
|
|
11
9
|
tags: ['wecom'],
|
|
12
|
-
async execute({
|
|
13
|
-
const endpoint =
|
|
10
|
+
async execute({ user_id }: { user_id: string }, context) {
|
|
11
|
+
const endpoint = context.$client;
|
|
14
12
|
return await endpoint.getUserInfo(user_id);
|
|
15
13
|
},
|
|
16
14
|
});
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { defineAgentTool } from '@zhin.js/agent/tools';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
|
|
4
|
-
export default defineAgentTool<{ endpoint_id: string; dept_id?: string }>({
|
|
3
|
+
export default defineAgentTool<{ dept_id?: string }>({
|
|
5
4
|
description: '获取企业微信部门列表',
|
|
6
5
|
inputSchema: z.object({
|
|
7
|
-
endpoint_id: z.string().describe('Endpoint 名称'),
|
|
8
6
|
dept_id: z.string().optional().describe('父部门 ID,默认 1(根部门)'),
|
|
9
7
|
}),
|
|
10
|
-
|
|
8
|
+
adapter: 'wecom',
|
|
11
9
|
tags: ['wecom'],
|
|
12
|
-
async execute({
|
|
13
|
-
const endpoint =
|
|
10
|
+
async execute({ dept_id }: { dept_id?: string }, context) {
|
|
11
|
+
const endpoint = context.$client;
|
|
14
12
|
const departments = await endpoint.getDepartmentList(Number(dept_id) || 1);
|
|
15
13
|
return { departments, count: departments.length };
|
|
16
14
|
},
|
package/agent/tools/send_text.ts
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
import { defineAgentTool } from '@zhin.js/agent/tools';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
|
|
4
|
-
export default defineAgentTool<{ endpoint_id: string; user_id: string; content: string }>({
|
|
3
|
+
export default defineAgentTool<{ user_id: string; content: string }>({
|
|
5
4
|
description: '向指定企业微信用户发送文本消息',
|
|
6
5
|
inputSchema: z.object({
|
|
7
|
-
endpoint_id: z.string().describe('Endpoint 名称'),
|
|
8
6
|
user_id: z.string().describe('用户 ID'),
|
|
9
7
|
content: z.string().describe('消息内容'),
|
|
10
8
|
}),
|
|
11
|
-
|
|
9
|
+
adapter: 'wecom',
|
|
12
10
|
tags: ['wecom'],
|
|
13
|
-
async execute({
|
|
14
|
-
const endpoint =
|
|
11
|
+
async execute({ user_id, content }: { user_id: string; content: string }, context) {
|
|
12
|
+
const endpoint = context.$client;
|
|
15
13
|
const success = await endpoint.sendTextMessage(user_id, content);
|
|
16
14
|
return { success, message: success ? '消息已发送' : '发送失败' };
|
|
17
15
|
},
|
package/lib/client.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { WecomClient } from './endpoint.js';
|
|
2
|
+
import type { WecomMessage } from './protocol.js';
|
|
3
|
+
export type WecomClientEventMap = Record<string, WecomMessage>;
|
|
4
|
+
declare module '@zhin.js/feature-kit' {
|
|
5
|
+
interface AdapterClientRegistry {
|
|
6
|
+
readonly wecom: {
|
|
7
|
+
readonly client: WecomClient;
|
|
8
|
+
readonly events: WecomClientEventMap;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export declare const wecomClient: import("@zhin.js/adapter").EndpointClientToken<WecomClient, WecomClientEventMap>;
|
package/lib/client.js
ADDED
package/lib/endpoint.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
import { Endpoint } from 'zhin.js/adapter';
|
|
1
2
|
/**
|
|
2
3
|
* WecomEndpoint — lifecycle, outbound send, inbound admit, OpenAPI helpers for agent tools.
|
|
3
4
|
*/
|
|
4
|
-
import { type EndpointControl, type
|
|
5
|
-
import type { MessageGateway, SideEventGateway } from '@zhin.js/core/runtime';
|
|
5
|
+
import { type EndpointControl, type EndpointSendRequest } from 'zhin.js/adapter';
|
|
6
6
|
import type { HttpHost } from '@zhin.js/host-http';
|
|
7
7
|
import type { CapabilityId } from 'zhin.js';
|
|
8
|
-
import { type ResolvedWecomConfig, type
|
|
8
|
+
import { type ResolvedWecomConfig, type WecomMessage } from './protocol.js';
|
|
9
9
|
export type WecomFetch = (url: string, init?: {
|
|
10
10
|
readonly method?: string;
|
|
11
11
|
readonly headers?: Record<string, string>;
|
|
@@ -18,19 +18,33 @@ export type WecomFetch = (url: string, init?: {
|
|
|
18
18
|
}>;
|
|
19
19
|
export interface WecomEndpointOptions {
|
|
20
20
|
readonly id: CapabilityId;
|
|
21
|
-
readonly gateway: MessageGateway;
|
|
22
|
-
readonly sideEvents?: SideEventGateway;
|
|
23
21
|
readonly http: HttpHost;
|
|
24
22
|
readonly config: ResolvedWecomConfig;
|
|
25
23
|
readonly fetch?: WecomFetch;
|
|
26
24
|
}
|
|
25
|
+
export interface WecomClientApi {
|
|
26
|
+
getUserInfo(userId: string): Promise<unknown>;
|
|
27
|
+
getDepartmentUsers(deptId: number): Promise<unknown[]>;
|
|
28
|
+
getDepartmentList(deptId?: number): Promise<unknown[]>;
|
|
29
|
+
sendTextMessage(userId: string, content: string): Promise<boolean>;
|
|
30
|
+
}
|
|
31
|
+
/** WeCom API surface exposed to plugin events without Endpoint lifecycle methods. */
|
|
32
|
+
export declare class WecomClient implements WecomClientApi {
|
|
33
|
+
readonly api: WecomClientApi;
|
|
34
|
+
constructor(api: WecomClientApi);
|
|
35
|
+
getUserInfo: (userId: string) => Promise<unknown>;
|
|
36
|
+
getDepartmentUsers: (deptId: number) => Promise<unknown[]>;
|
|
37
|
+
getDepartmentList: (deptId?: number) => Promise<unknown[]>;
|
|
38
|
+
sendTextMessage: (userId: string, content: string) => Promise<boolean>;
|
|
39
|
+
}
|
|
27
40
|
/**
|
|
28
41
|
* 企业微信服务端 API 无 bot 群列表/群成员列表接口(客户群接口属「客户联系」
|
|
29
42
|
* 独立授权域,非 bot 社交面),好友/频道概念亦不存在;
|
|
30
43
|
* 因此本 endpoint 不暴露 EndpointManagement(Console 社交面 RPC 对该平台保持未接线)。
|
|
31
44
|
*/
|
|
32
|
-
export declare class WecomEndpoint
|
|
45
|
+
export declare class WecomEndpoint extends Endpoint<WecomClient> {
|
|
33
46
|
#private;
|
|
47
|
+
readonly client: WecomClient;
|
|
34
48
|
readonly control: EndpointControl;
|
|
35
49
|
constructor(options: WecomEndpointOptions);
|
|
36
50
|
/** Used by webhook handler. */
|
|
@@ -44,8 +58,4 @@ export declare class WecomEndpoint implements EndpointInstance {
|
|
|
44
58
|
recallMessage(messageId: string): Promise<void>;
|
|
45
59
|
/** Test / internal: admit a parsed message when open (non-webhook path). */
|
|
46
60
|
admit(msg: WecomMessage): void;
|
|
47
|
-
getUserInfo(userId: string): Promise<WecomApiResponse | null>;
|
|
48
|
-
getDepartmentUsers(deptId: number): Promise<unknown[]>;
|
|
49
|
-
getDepartmentList(deptId?: number): Promise<unknown[]>;
|
|
50
|
-
sendTextMessage(userId: string, content: string): Promise<boolean>;
|
|
51
61
|
}
|
package/lib/endpoint.js
CHANGED
|
@@ -1,19 +1,36 @@
|
|
|
1
|
+
import { Endpoint } from 'zhin.js/adapter';
|
|
1
2
|
/**
|
|
2
3
|
* WecomEndpoint — lifecycle, outbound send, inbound admit, OpenAPI helpers for agent tools.
|
|
3
4
|
*/
|
|
4
5
|
import { createRecallEndpointControl, } from 'zhin.js/adapter';
|
|
5
6
|
import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
|
|
6
|
-
import { registerWecomAgentEndpoint } from './wecom-agent-deps.js';
|
|
7
7
|
import { buildMediaUploadForm, readOutboundImageMedia, resolveMediaBinary, } from './media-upload.js';
|
|
8
8
|
import { buildSendRequestBody, formatInboundContent, formatOutboundBody, resolveChatType, wecomInboundConversation, } from './protocol.js';
|
|
9
9
|
import { registerWecomWebhookRoutes } from './webhook.js';
|
|
10
10
|
import { receiveWecomSideEvent } from './side-event-dispatch.js';
|
|
11
|
+
/** WeCom API surface exposed to plugin events without Endpoint lifecycle methods. */
|
|
12
|
+
export class WecomClient {
|
|
13
|
+
api;
|
|
14
|
+
constructor(api) {
|
|
15
|
+
this.api = api;
|
|
16
|
+
}
|
|
17
|
+
getUserInfo = (userId) => this.api.getUserInfo(userId);
|
|
18
|
+
getDepartmentUsers = (deptId) => this.api.getDepartmentUsers(deptId);
|
|
19
|
+
getDepartmentList = (deptId) => this.api.getDepartmentList(deptId);
|
|
20
|
+
sendTextMessage = (userId, content) => this.api.sendTextMessage(userId, content);
|
|
21
|
+
}
|
|
11
22
|
/**
|
|
12
23
|
* 企业微信服务端 API 无 bot 群列表/群成员列表接口(客户群接口属「客户联系」
|
|
13
24
|
* 独立授权域,非 bot 社交面),好友/频道概念亦不存在;
|
|
14
25
|
* 因此本 endpoint 不暴露 EndpointManagement(Console 社交面 RPC 对该平台保持未接线)。
|
|
15
26
|
*/
|
|
16
|
-
export class WecomEndpoint {
|
|
27
|
+
export class WecomEndpoint extends Endpoint {
|
|
28
|
+
client = new WecomClient({
|
|
29
|
+
getUserInfo: (userId) => this.#getUserInfo(userId),
|
|
30
|
+
getDepartmentUsers: (deptId) => this.#getDepartmentUsers(deptId),
|
|
31
|
+
getDepartmentList: (deptId) => this.#getDepartmentList(deptId),
|
|
32
|
+
sendTextMessage: (userId, content) => this.#sendTextMessage(userId, content),
|
|
33
|
+
});
|
|
17
34
|
#logger;
|
|
18
35
|
#options;
|
|
19
36
|
control = createRecallEndpointControl((id) => this.recallMessage(id));
|
|
@@ -23,8 +40,8 @@ export class WecomEndpoint {
|
|
|
23
40
|
#refreshPromise = null;
|
|
24
41
|
#open = false;
|
|
25
42
|
#started = false;
|
|
26
|
-
#unregisterAgent;
|
|
27
43
|
constructor(options) {
|
|
44
|
+
super();
|
|
28
45
|
this.#logger = getAdapterLogger('wecom', options.config.id);
|
|
29
46
|
this.#options = options;
|
|
30
47
|
this.#fetch = options.fetch ?? globalThis.fetch;
|
|
@@ -42,7 +59,6 @@ export class WecomEndpoint {
|
|
|
42
59
|
this.#started = true;
|
|
43
60
|
try {
|
|
44
61
|
await this.#refreshAccessToken();
|
|
45
|
-
this.#unregisterAgent = registerWecomAgentEndpoint(this.#options.config.id, this);
|
|
46
62
|
this.#routeReleases.push(...registerWecomWebhookRoutes(this.#options.http, this));
|
|
47
63
|
this.#logger.debug(formatCompact({
|
|
48
64
|
endpoint: this.#options.config.id,
|
|
@@ -66,8 +82,6 @@ export class WecomEndpoint {
|
|
|
66
82
|
this.#open = false;
|
|
67
83
|
for (const release of this.#routeReleases.splice(0))
|
|
68
84
|
release();
|
|
69
|
-
this.#unregisterAgent?.();
|
|
70
|
-
this.#unregisterAgent = undefined;
|
|
71
85
|
this.#started = false;
|
|
72
86
|
this.#logger.debug(formatCompact({ op: 'disconnect' }));
|
|
73
87
|
}
|
|
@@ -157,12 +171,19 @@ export class WecomEndpoint {
|
|
|
157
171
|
admit(msg) {
|
|
158
172
|
if (!this.#open)
|
|
159
173
|
return;
|
|
160
|
-
|
|
174
|
+
void this.emitPlatform(msg.Event || msg.MsgType || 'event', msg).catch((error) => {
|
|
175
|
+
this.#logger.warn(formatCompact({
|
|
176
|
+
op: 'wecom_platform_event_failed',
|
|
177
|
+
event: msg.Event || msg.MsgType,
|
|
178
|
+
error: error instanceof Error ? error.message : String(error),
|
|
179
|
+
}));
|
|
180
|
+
});
|
|
181
|
+
if (receiveWecomSideEvent((name, payload) => this.emit(name, payload), String(this.#options.id), this.#options.config.id, msg, this.#logger)) {
|
|
161
182
|
return;
|
|
162
183
|
}
|
|
163
184
|
const chatType = resolveChatType(msg.FromUserName);
|
|
164
185
|
const conversation = wecomInboundConversation(String(this.#options.id), msg);
|
|
165
|
-
void this
|
|
186
|
+
void this.emit('message.receive', {
|
|
166
187
|
conversation,
|
|
167
188
|
message: { conversation, id: msg.MsgId || `${msg.CreateTime}` },
|
|
168
189
|
content: formatInboundContent(msg),
|
|
@@ -183,7 +204,7 @@ export class WecomEndpoint {
|
|
|
183
204
|
}));
|
|
184
205
|
});
|
|
185
206
|
}
|
|
186
|
-
async getUserInfo(userId) {
|
|
207
|
+
async #getUserInfo(userId) {
|
|
187
208
|
try {
|
|
188
209
|
const data = await this.#request('/cgi-bin/user/get', {
|
|
189
210
|
params: { userid: userId },
|
|
@@ -197,7 +218,7 @@ export class WecomEndpoint {
|
|
|
197
218
|
return null;
|
|
198
219
|
}
|
|
199
220
|
}
|
|
200
|
-
async getDepartmentUsers(deptId) {
|
|
221
|
+
async #getDepartmentUsers(deptId) {
|
|
201
222
|
try {
|
|
202
223
|
const data = await this.#request('/cgi-bin/user/simplelist', {
|
|
203
224
|
params: { department_id: deptId },
|
|
@@ -211,7 +232,7 @@ export class WecomEndpoint {
|
|
|
211
232
|
return [];
|
|
212
233
|
}
|
|
213
234
|
}
|
|
214
|
-
async getDepartmentList(deptId = 1) {
|
|
235
|
+
async #getDepartmentList(deptId = 1) {
|
|
215
236
|
try {
|
|
216
237
|
const data = await this.#request('/cgi-bin/department/list', {
|
|
217
238
|
params: { id: deptId },
|
|
@@ -225,7 +246,7 @@ export class WecomEndpoint {
|
|
|
225
246
|
return [];
|
|
226
247
|
}
|
|
227
248
|
}
|
|
228
|
-
async sendTextMessage(userId, content) {
|
|
249
|
+
async #sendTextMessage(userId, content) {
|
|
229
250
|
try {
|
|
230
251
|
const endpointKey = String(this.#options.id);
|
|
231
252
|
await this.send({
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { buildSendRequestBody, decryptMessage, extractEncryptFromXml, formatInboundContent, formatOutboundBody, getAesKey, normalizeEchostrParam, normalizeWebhookPath, parseXmlMessage, queryParam, readTextBody, resolveChatType, resolveWecomConfig, verifySignature, type AccessToken, type ResolvedWecomConfig, type WecomAdapterConfig, type WecomApiResponse, type WecomMessage, type WecomSendBody, type WecomWireSegment, } from './protocol.js';
|
|
2
|
-
export {
|
|
2
|
+
export { wecomClient, type WecomClientEventMap } from './client.js';
|
|
3
3
|
export { checkWecomPlatformPermit, normalizeWecomSenderForPermit, platformPermit, wecomGroupPermitResolver, } from './platform-permit.js';
|
|
4
|
-
export { WecomEndpoint, type WecomEndpointOptions, type WecomFetch, } from './endpoint.js';
|
|
4
|
+
export { WecomClient, WecomEndpoint, type WecomClientApi, type WecomEndpointOptions, type WecomFetch, } from './endpoint.js';
|
|
5
5
|
export { buildMediaUploadForm, readOutboundImageMedia, resolveMediaBinary, type MediaBinary, type WecomMediaUploadResult, } from './media-upload.js';
|
|
6
6
|
export { registerWecomWebhookRoutes, handleWecomVerificationRequest, handleWecomWebhookRequest, type WecomWebhookHandler, } from './webhook.js';
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { buildSendRequestBody, decryptMessage, extractEncryptFromXml, formatInboundContent, formatOutboundBody, getAesKey, normalizeEchostrParam, normalizeWebhookPath, parseXmlMessage, queryParam, readTextBody, resolveChatType, resolveWecomConfig, verifySignature, } from './protocol.js';
|
|
2
|
-
export {
|
|
2
|
+
export { wecomClient } from './client.js';
|
|
3
3
|
export { checkWecomPlatformPermit, normalizeWecomSenderForPermit, platformPermit, wecomGroupPermitResolver, } from './platform-permit.js';
|
|
4
|
-
export { WecomEndpoint, } from './endpoint.js';
|
|
4
|
+
export { WecomClient, WecomEndpoint, } from './endpoint.js';
|
|
5
5
|
export { buildMediaUploadForm, readOutboundImageMedia, resolveMediaBinary, } from './media-upload.js';
|
|
6
6
|
export { registerWecomWebhookRoutes, handleWecomVerificationRequest, handleWecomWebhookRequest, } from './webhook.js';
|
package/lib/protocol.d.ts
CHANGED
|
@@ -84,7 +84,7 @@ export declare function verifySignature(token: string, timestamp: string, nonce:
|
|
|
84
84
|
export declare function decryptMessage(encrypted: string, encodingAESKey: string, corpId: string): string | null;
|
|
85
85
|
export declare function extractEncryptFromXml(xml: string): string | null;
|
|
86
86
|
export declare function parseXmlMessage(xml: string): WecomMessage | null;
|
|
87
|
-
/** Build inbound text for
|
|
87
|
+
/** Build inbound text for OutboundMessageService.receive. */
|
|
88
88
|
export declare function formatInboundContent(msg: WecomMessage): string;
|
|
89
89
|
export declare function resolveChatType(fromUserName: string): 'group' | 'private';
|
|
90
90
|
/**
|
package/lib/protocol.js
CHANGED
|
@@ -128,7 +128,7 @@ export function parseXmlMessage(xml) {
|
|
|
128
128
|
return null;
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
|
-
/** Build inbound text for
|
|
131
|
+
/** Build inbound text for OutboundMessageService.receive. */
|
|
132
132
|
export function formatInboundContent(msg) {
|
|
133
133
|
switch (msg.MsgType) {
|
|
134
134
|
case 'text':
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { EndpointEventEmitter } from 'zhin.js/adapter';
|
|
2
2
|
import { type getAdapterLogger } from '@zhin.js/logger';
|
|
3
3
|
import { type WecomMessage } from './protocol.js';
|
|
4
|
-
export declare function receiveWecomSideEvent(
|
|
4
|
+
export declare function receiveWecomSideEvent(emit: EndpointEventEmitter, endpointKey: string, configId: string, msg: WecomMessage, logger: ReturnType<typeof getAdapterLogger>): boolean;
|
|
@@ -13,12 +13,12 @@ function mapWecomEventParts(eventName) {
|
|
|
13
13
|
return { scene_type: 'wecom', sub_type: eventName || 'unknown' };
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
-
export function receiveWecomSideEvent(
|
|
17
|
-
if (
|
|
16
|
+
export function receiveWecomSideEvent(emit, endpointKey, configId, msg, logger) {
|
|
17
|
+
if (msg.MsgType !== 'event')
|
|
18
18
|
return false;
|
|
19
19
|
const eventName = msg.Event ?? 'unknown';
|
|
20
20
|
if (eventName === 'enter_agent') {
|
|
21
|
-
void
|
|
21
|
+
void emit('system.receive', buildSystem(msg, {
|
|
22
22
|
$id: `wecom:enter_agent:${msg.FromUserName}:${msg.CreateTime ?? Date.now()}`,
|
|
23
23
|
$adapter: 'wecom',
|
|
24
24
|
$endpoint: configId,
|
|
@@ -41,7 +41,7 @@ export function receiveWecomSideEvent(sideEvents, endpointKey, configId, msg, lo
|
|
|
41
41
|
if (!parts)
|
|
42
42
|
return false;
|
|
43
43
|
const sceneType = resolveChatType(msg.FromUserName);
|
|
44
|
-
void
|
|
44
|
+
void emit('notice.receive', buildNotice(msg, {
|
|
45
45
|
$id: `wecom:${eventName}:${msg.FromUserName}:${msg.CreateTime ?? Date.now()}`,
|
|
46
46
|
$adapter: 'wecom',
|
|
47
47
|
$endpoint: configId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const wecomEndpointCommands: import("@zhin.js/adapter").EndpointCommands<Readonly<import("@zhin.js/command").CommandDefinition<unknown, unknown, import("@zhin.js/command").CommandMessage>>>;
|
|
1
|
+
export declare const wecomEndpointCommands: import("@zhin.js/adapter").EndpointCommands<Readonly<import("@zhin.js/command").CommandDefinition<unknown, unknown, import("@zhin.js/command").CommandMessage, string | undefined>>>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/adapter-wecom",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.1",
|
|
4
4
|
"description": "Zhin.js WeCom (企业微信) adapter for Plugin Runtime (HTTP webhook)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -34,21 +34,22 @@
|
|
|
34
34
|
"directory": "plugins/adapters/wecom"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@zhin.js/adapter": "1.2.
|
|
38
|
-
"@zhin.js/core": "1.5.
|
|
39
|
-
"@zhin.js/
|
|
37
|
+
"@zhin.js/adapter": "1.2.1",
|
|
38
|
+
"@zhin.js/core": "1.5.14",
|
|
39
|
+
"@zhin.js/feature-kit": "1.0.13",
|
|
40
|
+
"@zhin.js/host-http": "1.0.13",
|
|
40
41
|
"@zhin.js/im-contract": "1.0.4",
|
|
41
|
-
"@zhin.js/logger": "1.0.
|
|
42
|
+
"@zhin.js/logger": "1.0.77"
|
|
42
43
|
},
|
|
43
44
|
"peerDependencies": {
|
|
44
45
|
"zod": "^4.0.0",
|
|
45
|
-
"@zhin.js/adapter": "1.2.
|
|
46
|
-
"@zhin.js/agent": "1.1.
|
|
47
|
-
"@zhin.js/command": "1.0.
|
|
48
|
-
"@zhin.js/core": "1.5.
|
|
49
|
-
"@zhin.js/host-http": "1.0.
|
|
50
|
-
"@zhin.js/permission": "1.0.
|
|
51
|
-
"zhin.js": "6.0.
|
|
46
|
+
"@zhin.js/adapter": "1.2.1",
|
|
47
|
+
"@zhin.js/agent": "1.1.16",
|
|
48
|
+
"@zhin.js/command": "1.0.16",
|
|
49
|
+
"@zhin.js/core": "1.5.14",
|
|
50
|
+
"@zhin.js/host-http": "1.0.13",
|
|
51
|
+
"@zhin.js/permission": "1.0.4",
|
|
52
|
+
"zhin.js": "6.0.14"
|
|
52
53
|
},
|
|
53
54
|
"peerDependenciesMeta": {
|
|
54
55
|
"@zhin.js/agent": {
|
|
@@ -69,8 +70,8 @@
|
|
|
69
70
|
"typescript": "^6.0.3",
|
|
70
71
|
"vitest": "^4.1.10",
|
|
71
72
|
"zod": "^4.4.3",
|
|
72
|
-
"@zhin.js/agent": "1.1.
|
|
73
|
-
"zhin.js": "6.0.
|
|
73
|
+
"@zhin.js/agent": "1.1.16",
|
|
74
|
+
"zhin.js": "6.0.14"
|
|
74
75
|
},
|
|
75
76
|
"files": [
|
|
76
77
|
"adapters",
|
package/src/client.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { defineEndpointClient } from 'zhin.js/adapter';
|
|
2
|
+
import type { WecomClient } from './endpoint.js';
|
|
3
|
+
import type { WecomMessage } from './protocol.js';
|
|
4
|
+
|
|
5
|
+
export type WecomClientEventMap = Record<string, WecomMessage>;
|
|
6
|
+
|
|
7
|
+
declare module '@zhin.js/feature-kit' {
|
|
8
|
+
interface AdapterClientRegistry {
|
|
9
|
+
readonly wecom: {
|
|
10
|
+
readonly client: WecomClient;
|
|
11
|
+
readonly events: WecomClientEventMap;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const wecomClient = defineEndpointClient<WecomClient, WecomClientEventMap>('wecom');
|
package/src/endpoint.ts
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
|
+
import { Endpoint } from 'zhin.js/adapter';
|
|
1
2
|
/**
|
|
2
3
|
* WecomEndpoint — lifecycle, outbound send, inbound admit, OpenAPI helpers for agent tools.
|
|
3
4
|
*/
|
|
4
5
|
import {
|
|
5
6
|
createRecallEndpointControl,
|
|
6
7
|
type EndpointControl,
|
|
7
|
-
type EndpointInstance,
|
|
8
8
|
type EndpointSendRequest,
|
|
9
9
|
} from 'zhin.js/adapter';
|
|
10
|
-
import type { MessageGateway, SideEventGateway } from '@zhin.js/core/runtime';
|
|
11
10
|
import type { HttpHost, HttpRouteRegistration } from '@zhin.js/host-http';
|
|
12
11
|
import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
|
|
13
12
|
import type { CapabilityId } from 'zhin.js';
|
|
14
|
-
import { registerWecomAgentEndpoint } from './wecom-agent-deps.js';
|
|
15
13
|
import {
|
|
16
14
|
buildMediaUploadForm,
|
|
17
15
|
readOutboundImageMedia,
|
|
@@ -48,19 +46,39 @@ export type WecomFetch = (
|
|
|
48
46
|
|
|
49
47
|
export interface WecomEndpointOptions {
|
|
50
48
|
readonly id: CapabilityId;
|
|
51
|
-
readonly gateway: MessageGateway;
|
|
52
|
-
readonly sideEvents?: SideEventGateway;
|
|
53
49
|
readonly http: HttpHost;
|
|
54
50
|
readonly config: ResolvedWecomConfig;
|
|
55
51
|
readonly fetch?: WecomFetch;
|
|
56
52
|
}
|
|
57
53
|
|
|
54
|
+
export interface WecomClientApi {
|
|
55
|
+
getUserInfo(userId: string): Promise<unknown>;
|
|
56
|
+
getDepartmentUsers(deptId: number): Promise<unknown[]>;
|
|
57
|
+
getDepartmentList(deptId?: number): Promise<unknown[]>;
|
|
58
|
+
sendTextMessage(userId: string, content: string): Promise<boolean>;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** WeCom API surface exposed to plugin events without Endpoint lifecycle methods. */
|
|
62
|
+
export class WecomClient implements WecomClientApi {
|
|
63
|
+
constructor(readonly api: WecomClientApi) {}
|
|
64
|
+
getUserInfo = (userId: string) => this.api.getUserInfo(userId);
|
|
65
|
+
getDepartmentUsers = (deptId: number) => this.api.getDepartmentUsers(deptId);
|
|
66
|
+
getDepartmentList = (deptId?: number) => this.api.getDepartmentList(deptId);
|
|
67
|
+
sendTextMessage = (userId: string, content: string) => this.api.sendTextMessage(userId, content);
|
|
68
|
+
}
|
|
69
|
+
|
|
58
70
|
/**
|
|
59
71
|
* 企业微信服务端 API 无 bot 群列表/群成员列表接口(客户群接口属「客户联系」
|
|
60
72
|
* 独立授权域,非 bot 社交面),好友/频道概念亦不存在;
|
|
61
73
|
* 因此本 endpoint 不暴露 EndpointManagement(Console 社交面 RPC 对该平台保持未接线)。
|
|
62
74
|
*/
|
|
63
|
-
export class WecomEndpoint
|
|
75
|
+
export class WecomEndpoint extends Endpoint<WecomClient> {
|
|
76
|
+
readonly client = new WecomClient({
|
|
77
|
+
getUserInfo: (userId) => this.#getUserInfo(userId),
|
|
78
|
+
getDepartmentUsers: (deptId) => this.#getDepartmentUsers(deptId),
|
|
79
|
+
getDepartmentList: (deptId) => this.#getDepartmentList(deptId),
|
|
80
|
+
sendTextMessage: (userId, content) => this.#sendTextMessage(userId, content),
|
|
81
|
+
});
|
|
64
82
|
readonly #logger!: ReturnType<typeof getAdapterLogger>;
|
|
65
83
|
|
|
66
84
|
readonly #options: WecomEndpointOptions;
|
|
@@ -71,9 +89,9 @@ export class WecomEndpoint implements EndpointInstance {
|
|
|
71
89
|
#refreshPromise: Promise<string> | null = null;
|
|
72
90
|
#open = false;
|
|
73
91
|
#started = false;
|
|
74
|
-
#unregisterAgent?: () => void;
|
|
75
92
|
|
|
76
93
|
constructor(options: WecomEndpointOptions) {
|
|
94
|
+
super();
|
|
77
95
|
this.#logger = getAdapterLogger('wecom', options.config.id);
|
|
78
96
|
this.#options = options;
|
|
79
97
|
this.#fetch = options.fetch ?? globalThis.fetch;
|
|
@@ -93,7 +111,6 @@ export class WecomEndpoint implements EndpointInstance {
|
|
|
93
111
|
this.#started = true;
|
|
94
112
|
try {
|
|
95
113
|
await this.#refreshAccessToken();
|
|
96
|
-
this.#unregisterAgent = registerWecomAgentEndpoint(this.#options.config.id, this);
|
|
97
114
|
this.#routeReleases.push(...registerWecomWebhookRoutes(this.#options.http, this));
|
|
98
115
|
this.#logger.debug(formatCompact({
|
|
99
116
|
endpoint: this.#options.config.id,
|
|
@@ -118,8 +135,6 @@ export class WecomEndpoint implements EndpointInstance {
|
|
|
118
135
|
async stop(): Promise<void> {
|
|
119
136
|
this.#open = false;
|
|
120
137
|
for (const release of this.#routeReleases.splice(0)) release();
|
|
121
|
-
this.#unregisterAgent?.();
|
|
122
|
-
this.#unregisterAgent = undefined;
|
|
123
138
|
this.#started = false;
|
|
124
139
|
this.#logger.debug(formatCompact({ op: 'disconnect' }));
|
|
125
140
|
}
|
|
@@ -210,8 +225,15 @@ export class WecomEndpoint implements EndpointInstance {
|
|
|
210
225
|
/** Test / internal: admit a parsed message when open (non-webhook path). */
|
|
211
226
|
admit(msg: WecomMessage): void {
|
|
212
227
|
if (!this.#open) return;
|
|
228
|
+
void this.emitPlatform(msg.Event || msg.MsgType || 'event', msg).catch((error) => {
|
|
229
|
+
this.#logger.warn(formatCompact({
|
|
230
|
+
op: 'wecom_platform_event_failed',
|
|
231
|
+
event: msg.Event || msg.MsgType,
|
|
232
|
+
error: error instanceof Error ? error.message : String(error),
|
|
233
|
+
}));
|
|
234
|
+
});
|
|
213
235
|
if (receiveWecomSideEvent(
|
|
214
|
-
this
|
|
236
|
+
(name, payload) => this.emit(name, payload),
|
|
215
237
|
String(this.#options.id),
|
|
216
238
|
this.#options.config.id,
|
|
217
239
|
msg,
|
|
@@ -221,7 +243,7 @@ export class WecomEndpoint implements EndpointInstance {
|
|
|
221
243
|
}
|
|
222
244
|
const chatType = resolveChatType(msg.FromUserName);
|
|
223
245
|
const conversation = wecomInboundConversation(String(this.#options.id), msg);
|
|
224
|
-
void this
|
|
246
|
+
void this.emit('message.receive', {
|
|
225
247
|
conversation,
|
|
226
248
|
message: { conversation, id: msg.MsgId || `${msg.CreateTime}` },
|
|
227
249
|
content: formatInboundContent(msg),
|
|
@@ -243,7 +265,7 @@ export class WecomEndpoint implements EndpointInstance {
|
|
|
243
265
|
});
|
|
244
266
|
}
|
|
245
267
|
|
|
246
|
-
async getUserInfo(userId: string): Promise<WecomApiResponse | null> {
|
|
268
|
+
async #getUserInfo(userId: string): Promise<WecomApiResponse | null> {
|
|
247
269
|
try {
|
|
248
270
|
const data = await this.#request('/cgi-bin/user/get', {
|
|
249
271
|
params: { userid: userId },
|
|
@@ -256,7 +278,7 @@ export class WecomEndpoint implements EndpointInstance {
|
|
|
256
278
|
}
|
|
257
279
|
}
|
|
258
280
|
|
|
259
|
-
async getDepartmentUsers(deptId: number): Promise<unknown[]> {
|
|
281
|
+
async #getDepartmentUsers(deptId: number): Promise<unknown[]> {
|
|
260
282
|
try {
|
|
261
283
|
const data = await this.#request('/cgi-bin/user/simplelist', {
|
|
262
284
|
params: { department_id: deptId },
|
|
@@ -269,7 +291,7 @@ export class WecomEndpoint implements EndpointInstance {
|
|
|
269
291
|
}
|
|
270
292
|
}
|
|
271
293
|
|
|
272
|
-
async getDepartmentList(deptId: number = 1): Promise<unknown[]> {
|
|
294
|
+
async #getDepartmentList(deptId: number = 1): Promise<unknown[]> {
|
|
273
295
|
try {
|
|
274
296
|
const data = await this.#request('/cgi-bin/department/list', {
|
|
275
297
|
params: { id: deptId },
|
|
@@ -282,7 +304,7 @@ export class WecomEndpoint implements EndpointInstance {
|
|
|
282
304
|
}
|
|
283
305
|
}
|
|
284
306
|
|
|
285
|
-
async sendTextMessage(userId: string, content: string): Promise<boolean> {
|
|
307
|
+
async #sendTextMessage(userId: string, content: string): Promise<boolean> {
|
|
286
308
|
try {
|
|
287
309
|
const endpointKey = String(this.#options.id);
|
|
288
310
|
await this.send({
|
package/src/index.ts
CHANGED
|
@@ -22,13 +22,7 @@ export {
|
|
|
22
22
|
type WecomWireSegment,
|
|
23
23
|
} from './protocol.js';
|
|
24
24
|
|
|
25
|
-
export {
|
|
26
|
-
getWecomAgentDeps,
|
|
27
|
-
registerWecomAgentEndpoint,
|
|
28
|
-
setWecomAgentDeps,
|
|
29
|
-
type WecomAgentDeps,
|
|
30
|
-
type WecomAgentEndpoint,
|
|
31
|
-
} from './wecom-agent-deps.js';
|
|
25
|
+
export { wecomClient, type WecomClientEventMap } from './client.js';
|
|
32
26
|
|
|
33
27
|
export {
|
|
34
28
|
checkWecomPlatformPermit,
|
|
@@ -38,7 +32,9 @@ export {
|
|
|
38
32
|
} from './platform-permit.js';
|
|
39
33
|
|
|
40
34
|
export {
|
|
35
|
+
WecomClient,
|
|
41
36
|
WecomEndpoint,
|
|
37
|
+
type WecomClientApi,
|
|
42
38
|
type WecomEndpointOptions,
|
|
43
39
|
type WecomFetch,
|
|
44
40
|
} from './endpoint.js';
|
package/src/protocol.ts
CHANGED
|
@@ -227,7 +227,7 @@ export function parseXmlMessage(xml: string): WecomMessage | null {
|
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
229
|
|
|
230
|
-
/** Build inbound text for
|
|
230
|
+
/** Build inbound text for OutboundMessageService.receive. */
|
|
231
231
|
export function formatInboundContent(msg: WecomMessage): string {
|
|
232
232
|
switch (msg.MsgType) {
|
|
233
233
|
case 'text':
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { buildNotice, buildSystem, senderFromId } from '@zhin.js/core';
|
|
2
|
-
import type {
|
|
2
|
+
import type { EndpointEventEmitter } from 'zhin.js/adapter';
|
|
3
3
|
import { formatCompact, type getAdapterLogger } from '@zhin.js/logger';
|
|
4
4
|
import { resolveChatType, type WecomMessage } from './protocol.js';
|
|
5
5
|
|
|
@@ -17,16 +17,16 @@ function mapWecomEventParts(eventName: string): { scene_type: string; sub_type:
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export function receiveWecomSideEvent(
|
|
20
|
-
|
|
20
|
+
emit: EndpointEventEmitter,
|
|
21
21
|
endpointKey: string,
|
|
22
22
|
configId: string,
|
|
23
23
|
msg: WecomMessage,
|
|
24
24
|
logger: ReturnType<typeof getAdapterLogger>,
|
|
25
25
|
): boolean {
|
|
26
|
-
if (
|
|
26
|
+
if (msg.MsgType !== 'event') return false;
|
|
27
27
|
const eventName = msg.Event ?? 'unknown';
|
|
28
28
|
if (eventName === 'enter_agent') {
|
|
29
|
-
void
|
|
29
|
+
void emit('system.receive', buildSystem(msg, {
|
|
30
30
|
$id: `wecom:enter_agent:${msg.FromUserName}:${msg.CreateTime ?? Date.now()}`,
|
|
31
31
|
$adapter: 'wecom' as never,
|
|
32
32
|
$endpoint: configId,
|
|
@@ -48,7 +48,7 @@ export function receiveWecomSideEvent(
|
|
|
48
48
|
const parts = mapWecomEventParts(eventName);
|
|
49
49
|
if (!parts) return false;
|
|
50
50
|
const sceneType = resolveChatType(msg.FromUserName);
|
|
51
|
-
void
|
|
51
|
+
void emit('notice.receive', buildNotice(msg, {
|
|
52
52
|
$id: `wecom:${eventName}:${msg.FromUserName}:${msg.CreateTime ?? Date.now()}`,
|
|
53
53
|
$adapter: 'wecom' as never,
|
|
54
54
|
$endpoint: configId,
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent tool deps for wecom (get_user / departments / send_text).
|
|
3
|
-
* Endpoints register themselves on start; tools look up by endpoint id.
|
|
4
|
-
*/
|
|
5
|
-
export interface WecomAgentEndpoint {
|
|
6
|
-
getUserInfo(userId: string): Promise<unknown>;
|
|
7
|
-
getDepartmentUsers(deptId: number): Promise<unknown[]>;
|
|
8
|
-
getDepartmentList(deptId?: number): Promise<unknown[]>;
|
|
9
|
-
sendTextMessage(userId: string, content: string): Promise<boolean>;
|
|
10
|
-
}
|
|
11
|
-
export interface WecomAgentDeps {
|
|
12
|
-
getEndpoint: (endpointKey: string) => WecomAgentEndpoint;
|
|
13
|
-
}
|
|
14
|
-
export declare function registerWecomAgentEndpoint(endpointKey: string, endpoint: WecomAgentEndpoint): () => void;
|
|
15
|
-
/** Optional override used by tests / transitional callers. Pass `null` to clear. */
|
|
16
|
-
export declare function setWecomAgentDeps(deps: WecomAgentDeps | null): void;
|
|
17
|
-
export declare function getWecomAgentDeps(): WecomAgentDeps;
|
package/lib/wecom-agent-deps.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent tool deps for wecom (get_user / departments / send_text).
|
|
3
|
-
* Endpoints register themselves on start; tools look up by endpoint id.
|
|
4
|
-
*/
|
|
5
|
-
const endpoints = new Map();
|
|
6
|
-
let override = null;
|
|
7
|
-
export function registerWecomAgentEndpoint(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 setWecomAgentDeps(deps) {
|
|
17
|
-
override = deps;
|
|
18
|
-
}
|
|
19
|
-
export function getWecomAgentDeps() {
|
|
20
|
-
if (override)
|
|
21
|
-
return override;
|
|
22
|
-
return {
|
|
23
|
-
getEndpoint(endpointKey) {
|
|
24
|
-
const endpoint = endpoints.get(endpointKey);
|
|
25
|
-
if (!endpoint)
|
|
26
|
-
throw new Error(`Endpoint ${endpointKey} 不存在`);
|
|
27
|
-
return endpoint;
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
}
|
package/src/wecom-agent-deps.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent tool deps for wecom (get_user / departments / send_text).
|
|
3
|
-
* Endpoints register themselves on start; tools look up by endpoint id.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export interface WecomAgentEndpoint {
|
|
7
|
-
getUserInfo(userId: string): Promise<unknown>;
|
|
8
|
-
getDepartmentUsers(deptId: number): Promise<unknown[]>;
|
|
9
|
-
getDepartmentList(deptId?: number): Promise<unknown[]>;
|
|
10
|
-
sendTextMessage(userId: string, content: string): Promise<boolean>;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface WecomAgentDeps {
|
|
14
|
-
getEndpoint: (endpointKey: string) => WecomAgentEndpoint;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const endpoints = new Map<string, WecomAgentEndpoint>();
|
|
18
|
-
let override: WecomAgentDeps | null = null;
|
|
19
|
-
|
|
20
|
-
export function registerWecomAgentEndpoint(
|
|
21
|
-
endpointKey: string,
|
|
22
|
-
endpoint: WecomAgentEndpoint,
|
|
23
|
-
): () => void {
|
|
24
|
-
endpoints.set(endpointKey, endpoint);
|
|
25
|
-
return () => {
|
|
26
|
-
if (endpoints.get(endpointKey) === endpoint) {
|
|
27
|
-
endpoints.delete(endpointKey);
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/** Optional override used by tests / transitional callers. Pass `null` to clear. */
|
|
33
|
-
export function setWecomAgentDeps(deps: WecomAgentDeps | null): void {
|
|
34
|
-
override = deps;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function getWecomAgentDeps(): WecomAgentDeps {
|
|
38
|
-
if (override) return override;
|
|
39
|
-
return {
|
|
40
|
-
getEndpoint(endpointKey) {
|
|
41
|
-
const endpoint = endpoints.get(endpointKey);
|
|
42
|
-
if (!endpoint) throw new Error(`Endpoint ${endpointKey} 不存在`);
|
|
43
|
-
return endpoint;
|
|
44
|
-
},
|
|
45
|
-
};
|
|
46
|
-
}
|