@chen0825/aiapp-ability 0.1.1 → 0.1.2
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/lib/abilities/dingtalk/index.d.ts +92 -0
- package/lib/abilities/dingtalk/index.js +242 -0
- package/lib/abilities/index.d.ts +5 -0
- package/lib/abilities/index.js +21 -0
- package/lib/abilities/registry.d.ts +69 -0
- package/lib/abilities/registry.js +111 -0
- package/lib/core/environment.d.ts +47 -0
- package/lib/core/environment.js +51 -0
- package/lib/core/http-client.d.ts +16 -0
- package/lib/core/http-client.js +77 -0
- package/lib/core/index.d.ts +5 -0
- package/lib/core/index.js +21 -0
- package/lib/index.d.ts +8 -0
- package/lib/index.js +30 -0
- package/lib/types/dingtalk.d.ts +80 -0
- package/lib/types/dingtalk.js +5 -0
- package/lib/types/index.d.ts +21 -0
- package/lib/types/index.js +21 -0
- package/lib/utils/index.d.ts +0 -0
- package/lib/utils/index.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 钉钉能力模块
|
|
3
|
+
*/
|
|
4
|
+
import { BatchSendRobotMsgRequest, BatchSendResponse, RobotMsgKey } from '../../types/dingtalk';
|
|
5
|
+
import { AbilityProvider } from '../../types';
|
|
6
|
+
/**
|
|
7
|
+
* 简化的 Markdown 通知参数
|
|
8
|
+
*/
|
|
9
|
+
export interface MarkdownNotificationParams {
|
|
10
|
+
/** 接收者用户 ID 列表 */
|
|
11
|
+
userIds: string[];
|
|
12
|
+
/** 消息标题 */
|
|
13
|
+
title: string;
|
|
14
|
+
/** Markdown 格式的消息内容 */
|
|
15
|
+
text: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* 通用批量发送参数
|
|
19
|
+
*/
|
|
20
|
+
export interface BatchNotificationParams<T extends RobotMsgKey = RobotMsgKey> {
|
|
21
|
+
/** 接收者用户 ID 列表 */
|
|
22
|
+
userIds: string[];
|
|
23
|
+
/** 消息类型 */
|
|
24
|
+
msgKey: T;
|
|
25
|
+
/** 消息参数 */
|
|
26
|
+
msgParam: Record<string, unknown>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 钉钉能力提供者
|
|
30
|
+
*
|
|
31
|
+
* 必须配置以下环境变量:
|
|
32
|
+
* - DINGTALK_APP_KEY: 钉钉应用 AppKey
|
|
33
|
+
* - DINGTALK_APP_SECRET: 钉钉应用 AppSecret
|
|
34
|
+
* - DINGTALK_ROBOT_CODE: 钉钉机器人编码
|
|
35
|
+
* - DINGTALK_API_URL: 钉钉 API 基础 URL
|
|
36
|
+
*/
|
|
37
|
+
export declare class DingTalkProvider implements AbilityProvider {
|
|
38
|
+
readonly name = "dingtalk";
|
|
39
|
+
readonly version = "1.0.0";
|
|
40
|
+
private dingtalkApiClient;
|
|
41
|
+
constructor();
|
|
42
|
+
/**
|
|
43
|
+
* 获取 appKey
|
|
44
|
+
*/
|
|
45
|
+
private getAppKey;
|
|
46
|
+
/**
|
|
47
|
+
* 获取 appSecret
|
|
48
|
+
*/
|
|
49
|
+
private getAppSecret;
|
|
50
|
+
/**
|
|
51
|
+
* 获取机器人编码
|
|
52
|
+
*/
|
|
53
|
+
private getRobotCode;
|
|
54
|
+
/**
|
|
55
|
+
* 获取 API 基础 URL
|
|
56
|
+
*/
|
|
57
|
+
private getApiUrl;
|
|
58
|
+
/**
|
|
59
|
+
* 获取企业内部应用的 accessToken(每次调用都重新获取)
|
|
60
|
+
*/
|
|
61
|
+
getAccessToken(): Promise<{
|
|
62
|
+
success: boolean;
|
|
63
|
+
accessToken?: string;
|
|
64
|
+
message?: string;
|
|
65
|
+
}>;
|
|
66
|
+
/**
|
|
67
|
+
* 批量发送机器人消息
|
|
68
|
+
*/
|
|
69
|
+
batchSendRobotMessage<T extends RobotMsgKey>(params: BatchSendRobotMsgRequest<T>): Promise<BatchSendResponse>;
|
|
70
|
+
/**
|
|
71
|
+
* 分批发送机器人消息(超过20人时自动分批)
|
|
72
|
+
*/
|
|
73
|
+
private batchSendInChunks;
|
|
74
|
+
/**
|
|
75
|
+
* 发送 Markdown 消息
|
|
76
|
+
*/
|
|
77
|
+
sendMarkdownMessage(params: MarkdownNotificationParams): Promise<BatchSendResponse>;
|
|
78
|
+
/**
|
|
79
|
+
* 通用批量发送接口
|
|
80
|
+
*/
|
|
81
|
+
sendBatchNotification<T extends RobotMsgKey>(params: BatchNotificationParams<T>): Promise<BatchSendResponse>;
|
|
82
|
+
/**
|
|
83
|
+
* 初始化(重新加载环境变量配置)
|
|
84
|
+
*/
|
|
85
|
+
initialize(): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* 将数组分割成指定大小的块
|
|
88
|
+
*/
|
|
89
|
+
private chunkArray;
|
|
90
|
+
}
|
|
91
|
+
/** 默认钉钉提供者实例 */
|
|
92
|
+
export declare const dingtalkProvider: DingTalkProvider;
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 钉钉能力模块
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.dingtalkProvider = exports.DingTalkProvider = void 0;
|
|
7
|
+
const http_client_1 = require("../../core/http-client");
|
|
8
|
+
const environment_1 = require("../../core/environment");
|
|
9
|
+
/** 钉钉API批量发送限制:每次最多20人 */
|
|
10
|
+
const BATCH_SEND_LIMIT = 20;
|
|
11
|
+
/**
|
|
12
|
+
* 钉钉能力提供者
|
|
13
|
+
*
|
|
14
|
+
* 必须配置以下环境变量:
|
|
15
|
+
* - DINGTALK_APP_KEY: 钉钉应用 AppKey
|
|
16
|
+
* - DINGTALK_APP_SECRET: 钉钉应用 AppSecret
|
|
17
|
+
* - DINGTALK_ROBOT_CODE: 钉钉机器人编码
|
|
18
|
+
* - DINGTALK_API_URL: 钉钉 API 基础 URL
|
|
19
|
+
*/
|
|
20
|
+
class DingTalkProvider {
|
|
21
|
+
constructor() {
|
|
22
|
+
this.name = 'dingtalk';
|
|
23
|
+
this.version = '1.0.0';
|
|
24
|
+
const envConfig = (0, environment_1.getDingTalkEnvConfig)();
|
|
25
|
+
this.dingtalkApiClient = new http_client_1.HttpClient(envConfig.apiUrl || 'https://api.dingtalk.com');
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 获取 appKey
|
|
29
|
+
*/
|
|
30
|
+
getAppKey() {
|
|
31
|
+
return (0, environment_1.getDingTalkEnvConfig)().appKey;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 获取 appSecret
|
|
35
|
+
*/
|
|
36
|
+
getAppSecret() {
|
|
37
|
+
return (0, environment_1.getDingTalkEnvConfig)().appSecret;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 获取机器人编码
|
|
41
|
+
*/
|
|
42
|
+
getRobotCode() {
|
|
43
|
+
return (0, environment_1.getDingTalkEnvConfig)().robotCode;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* 获取 API 基础 URL
|
|
47
|
+
*/
|
|
48
|
+
getApiUrl() {
|
|
49
|
+
return (0, environment_1.getDingTalkEnvConfig)().apiUrl || 'https://api.dingtalk.com';
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* 获取企业内部应用的 accessToken(每次调用都重新获取)
|
|
53
|
+
*/
|
|
54
|
+
async getAccessToken() {
|
|
55
|
+
const appKey = this.getAppKey();
|
|
56
|
+
const appSecret = this.getAppSecret();
|
|
57
|
+
if (!appKey || !appSecret) {
|
|
58
|
+
return {
|
|
59
|
+
success: false,
|
|
60
|
+
message: '未配置环境变量 DINGTALK_APP_KEY 或 DINGTALK_APP_SECRET',
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
const response = await fetch(`${this.getApiUrl()}/v1.0/oauth2/accessToken`, {
|
|
65
|
+
method: 'POST',
|
|
66
|
+
headers: {
|
|
67
|
+
'Content-Type': 'application/json',
|
|
68
|
+
},
|
|
69
|
+
body: JSON.stringify({ appKey, appSecret }),
|
|
70
|
+
});
|
|
71
|
+
if (!response.ok) {
|
|
72
|
+
const errorText = await response.text();
|
|
73
|
+
console.error('获取 accessToken 失败:', errorText);
|
|
74
|
+
return {
|
|
75
|
+
success: false,
|
|
76
|
+
message: `获取 accessToken 失败: ${response.status}`,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
const data = await response.json();
|
|
80
|
+
if (!data.accessToken) {
|
|
81
|
+
return {
|
|
82
|
+
success: false,
|
|
83
|
+
message: '获取 accessToken 失败: 响应中无 accessToken',
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
success: true,
|
|
88
|
+
accessToken: data.accessToken,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
console.error('获取 accessToken 异常:', error);
|
|
93
|
+
return {
|
|
94
|
+
success: false,
|
|
95
|
+
message: error instanceof Error ? error.message : '获取 accessToken 异常',
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* 批量发送机器人消息
|
|
101
|
+
*/
|
|
102
|
+
async batchSendRobotMessage(params) {
|
|
103
|
+
const tokenResult = await this.getAccessToken();
|
|
104
|
+
if (!tokenResult.success || !tokenResult.accessToken) {
|
|
105
|
+
return {
|
|
106
|
+
success: false,
|
|
107
|
+
message: tokenResult.message || '获取 accessToken 失败',
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
if (!params.userIds || params.userIds.length === 0) {
|
|
111
|
+
return {
|
|
112
|
+
success: false,
|
|
113
|
+
message: '接收者列表不能为空',
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
if (params.userIds.length > BATCH_SEND_LIMIT) {
|
|
117
|
+
return this.batchSendInChunks(params);
|
|
118
|
+
}
|
|
119
|
+
try {
|
|
120
|
+
const result = await this.dingtalkApiClient.post('/v1.0/robot/oToMessages/batchSend', params, {
|
|
121
|
+
headers: {
|
|
122
|
+
'x-acs-dingtalk-access-token': tokenResult.accessToken,
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
if (!result.success) {
|
|
126
|
+
return {
|
|
127
|
+
success: false,
|
|
128
|
+
message: result.message || '批量发送机器人消息失败',
|
|
129
|
+
data: result.data,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
success: true,
|
|
134
|
+
message: '批量发送成功',
|
|
135
|
+
data: result.data,
|
|
136
|
+
successCount: params.userIds.length,
|
|
137
|
+
failCount: 0,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
console.error('批量发送机器人消息异常:', error);
|
|
142
|
+
return {
|
|
143
|
+
success: false,
|
|
144
|
+
message: error instanceof Error ? error.message : '批量发送机器人消息异常',
|
|
145
|
+
failedUserIds: params.userIds,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* 分批发送机器人消息(超过20人时自动分批)
|
|
151
|
+
*/
|
|
152
|
+
async batchSendInChunks(params) {
|
|
153
|
+
const { userIds, ...restParams } = params;
|
|
154
|
+
const chunks = this.chunkArray(userIds, BATCH_SEND_LIMIT);
|
|
155
|
+
const failedUserIds = [];
|
|
156
|
+
let successCount = 0;
|
|
157
|
+
let failCount = 0;
|
|
158
|
+
for (const chunk of chunks) {
|
|
159
|
+
const chunkParams = {
|
|
160
|
+
...restParams,
|
|
161
|
+
userIds: chunk,
|
|
162
|
+
};
|
|
163
|
+
const result = await this.batchSendRobotMessage(chunkParams);
|
|
164
|
+
if (result.success) {
|
|
165
|
+
successCount += chunk.length;
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
failCount += chunk.length;
|
|
169
|
+
failedUserIds.push(...chunk);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
const allSuccess = failCount === 0;
|
|
173
|
+
return {
|
|
174
|
+
success: allSuccess,
|
|
175
|
+
message: allSuccess
|
|
176
|
+
? `批量发送成功,共 ${successCount} 人`
|
|
177
|
+
: `部分发送失败,成功 ${successCount} 人,失败 ${failCount} 人`,
|
|
178
|
+
successCount,
|
|
179
|
+
failCount,
|
|
180
|
+
failedUserIds: failedUserIds.length > 0 ? failedUserIds : undefined,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* 发送 Markdown 消息
|
|
185
|
+
*/
|
|
186
|
+
async sendMarkdownMessage(params) {
|
|
187
|
+
const robotCode = this.getRobotCode();
|
|
188
|
+
if (!robotCode) {
|
|
189
|
+
return {
|
|
190
|
+
success: false,
|
|
191
|
+
message: '未配置环境变量 DINGTALK_ROBOT_CODE',
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
return this.batchSendRobotMessage({
|
|
195
|
+
robotCode,
|
|
196
|
+
userIds: params.userIds,
|
|
197
|
+
msgKey: 'sampleMarkdown',
|
|
198
|
+
msgParam: JSON.stringify({
|
|
199
|
+
title: params.title,
|
|
200
|
+
text: params.text,
|
|
201
|
+
}),
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* 通用批量发送接口
|
|
206
|
+
*/
|
|
207
|
+
async sendBatchNotification(params) {
|
|
208
|
+
const robotCode = this.getRobotCode();
|
|
209
|
+
if (!robotCode) {
|
|
210
|
+
return {
|
|
211
|
+
success: false,
|
|
212
|
+
message: '未配置环境变量 DINGTALK_ROBOT_CODE',
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
return this.batchSendRobotMessage({
|
|
216
|
+
robotCode,
|
|
217
|
+
userIds: params.userIds,
|
|
218
|
+
msgKey: params.msgKey,
|
|
219
|
+
msgParam: JSON.stringify(params.msgParam),
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* 初始化(重新加载环境变量配置)
|
|
224
|
+
*/
|
|
225
|
+
async initialize() {
|
|
226
|
+
const envConfig = (0, environment_1.getDingTalkEnvConfig)();
|
|
227
|
+
this.dingtalkApiClient = new http_client_1.HttpClient(envConfig.apiUrl || 'https://api.dingtalk.com');
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* 将数组分割成指定大小的块
|
|
231
|
+
*/
|
|
232
|
+
chunkArray(array, size) {
|
|
233
|
+
const chunks = [];
|
|
234
|
+
for (let i = 0; i < array.length; i += size) {
|
|
235
|
+
chunks.push(array.slice(i, i + size));
|
|
236
|
+
}
|
|
237
|
+
return chunks;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
exports.DingTalkProvider = DingTalkProvider;
|
|
241
|
+
/** 默认钉钉提供者实例 */
|
|
242
|
+
exports.dingtalkProvider = new DingTalkProvider();
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 能力模块统一导出
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
17
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
__exportStar(require("./dingtalk"), exports);
|
|
21
|
+
__exportStar(require("./registry"), exports);
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 能力注册表模块
|
|
3
|
+
*/
|
|
4
|
+
import { AbilityProvider } from '../types';
|
|
5
|
+
/**
|
|
6
|
+
* 能力注册表配置
|
|
7
|
+
*/
|
|
8
|
+
export interface AbilityRegistryConfig {
|
|
9
|
+
/** 是否启用日志 */
|
|
10
|
+
enableLogging?: boolean;
|
|
11
|
+
/** 默认超时时间 */
|
|
12
|
+
defaultTimeout?: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* 能力注册表
|
|
16
|
+
*/
|
|
17
|
+
export declare class AbilityRegistry {
|
|
18
|
+
private providers;
|
|
19
|
+
private config;
|
|
20
|
+
constructor(config?: AbilityRegistryConfig);
|
|
21
|
+
/**
|
|
22
|
+
* 注册能力提供者
|
|
23
|
+
* @param provider 能力提供者
|
|
24
|
+
*/
|
|
25
|
+
register(provider: AbilityProvider): void;
|
|
26
|
+
/**
|
|
27
|
+
* 批量注册能力提供者
|
|
28
|
+
* @param providers 能力提供者数组
|
|
29
|
+
*/
|
|
30
|
+
registerAll(providers: AbilityProvider[]): void;
|
|
31
|
+
/**
|
|
32
|
+
* 获取能力提供者
|
|
33
|
+
* @param name 提供者名称
|
|
34
|
+
*/
|
|
35
|
+
get<T extends AbilityProvider = AbilityProvider>(name: string): T | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* 检查能力提供者是否已注册
|
|
38
|
+
* @param name 提供者名称
|
|
39
|
+
*/
|
|
40
|
+
has(name: string): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* 获取所有已注册的提供者名称
|
|
43
|
+
*/
|
|
44
|
+
getNames(): string[];
|
|
45
|
+
/**
|
|
46
|
+
* 获取所有已注册的提供者
|
|
47
|
+
*/
|
|
48
|
+
getAll(): AbilityProvider[];
|
|
49
|
+
/**
|
|
50
|
+
* 注销能力提供者
|
|
51
|
+
* @param name 提供者名称
|
|
52
|
+
*/
|
|
53
|
+
unregister(name: string): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* 清空所有能力提供者
|
|
56
|
+
*/
|
|
57
|
+
clear(): void;
|
|
58
|
+
/**
|
|
59
|
+
* 初始化所有已注册的提供者
|
|
60
|
+
*/
|
|
61
|
+
initializeAll(): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* 销毁所有已注册的提供者
|
|
64
|
+
*/
|
|
65
|
+
destroyAll(): Promise<void>;
|
|
66
|
+
private log;
|
|
67
|
+
}
|
|
68
|
+
/** 默认能力注册表实例 */
|
|
69
|
+
export declare const defaultRegistry: AbilityRegistry;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 能力注册表模块
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.defaultRegistry = exports.AbilityRegistry = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* 能力注册表
|
|
9
|
+
*/
|
|
10
|
+
class AbilityRegistry {
|
|
11
|
+
constructor(config = {}) {
|
|
12
|
+
this.providers = new Map();
|
|
13
|
+
this.config = {
|
|
14
|
+
enableLogging: false,
|
|
15
|
+
defaultTimeout: 30000,
|
|
16
|
+
...config,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 注册能力提供者
|
|
21
|
+
* @param provider 能力提供者
|
|
22
|
+
*/
|
|
23
|
+
register(provider) {
|
|
24
|
+
if (this.providers.has(provider.name)) {
|
|
25
|
+
throw new Error(`Provider "${provider.name}" is already registered`);
|
|
26
|
+
}
|
|
27
|
+
this.providers.set(provider.name, provider);
|
|
28
|
+
this.log(`Registered provider: ${provider.name}`);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 批量注册能力提供者
|
|
32
|
+
* @param providers 能力提供者数组
|
|
33
|
+
*/
|
|
34
|
+
registerAll(providers) {
|
|
35
|
+
for (const provider of providers) {
|
|
36
|
+
this.register(provider);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 获取能力提供者
|
|
41
|
+
* @param name 提供者名称
|
|
42
|
+
*/
|
|
43
|
+
get(name) {
|
|
44
|
+
return this.providers.get(name);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* 检查能力提供者是否已注册
|
|
48
|
+
* @param name 提供者名称
|
|
49
|
+
*/
|
|
50
|
+
has(name) {
|
|
51
|
+
return this.providers.has(name);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* 获取所有已注册的提供者名称
|
|
55
|
+
*/
|
|
56
|
+
getNames() {
|
|
57
|
+
return Array.from(this.providers.keys());
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* 获取所有已注册的提供者
|
|
61
|
+
*/
|
|
62
|
+
getAll() {
|
|
63
|
+
return Array.from(this.providers.values());
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* 注销能力提供者
|
|
67
|
+
* @param name 提供者名称
|
|
68
|
+
*/
|
|
69
|
+
unregister(name) {
|
|
70
|
+
const result = this.providers.delete(name);
|
|
71
|
+
if (result) {
|
|
72
|
+
this.log(`Unregistered provider: ${name}`);
|
|
73
|
+
}
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* 清空所有能力提供者
|
|
78
|
+
*/
|
|
79
|
+
clear() {
|
|
80
|
+
this.providers.clear();
|
|
81
|
+
this.log('Cleared all providers');
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* 初始化所有已注册的提供者
|
|
85
|
+
*/
|
|
86
|
+
async initializeAll() {
|
|
87
|
+
for (const provider of this.providers.values()) {
|
|
88
|
+
if (provider.initialize) {
|
|
89
|
+
await provider.initialize();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* 销毁所有已注册的提供者
|
|
95
|
+
*/
|
|
96
|
+
async destroyAll() {
|
|
97
|
+
for (const provider of this.providers.values()) {
|
|
98
|
+
if (provider.destroy) {
|
|
99
|
+
await provider.destroy();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
log(message) {
|
|
104
|
+
if (this.config.enableLogging) {
|
|
105
|
+
console.log(`[AbilityRegistry] ${message}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
exports.AbilityRegistry = AbilityRegistry;
|
|
110
|
+
/** 默认能力注册表实例 */
|
|
111
|
+
exports.defaultRegistry = new AbilityRegistry();
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 环境配置模块
|
|
3
|
+
*/
|
|
4
|
+
export interface EnvironmentConfig {
|
|
5
|
+
/** API 基础 URL */
|
|
6
|
+
apiUrl: string;
|
|
7
|
+
/** 当前环境 */
|
|
8
|
+
env: 'development' | 'production';
|
|
9
|
+
/** 应用 ID */
|
|
10
|
+
appId?: string;
|
|
11
|
+
/** 用户 ID */
|
|
12
|
+
userId?: string;
|
|
13
|
+
/** 租户 ID */
|
|
14
|
+
tenantId?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 钉钉环境配置
|
|
18
|
+
*/
|
|
19
|
+
export interface DingTalkEnvConfig {
|
|
20
|
+
/** 钉钉应用 AppKey */
|
|
21
|
+
appKey?: string;
|
|
22
|
+
/** 钉钉应用 AppSecret */
|
|
23
|
+
appSecret?: string;
|
|
24
|
+
/** 钉钉机器人编码 */
|
|
25
|
+
robotCode?: string;
|
|
26
|
+
/** 钉钉 API 基础 URL */
|
|
27
|
+
apiUrl?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 获取环境配置
|
|
31
|
+
* @returns 环境配置对象
|
|
32
|
+
*/
|
|
33
|
+
export declare function getEnvironmentConfig(): EnvironmentConfig;
|
|
34
|
+
/**
|
|
35
|
+
* 设置环境配置
|
|
36
|
+
* @param config 部分配置
|
|
37
|
+
*/
|
|
38
|
+
export declare function setEnvironmentConfig(config: Partial<EnvironmentConfig>): void;
|
|
39
|
+
/**
|
|
40
|
+
* 重置环境配置为默认值
|
|
41
|
+
*/
|
|
42
|
+
export declare function resetEnvironmentConfig(): void;
|
|
43
|
+
/**
|
|
44
|
+
* 获取钉钉环境配置(从环境变量)
|
|
45
|
+
* @returns 钉钉环境配置对象
|
|
46
|
+
*/
|
|
47
|
+
export declare function getDingTalkEnvConfig(): DingTalkEnvConfig;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getDingTalkEnvConfig = exports.resetEnvironmentConfig = exports.setEnvironmentConfig = exports.getEnvironmentConfig = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* 默认环境配置
|
|
6
|
+
*/
|
|
7
|
+
const defaultConfig = {
|
|
8
|
+
apiUrl: process.env.API_URL || '',
|
|
9
|
+
env: process.env.NODE_ENV || 'development',
|
|
10
|
+
appId: process.env.APP_ID,
|
|
11
|
+
userId: process.env.USER_ID,
|
|
12
|
+
tenantId: process.env.TENANT_ID,
|
|
13
|
+
};
|
|
14
|
+
/** 当前环境配置 */
|
|
15
|
+
let currentConfig = { ...defaultConfig };
|
|
16
|
+
/**
|
|
17
|
+
* 获取环境配置
|
|
18
|
+
* @returns 环境配置对象
|
|
19
|
+
*/
|
|
20
|
+
function getEnvironmentConfig() {
|
|
21
|
+
return { ...currentConfig };
|
|
22
|
+
}
|
|
23
|
+
exports.getEnvironmentConfig = getEnvironmentConfig;
|
|
24
|
+
/**
|
|
25
|
+
* 设置环境配置
|
|
26
|
+
* @param config 部分配置
|
|
27
|
+
*/
|
|
28
|
+
function setEnvironmentConfig(config) {
|
|
29
|
+
currentConfig = { ...currentConfig, ...config };
|
|
30
|
+
}
|
|
31
|
+
exports.setEnvironmentConfig = setEnvironmentConfig;
|
|
32
|
+
/**
|
|
33
|
+
* 重置环境配置为默认值
|
|
34
|
+
*/
|
|
35
|
+
function resetEnvironmentConfig() {
|
|
36
|
+
currentConfig = { ...defaultConfig };
|
|
37
|
+
}
|
|
38
|
+
exports.resetEnvironmentConfig = resetEnvironmentConfig;
|
|
39
|
+
/**
|
|
40
|
+
* 获取钉钉环境配置(从环境变量)
|
|
41
|
+
* @returns 钉钉环境配置对象
|
|
42
|
+
*/
|
|
43
|
+
function getDingTalkEnvConfig() {
|
|
44
|
+
return {
|
|
45
|
+
appKey: process.env.DINGTALK_APP_KEY,
|
|
46
|
+
appSecret: process.env.DINGTALK_APP_SECRET,
|
|
47
|
+
robotCode: process.env.DINGTALK_ROBOT_CODE,
|
|
48
|
+
apiUrl: process.env.DINGTALK_API_URL,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
exports.getDingTalkEnvConfig = getDingTalkEnvConfig;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { BaseResponse } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* HTTP 请求客户端
|
|
4
|
+
*/
|
|
5
|
+
export declare class HttpClient {
|
|
6
|
+
private baseUrl;
|
|
7
|
+
constructor(baseUrl: string);
|
|
8
|
+
/**
|
|
9
|
+
* 发送 POST 请求
|
|
10
|
+
*/
|
|
11
|
+
post<T = any>(endpoint: string, data: any, options?: RequestInit): Promise<BaseResponse<T>>;
|
|
12
|
+
/**
|
|
13
|
+
* 发送 GET 请求
|
|
14
|
+
*/
|
|
15
|
+
get<T = any>(endpoint: string, options?: RequestInit): Promise<BaseResponse<T>>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HttpClient = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* HTTP 请求客户端
|
|
6
|
+
*/
|
|
7
|
+
class HttpClient {
|
|
8
|
+
constructor(baseUrl) {
|
|
9
|
+
this.baseUrl = baseUrl;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* 发送 POST 请求
|
|
13
|
+
*/
|
|
14
|
+
async post(endpoint, data, options) {
|
|
15
|
+
try {
|
|
16
|
+
const response = await fetch(`${this.baseUrl}${endpoint}`, {
|
|
17
|
+
method: "POST",
|
|
18
|
+
headers: {
|
|
19
|
+
"Content-Type": "application/json",
|
|
20
|
+
...options?.headers,
|
|
21
|
+
},
|
|
22
|
+
body: JSON.stringify(data),
|
|
23
|
+
...options,
|
|
24
|
+
});
|
|
25
|
+
if (!response.ok) {
|
|
26
|
+
return {
|
|
27
|
+
success: false,
|
|
28
|
+
message: "请求异常",
|
|
29
|
+
data: undefined,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const result = await response.json();
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
console.error("HTTP请求失败:", error);
|
|
37
|
+
return {
|
|
38
|
+
success: false,
|
|
39
|
+
message: error instanceof Error ? error.message : "请求失败",
|
|
40
|
+
data: undefined,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 发送 GET 请求
|
|
46
|
+
*/
|
|
47
|
+
async get(endpoint, options) {
|
|
48
|
+
try {
|
|
49
|
+
const response = await fetch(`${this.baseUrl}${endpoint}`, {
|
|
50
|
+
method: "GET",
|
|
51
|
+
headers: {
|
|
52
|
+
"Content-Type": "application/json",
|
|
53
|
+
...options?.headers,
|
|
54
|
+
},
|
|
55
|
+
...options,
|
|
56
|
+
});
|
|
57
|
+
if (!response.ok) {
|
|
58
|
+
return {
|
|
59
|
+
success: false,
|
|
60
|
+
message: "请求异常",
|
|
61
|
+
data: undefined,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
const result = await response.json();
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
console.error("HTTP请求失败:", error);
|
|
69
|
+
return {
|
|
70
|
+
success: false,
|
|
71
|
+
message: error instanceof Error ? error.message : "请求失败",
|
|
72
|
+
data: undefined,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.HttpClient = HttpClient;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 核心模块统一导出
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
17
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
__exportStar(require("./http-client"), exports);
|
|
21
|
+
__exportStar(require("./environment"), exports);
|
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @ali/aiapp-ability
|
|
4
|
+
* AI应用能力包
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
18
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
// 导出类型
|
|
22
|
+
__exportStar(require("./types"), exports);
|
|
23
|
+
// 导出核心模块
|
|
24
|
+
__exportStar(require("./core"), exports);
|
|
25
|
+
// 导出能力模块
|
|
26
|
+
__exportStar(require("./abilities"), exports);
|
|
27
|
+
function main() {
|
|
28
|
+
return 'Write your own legend...';
|
|
29
|
+
}
|
|
30
|
+
exports.default = main;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 钉钉能力相关类型定义
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* 获取 AccessToken 请求参数
|
|
6
|
+
*/
|
|
7
|
+
export interface GetAccessTokenRequest {
|
|
8
|
+
/** 已创建的企业内部应用的 AppKey */
|
|
9
|
+
appKey: string;
|
|
10
|
+
/** 已创建的企业内部应用的 AppSecret */
|
|
11
|
+
appSecret: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 获取 AccessToken 响应
|
|
15
|
+
*/
|
|
16
|
+
export interface GetAccessTokenResponse {
|
|
17
|
+
/** 生成的 accessToken */
|
|
18
|
+
accessToken: string;
|
|
19
|
+
/** accessToken 的过期时间,单位秒 */
|
|
20
|
+
expireIn: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* 批量发送机器人消息的消息类型
|
|
24
|
+
*/
|
|
25
|
+
export declare type RobotMsgKey = 'sampleMarkdown';
|
|
26
|
+
/**
|
|
27
|
+
* 批量发送机器人消息请求参数
|
|
28
|
+
* @see POST /v1.0/robot/oToMessages/batchSend
|
|
29
|
+
*/
|
|
30
|
+
export interface BatchSendRobotMsgRequest<T extends RobotMsgKey = RobotMsgKey> {
|
|
31
|
+
/** 机器人的编码 */
|
|
32
|
+
robotCode: string;
|
|
33
|
+
/** 接收消息的用户 userId 列表,最多支持 20 人 */
|
|
34
|
+
userIds: string[];
|
|
35
|
+
/** 消息模板 key */
|
|
36
|
+
msgKey: T;
|
|
37
|
+
/** 消息模板动态参数(JSON 字符串) */
|
|
38
|
+
msgParam: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* 批量发送机器人消息响应
|
|
42
|
+
*/
|
|
43
|
+
export interface BatchSendRobotMsgResponse {
|
|
44
|
+
/** 处理结果列表 */
|
|
45
|
+
sendResults?: BatchSendResult[];
|
|
46
|
+
/** 流程 ID */
|
|
47
|
+
processQueryKey?: string;
|
|
48
|
+
/** 被限流的用户列表 */
|
|
49
|
+
flowControlledStaffIdList?: string[];
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* 批量发送结果
|
|
53
|
+
*/
|
|
54
|
+
export interface BatchSendResult {
|
|
55
|
+
/** 用户 ID */
|
|
56
|
+
staffId: string;
|
|
57
|
+
/** 是否成功 */
|
|
58
|
+
success: boolean;
|
|
59
|
+
/** 错误码 */
|
|
60
|
+
errorCode?: string;
|
|
61
|
+
/** 错误信息 */
|
|
62
|
+
errorMsg?: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 批量发送响应
|
|
66
|
+
*/
|
|
67
|
+
export interface BatchSendResponse {
|
|
68
|
+
/** 是否成功 */
|
|
69
|
+
success: boolean;
|
|
70
|
+
/** 消息 */
|
|
71
|
+
message?: string;
|
|
72
|
+
/** 发送结果详情 */
|
|
73
|
+
data?: BatchSendRobotMsgResponse;
|
|
74
|
+
/** 失败的用户列表 */
|
|
75
|
+
failedUserIds?: string[];
|
|
76
|
+
/** 发送成功的数量 */
|
|
77
|
+
successCount?: number;
|
|
78
|
+
/** 发送失败的数量 */
|
|
79
|
+
failCount?: number;
|
|
80
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 类型定义统一导出
|
|
3
|
+
*/
|
|
4
|
+
export * from './dingtalk';
|
|
5
|
+
/**
|
|
6
|
+
* 通用响应接口
|
|
7
|
+
*/
|
|
8
|
+
export interface BaseResponse<T = any> {
|
|
9
|
+
success: boolean;
|
|
10
|
+
message?: string;
|
|
11
|
+
data?: T;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 能力提供者基础接口
|
|
15
|
+
*/
|
|
16
|
+
export interface AbilityProvider {
|
|
17
|
+
name: string;
|
|
18
|
+
version: string;
|
|
19
|
+
initialize?(config?: any): Promise<void> | void;
|
|
20
|
+
destroy?(): Promise<void> | void;
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 类型定义统一导出
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
17
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
// 导出钉钉相关类型
|
|
21
|
+
__exportStar(require("./dingtalk"), exports);
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|