dingtalk-mcp 1.0.11 → 1.0.13
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/README.md +36 -12
- package/dingtalk_appmanage_mcp_server.yaml +304 -0
- package/dingtalk_calendar_mcp_server.yaml +714 -0
- package/dingtalk_checkin_mcp_server.yaml +76 -0
- package/dingtalk_contacts_mcp_server.yaml +18 -1
- package/dingtalk_department_mcp_server.yaml +95 -0
- package/dingtalk_honor_mcp_server.yaml +174 -0
- package/dingtalk_notice_mcp_server.yaml +85 -0
- package/dingtalk_servicewindow_mcp_server.yaml +109 -0
- package/dist/DingTalkMCPServer.js +1 -2
- package/dist/cli.js +51 -5
- package/dist/utils/apiClient.d.ts +49 -0
- package/dist/utils/apiClient.d.ts.map +1 -0
- package/dist/utils/apiClient.js +85 -0
- package/dist/utils/apiClient.js.map +1 -0
- package/dist/utils/errorFormatter.d.ts +44 -0
- package/dist/utils/errorFormatter.d.ts.map +1 -0
- package/dist/utils/errorFormatter.js +164 -0
- package/dist/utils/errorFormatter.js.map +1 -0
- package/dist/utils/messageBuilder.d.ts +57 -0
- package/dist/utils/messageBuilder.d.ts.map +1 -0
- package/dist/utils/messageBuilder.js +200 -0
- package/dist/utils/messageBuilder.js.map +1 -0
- package/dist/utils/messageProcessor.d.ts +36 -0
- package/dist/utils/messageProcessor.d.ts.map +1 -0
- package/dist/utils/messageProcessor.js +145 -0
- package/dist/utils/messageProcessor.js.map +1 -0
- package/dist/utils/validator.d.ts +64 -0
- package/dist/utils/validator.d.ts.map +1 -0
- package/dist/utils/validator.js +181 -0
- package/dist/utils/validator.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API Client - 抽象DingTalk API调用
|
|
3
|
+
* 负责构建请求、发送API调用和处理响应
|
|
4
|
+
*/
|
|
5
|
+
import { type AxiosResponse } from 'axios';
|
|
6
|
+
import type { DingTalkApiResponse } from '../types.js';
|
|
7
|
+
import type { ProcessedMessage } from './messageProcessor.js';
|
|
8
|
+
export interface ApiClientOptions {
|
|
9
|
+
baseURL?: string;
|
|
10
|
+
timeout?: number;
|
|
11
|
+
retries?: number;
|
|
12
|
+
}
|
|
13
|
+
export declare class ApiClient {
|
|
14
|
+
private readonly baseURL;
|
|
15
|
+
private readonly timeout;
|
|
16
|
+
private readonly retries;
|
|
17
|
+
constructor(options?: ApiClientOptions);
|
|
18
|
+
/**
|
|
19
|
+
* 发送单人消息
|
|
20
|
+
*/
|
|
21
|
+
sendMessage(accessToken: string, message: ProcessedMessage, params: {
|
|
22
|
+
userId?: string;
|
|
23
|
+
unionId?: string;
|
|
24
|
+
bizId?: string;
|
|
25
|
+
accountId?: string;
|
|
26
|
+
}): Promise<AxiosResponse<DingTalkApiResponse>>;
|
|
27
|
+
/**
|
|
28
|
+
* 批量发送消息
|
|
29
|
+
*/
|
|
30
|
+
batchSendMessage(accessToken: string, message: ProcessedMessage, params: {
|
|
31
|
+
userIdList?: string[];
|
|
32
|
+
sendToAll?: boolean;
|
|
33
|
+
bizRequestId?: string;
|
|
34
|
+
bizId?: string;
|
|
35
|
+
accountId?: string;
|
|
36
|
+
}): Promise<AxiosResponse<DingTalkApiResponse>>;
|
|
37
|
+
/**
|
|
38
|
+
* 通用请求方法
|
|
39
|
+
*/
|
|
40
|
+
private makeRequest;
|
|
41
|
+
/**
|
|
42
|
+
* 获取access_token
|
|
43
|
+
*/
|
|
44
|
+
getAccessToken(appId: string, appSecret: string): Promise<{
|
|
45
|
+
access_token: string;
|
|
46
|
+
expires_in: number;
|
|
47
|
+
}>;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=apiClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiClient.d.ts","sourceRoot":"","sources":["../../src/utils/apiClient.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAc,EAAE,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAClD,OAAO,KAAK,EAA+C,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACpG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,OAAO,GAAE,gBAAqB;IAM1C;;OAEG;IACU,WAAW,CACtB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE;QACN,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GACA,OAAO,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAqB9C;;OAEG;IACU,gBAAgB,CAC3B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE;QACN,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;QACtB,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GACA,OAAO,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAsB9C;;OAEG;YACW,WAAW;IAmBzB;;OAEG;IACU,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QACrE,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CAkBH"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API Client - 抽象DingTalk API调用
|
|
3
|
+
* 负责构建请求、发送API调用和处理响应
|
|
4
|
+
*/
|
|
5
|
+
import axios from 'axios';
|
|
6
|
+
export class ApiClient {
|
|
7
|
+
constructor(options = {}) {
|
|
8
|
+
this.baseURL = options.baseURL || 'https://api.dingtalk.com/v1.0';
|
|
9
|
+
this.timeout = options.timeout || 30000;
|
|
10
|
+
this.retries = options.retries || 1;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 发送单人消息
|
|
14
|
+
*/
|
|
15
|
+
async sendMessage(accessToken, message, params) {
|
|
16
|
+
const request = {
|
|
17
|
+
detail: {
|
|
18
|
+
msgType: message.msgType,
|
|
19
|
+
uuid: message.uuid,
|
|
20
|
+
userId: params.userId,
|
|
21
|
+
unionId: params.unionId,
|
|
22
|
+
messageBody: message.messageBody
|
|
23
|
+
},
|
|
24
|
+
bizId: params.bizId,
|
|
25
|
+
accountId: params.accountId
|
|
26
|
+
};
|
|
27
|
+
return this.makeRequest('POST', '/crm/officialAccounts/oToMessages/send', request, accessToken);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 批量发送消息
|
|
31
|
+
*/
|
|
32
|
+
async batchSendMessage(accessToken, message, params) {
|
|
33
|
+
const request = {
|
|
34
|
+
detail: {
|
|
35
|
+
msgType: message.msgType,
|
|
36
|
+
uuid: message.uuid,
|
|
37
|
+
bizRequestId: params.bizRequestId,
|
|
38
|
+
userIdList: params.userIdList,
|
|
39
|
+
messageBody: message.messageBody,
|
|
40
|
+
sendToAll: params.sendToAll
|
|
41
|
+
},
|
|
42
|
+
bizId: params.bizId,
|
|
43
|
+
accountId: params.accountId
|
|
44
|
+
};
|
|
45
|
+
return this.makeRequest('POST', '/crm/officialAccounts/oToMessages/batchSend', request, accessToken);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 通用请求方法
|
|
49
|
+
*/
|
|
50
|
+
async makeRequest(method, endpoint, data, accessToken) {
|
|
51
|
+
const url = `${this.baseURL}${endpoint}`;
|
|
52
|
+
const headers = {
|
|
53
|
+
'Content-Type': 'application/json',
|
|
54
|
+
'x-acs-dingtalk-access-token': accessToken
|
|
55
|
+
};
|
|
56
|
+
if (method === 'GET') {
|
|
57
|
+
return await axios.get(url, { headers, timeout: this.timeout });
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
return await axios.post(url, data, { headers, timeout: this.timeout });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 获取access_token
|
|
65
|
+
*/
|
|
66
|
+
async getAccessToken(appId, appSecret) {
|
|
67
|
+
const response = await axios.get('https://oapi.dingtalk.com/gettoken', {
|
|
68
|
+
params: {
|
|
69
|
+
appkey: appId,
|
|
70
|
+
appsecret: appSecret
|
|
71
|
+
},
|
|
72
|
+
timeout: this.timeout
|
|
73
|
+
});
|
|
74
|
+
if (response.data.errcode === 0) {
|
|
75
|
+
return {
|
|
76
|
+
access_token: response.data.access_token,
|
|
77
|
+
expires_in: response.data.expires_in || 7200
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
throw new Error(`Token refresh failed: ${response.data.errmsg} (errcode: ${response.data.errcode})`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=apiClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiClient.js","sourceRoot":"","sources":["../../src/utils/apiClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Formatter - 统一错误格式化
|
|
3
|
+
* 负责将各种错误格式化为用户友好的消息
|
|
4
|
+
*/
|
|
5
|
+
import type { MCPToolResponse } from '../types.js';
|
|
6
|
+
export interface ErrorContext {
|
|
7
|
+
toolName?: string;
|
|
8
|
+
operation?: string;
|
|
9
|
+
userId?: string;
|
|
10
|
+
messageType?: string;
|
|
11
|
+
originalMessageBody?: any;
|
|
12
|
+
processedMessageBody?: any;
|
|
13
|
+
}
|
|
14
|
+
export declare class ErrorFormatter {
|
|
15
|
+
/**
|
|
16
|
+
* 格式化DingTalk API错误
|
|
17
|
+
*/
|
|
18
|
+
static formatDingTalkApiError(error: any, context?: ErrorContext): MCPToolResponse;
|
|
19
|
+
/**
|
|
20
|
+
* 格式化消息接收人错误
|
|
21
|
+
*/
|
|
22
|
+
private static formatMessageReceiverError;
|
|
23
|
+
/**
|
|
24
|
+
* 格式化消息体缺失错误
|
|
25
|
+
*/
|
|
26
|
+
private static formatMissingMessageBodyError;
|
|
27
|
+
/**
|
|
28
|
+
* 格式化Token错误
|
|
29
|
+
*/
|
|
30
|
+
private static formatTokenError;
|
|
31
|
+
/**
|
|
32
|
+
* 格式化通用API错误
|
|
33
|
+
*/
|
|
34
|
+
private static formatGenericApiError;
|
|
35
|
+
/**
|
|
36
|
+
* 格式化通用错误
|
|
37
|
+
*/
|
|
38
|
+
private static formatGenericError;
|
|
39
|
+
/**
|
|
40
|
+
* 格式化成功响应
|
|
41
|
+
*/
|
|
42
|
+
static formatSuccessResponse(data: any, context?: ErrorContext): MCPToolResponse;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=errorFormatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errorFormatter.d.ts","sourceRoot":"","sources":["../../src/utils/errorFormatter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,CAAC,EAAE,GAAG,CAAC;IAC1B,oBAAoB,CAAC,EAAE,GAAG,CAAC;CAC5B;AAED,qBAAa,cAAc;IACzB;;OAEG;WACW,sBAAsB,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,GAAE,YAAiB,GAAG,eAAe;IA0B7F;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,0BAA0B;IAuBzC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,6BAA6B;IA+B5C;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAmB/B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,qBAAqB;IA0BpC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAkBjC;;OAEG;WACW,qBAAqB,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,GAAE,YAAiB,GAAG,eAAe;CAW5F"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Formatter - 统一错误格式化
|
|
3
|
+
* 负责将各种错误格式化为用户友好的消息
|
|
4
|
+
*/
|
|
5
|
+
import axios from 'axios';
|
|
6
|
+
export class ErrorFormatter {
|
|
7
|
+
/**
|
|
8
|
+
* 格式化DingTalk API错误
|
|
9
|
+
*/
|
|
10
|
+
static formatDingTalkApiError(error, context = {}) {
|
|
11
|
+
if (axios.isAxiosError(error)) {
|
|
12
|
+
const errorData = error.response?.data;
|
|
13
|
+
// 特殊错误处理
|
|
14
|
+
if (errorData?.code === 'illegalParameter.messageReceiver') {
|
|
15
|
+
return this.formatMessageReceiverError(context);
|
|
16
|
+
}
|
|
17
|
+
if (errorData?.code === 'MissingmessageBody') {
|
|
18
|
+
return this.formatMissingMessageBodyError(context);
|
|
19
|
+
}
|
|
20
|
+
// 401 或 token 错误
|
|
21
|
+
if (error.response?.status === 401 || errorData?.errcode === 40014) {
|
|
22
|
+
return this.formatTokenError();
|
|
23
|
+
}
|
|
24
|
+
// 通用API错误
|
|
25
|
+
return this.formatGenericApiError(error, context);
|
|
26
|
+
}
|
|
27
|
+
// 非axios错误
|
|
28
|
+
return this.formatGenericError(error, context);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 格式化消息接收人错误
|
|
32
|
+
*/
|
|
33
|
+
static formatMessageReceiverError(context) {
|
|
34
|
+
const isMultipleUsers = Array.isArray(context.userId);
|
|
35
|
+
return {
|
|
36
|
+
content: [{
|
|
37
|
+
type: 'text',
|
|
38
|
+
text: `❌ 接收人参数错误\n\n` +
|
|
39
|
+
`🔍 可能的原因:\n` +
|
|
40
|
+
`• ${isMultipleUsers ? 'userIdList中包含未关注服务窗的用户' : '用户未关注该服务窗'}\n` +
|
|
41
|
+
`• 用户ID格式错误(企业用户ID ≠ 服务窗用户ID)\n` +
|
|
42
|
+
`• accountId参数错误或缺失\n\n` +
|
|
43
|
+
`🛠️ 解决方案:\n` +
|
|
44
|
+
`1. 使用 listServiceWindowFollowers 查询服务窗粉丝列表\n` +
|
|
45
|
+
`2. 确认${isMultipleUsers ? 'userIdList中的用户都已' : '用户已'}关注服务窗\n` +
|
|
46
|
+
`3. 使用正确的服务窗用户ID(不是企业内部用户ID)\n` +
|
|
47
|
+
`4. 检查accountId是否正确\n\n` +
|
|
48
|
+
`💡 服务窗用户ID格式示例: 4lhwybf3j37lyb6thdfnmtam7m\n` +
|
|
49
|
+
`💡 企业用户ID格式示例: 0420131813787933`
|
|
50
|
+
}],
|
|
51
|
+
isError: true
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 格式化消息体缺失错误
|
|
56
|
+
*/
|
|
57
|
+
static formatMissingMessageBodyError(context) {
|
|
58
|
+
let debugInfo = '';
|
|
59
|
+
if (context.originalMessageBody && context.processedMessageBody) {
|
|
60
|
+
const isNested = context.originalMessageBody.messageBody &&
|
|
61
|
+
typeof context.originalMessageBody.messageBody === 'object';
|
|
62
|
+
debugInfo = `🔍 调试信息:\n` +
|
|
63
|
+
`• 嵌套格式检测: ${isNested ? '✅ 检测到嵌套格式' : '❌ 未检测到嵌套格式'}\n` +
|
|
64
|
+
`• 原始messageBody: ${JSON.stringify(context.originalMessageBody, null, 2)}\n` +
|
|
65
|
+
`• 处理后messageBody: ${JSON.stringify(context.processedMessageBody, null, 2)}\n\n`;
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
content: [{
|
|
69
|
+
type: 'text',
|
|
70
|
+
text: `❌ 消息体参数错误 - MissingmessageBody\n\n` +
|
|
71
|
+
debugInfo +
|
|
72
|
+
`�� 可能的解决方案:\n` +
|
|
73
|
+
`1. 检查消息体格式是否正确\n` +
|
|
74
|
+
`2. 确保使用 buildServiceWindowMessage 构建消息\n` +
|
|
75
|
+
`3. 验证必填字段是否完整\n\n` +
|
|
76
|
+
`✅ 正确的消息体格式:\n` +
|
|
77
|
+
`• text: { "text": { "content": "内容" } }\n` +
|
|
78
|
+
`• link: { "link": { "title": "标题", "text": "描述", "messageUrl": "链接", "picUrl": "图片" } }\n` +
|
|
79
|
+
`• markdown: { "markdown": { "title": "标题", "text": "markdown内容" } }`
|
|
80
|
+
}],
|
|
81
|
+
isError: true
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* 格式化Token错误
|
|
86
|
+
*/
|
|
87
|
+
static formatTokenError() {
|
|
88
|
+
return {
|
|
89
|
+
content: [{
|
|
90
|
+
type: 'text',
|
|
91
|
+
text: `❌ 访问令牌错误\n\n` +
|
|
92
|
+
`🔍 可能的原因:\n` +
|
|
93
|
+
`• access_token 已过期\n` +
|
|
94
|
+
`• DINGTALK_Client_ID 或 DINGTALK_Client_Secret 配置错误\n` +
|
|
95
|
+
`• 应用权限不足\n\n` +
|
|
96
|
+
`🛠️ 解决方案:\n` +
|
|
97
|
+
`1. 检查环境变量配置\n` +
|
|
98
|
+
`2. 验证应用密钥是否正确\n` +
|
|
99
|
+
`3. 确认应用已获得服务窗相关权限\n` +
|
|
100
|
+
`4. Token缓存已清理,将在下次请求时自动刷新`
|
|
101
|
+
}],
|
|
102
|
+
isError: true
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* 格式化通用API错误
|
|
107
|
+
*/
|
|
108
|
+
static formatGenericApiError(error, context) {
|
|
109
|
+
const response = error.response;
|
|
110
|
+
const errorData = response?.data;
|
|
111
|
+
let errorDetails = '';
|
|
112
|
+
if (errorData) {
|
|
113
|
+
errorDetails = `📋 API响应详情:\n${JSON.stringify(errorData, null, 2)}\n\n`;
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
content: [{
|
|
117
|
+
type: 'text',
|
|
118
|
+
text: `❌ ${context.operation || '操作'}失败\n\n` +
|
|
119
|
+
`🌐 HTTP状态码: ${response?.status || 'Unknown'}\n` +
|
|
120
|
+
`🔍 错误代码: ${errorData?.code || errorData?.errcode || 'Unknown'}\n` +
|
|
121
|
+
`📝 错误信息: ${errorData?.message || errorData?.errmsg || error.message}\n\n` +
|
|
122
|
+
errorDetails +
|
|
123
|
+
`💡 建议检查:\n` +
|
|
124
|
+
`• 网络连接是否正常\n` +
|
|
125
|
+
`• API参数是否正确\n` +
|
|
126
|
+
`• 应用权限是否充足`
|
|
127
|
+
}],
|
|
128
|
+
isError: true
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* 格式化通用错误
|
|
133
|
+
*/
|
|
134
|
+
static formatGenericError(error, context) {
|
|
135
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
136
|
+
return {
|
|
137
|
+
content: [{
|
|
138
|
+
type: 'text',
|
|
139
|
+
text: `❌ ${context.operation || '操作'}失败: ${errorMessage}\n\n` +
|
|
140
|
+
`🔍 工具: ${context.toolName || 'Unknown'}\n` +
|
|
141
|
+
`�� 错误详情: ${errorMessage}\n\n` +
|
|
142
|
+
`💡 建议:\n` +
|
|
143
|
+
`• 检查参数格式是否正确\n` +
|
|
144
|
+
`• 确认必填参数已提供\n` +
|
|
145
|
+
`• 查看错误信息获取更多详情`
|
|
146
|
+
}],
|
|
147
|
+
isError: true
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* 格式化成功响应
|
|
152
|
+
*/
|
|
153
|
+
static formatSuccessResponse(data, context = {}) {
|
|
154
|
+
const operation = context.operation || '操作';
|
|
155
|
+
const details = typeof data === 'object' ? JSON.stringify(data, null, 2) : String(data);
|
|
156
|
+
return {
|
|
157
|
+
content: [{
|
|
158
|
+
type: 'text',
|
|
159
|
+
text: `✅ ${operation}成功!\n\n📊 响应结果:\n${details}`
|
|
160
|
+
}]
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=errorFormatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errorFormatter.js","sourceRoot":"","sources":["../../src/utils/errorFormatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ServiceWindow Message Builder - 核心特色功能
|
|
3
|
+
* 简化复杂的服务窗消息格式构建
|
|
4
|
+
*/
|
|
5
|
+
import type { ServiceWindowMessage, DingTalkMessageBody } from '../types.js';
|
|
6
|
+
export declare class ServiceWindowMessageBuilder {
|
|
7
|
+
private static readonly VALIDATION_RULES;
|
|
8
|
+
/**
|
|
9
|
+
* 构建服务窗消息体
|
|
10
|
+
* @param message 用户友好的消息参数
|
|
11
|
+
* @returns 钉钉API标准格式的消息体
|
|
12
|
+
*/
|
|
13
|
+
static buildMessage(message: ServiceWindowMessage): {
|
|
14
|
+
msgType: string;
|
|
15
|
+
messageBody: DingTalkMessageBody;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* 构建文本消息
|
|
19
|
+
*/
|
|
20
|
+
private static buildTextMessage;
|
|
21
|
+
/**
|
|
22
|
+
* 构建链接消息
|
|
23
|
+
*/
|
|
24
|
+
private static buildLinkMessage;
|
|
25
|
+
/**
|
|
26
|
+
* 构建Markdown消息
|
|
27
|
+
*/
|
|
28
|
+
private static buildMarkdownMessage;
|
|
29
|
+
/**
|
|
30
|
+
* 验证字段值
|
|
31
|
+
*/
|
|
32
|
+
private static validateField;
|
|
33
|
+
/**
|
|
34
|
+
* 验证字符串长度
|
|
35
|
+
*/
|
|
36
|
+
private static validateStringLength;
|
|
37
|
+
/**
|
|
38
|
+
* 验证URL格式
|
|
39
|
+
*/
|
|
40
|
+
private static validateUrl;
|
|
41
|
+
/**
|
|
42
|
+
* 生成唯一的消息ID
|
|
43
|
+
*/
|
|
44
|
+
static generateMessageUuid(): string;
|
|
45
|
+
/**
|
|
46
|
+
* 验证消息参数完整性
|
|
47
|
+
*/
|
|
48
|
+
static validateMessage(message: ServiceWindowMessage): {
|
|
49
|
+
valid: boolean;
|
|
50
|
+
errors: string[];
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* 获取消息类型的帮助信息
|
|
54
|
+
*/
|
|
55
|
+
static getMessageTypeHelp(messageType: string): string;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=messageBuilder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messageBuilder.d.ts","sourceRoot":"","sources":["../../src/utils/messageBuilder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,oBAAoB,EACpB,mBAAmB,EAMpB,MAAM,aAAa,CAAC;AAErB,qBAAa,2BAA2B;IACtC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAqBtC;IAEF;;;;OAIG;WACW,YAAY,CAAC,OAAO,EAAE,oBAAoB,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,mBAAmB,CAAA;KAAE;IAuBhH;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAW/B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAmB/B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAYnC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IA0B5B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAkBnC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IAgB1B;;OAEG;WACW,mBAAmB,IAAI,MAAM;IAI3C;;OAEG;WACW,eAAe,CAAC,OAAO,EAAE,oBAAoB,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE;IAYlG;;OAEG;WACW,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;CA2B9D"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ServiceWindow Message Builder - 核心特色功能
|
|
3
|
+
* 简化复杂的服务窗消息格式构建
|
|
4
|
+
*/
|
|
5
|
+
export class ServiceWindowMessageBuilder {
|
|
6
|
+
/**
|
|
7
|
+
* 构建服务窗消息体
|
|
8
|
+
* @param message 用户友好的消息参数
|
|
9
|
+
* @returns 钉钉API标准格式的消息体
|
|
10
|
+
*/
|
|
11
|
+
static buildMessage(message) {
|
|
12
|
+
switch (message.messageType) {
|
|
13
|
+
case 'text':
|
|
14
|
+
return {
|
|
15
|
+
msgType: 'text',
|
|
16
|
+
messageBody: this.buildTextMessage(message)
|
|
17
|
+
};
|
|
18
|
+
case 'link':
|
|
19
|
+
return {
|
|
20
|
+
msgType: 'link',
|
|
21
|
+
messageBody: this.buildLinkMessage(message)
|
|
22
|
+
};
|
|
23
|
+
case 'markdown':
|
|
24
|
+
return {
|
|
25
|
+
msgType: 'markdown',
|
|
26
|
+
messageBody: this.buildMarkdownMessage(message)
|
|
27
|
+
};
|
|
28
|
+
// actionCard 已不支持,在类型检查阶段就会被拦截
|
|
29
|
+
default:
|
|
30
|
+
throw new Error(`不支持的消息类型: ${message.messageType}。服务窗支持的类型: text, link, markdown`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 构建文本消息
|
|
35
|
+
*/
|
|
36
|
+
static buildTextMessage(message) {
|
|
37
|
+
this.validateField('textContent', message.content);
|
|
38
|
+
this.validateStringLength(message.content, 'content', { min: 1, max: 500 });
|
|
39
|
+
return {
|
|
40
|
+
text: {
|
|
41
|
+
content: message.content
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* 构建链接消息
|
|
47
|
+
*/
|
|
48
|
+
static buildLinkMessage(message) {
|
|
49
|
+
this.validateField('linkTitle', message.title);
|
|
50
|
+
this.validateField('linkText', message.text);
|
|
51
|
+
this.validateField('linkUrl', message.messageUrl);
|
|
52
|
+
this.validateField('linkPicUrl', message.picUrl);
|
|
53
|
+
this.validateUrl(message.messageUrl, 'messageUrl');
|
|
54
|
+
this.validateUrl(message.picUrl, 'picUrl');
|
|
55
|
+
return {
|
|
56
|
+
link: {
|
|
57
|
+
title: message.title,
|
|
58
|
+
text: message.text,
|
|
59
|
+
messageUrl: message.messageUrl,
|
|
60
|
+
picUrl: message.picUrl
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 构建Markdown消息
|
|
66
|
+
*/
|
|
67
|
+
static buildMarkdownMessage(message) {
|
|
68
|
+
this.validateField('markdownTitle', message.title);
|
|
69
|
+
this.validateField('markdownText', message.text);
|
|
70
|
+
return {
|
|
71
|
+
markdown: {
|
|
72
|
+
title: message.title,
|
|
73
|
+
text: message.text
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* 验证字段值
|
|
79
|
+
*/
|
|
80
|
+
static validateField(fieldName, value) {
|
|
81
|
+
const rule = this.VALIDATION_RULES[fieldName];
|
|
82
|
+
if (!rule)
|
|
83
|
+
return;
|
|
84
|
+
// 必填检查
|
|
85
|
+
if (rule.required && (!value || value.trim() === '')) {
|
|
86
|
+
throw new Error(`${fieldName} 为必填字段`);
|
|
87
|
+
}
|
|
88
|
+
if (!value)
|
|
89
|
+
return;
|
|
90
|
+
// 长度检查
|
|
91
|
+
if (rule.minLength !== undefined && value.length < rule.minLength) {
|
|
92
|
+
throw new Error(`${fieldName} 长度不能少于 ${rule.minLength} 个字符`);
|
|
93
|
+
}
|
|
94
|
+
if (rule.maxLength !== undefined && value.length > rule.maxLength) {
|
|
95
|
+
throw new Error(`${fieldName} 长度不能超过 ${rule.maxLength} 个字符`);
|
|
96
|
+
}
|
|
97
|
+
// 正则模式检查
|
|
98
|
+
if (rule.pattern && !rule.pattern.test(value)) {
|
|
99
|
+
throw new Error(`${fieldName} 格式不正确`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* 验证字符串长度
|
|
104
|
+
*/
|
|
105
|
+
static validateStringLength(value, fieldName, options) {
|
|
106
|
+
if (typeof value !== 'string') {
|
|
107
|
+
throw new Error(`${fieldName} 必须是字符串`);
|
|
108
|
+
}
|
|
109
|
+
if (options.min !== undefined && value.length < options.min) {
|
|
110
|
+
throw new Error(`${fieldName} 长度不能少于 ${options.min} 个字符`);
|
|
111
|
+
}
|
|
112
|
+
if (options.max !== undefined && value.length > options.max) {
|
|
113
|
+
throw new Error(`${fieldName} 长度不能超过 ${options.max} 个字符`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* 验证URL格式
|
|
118
|
+
*/
|
|
119
|
+
static validateUrl(url, fieldName) {
|
|
120
|
+
if (!url || typeof url !== 'string') {
|
|
121
|
+
throw new Error(`${fieldName} 必须是有效的URL字符串`);
|
|
122
|
+
}
|
|
123
|
+
try {
|
|
124
|
+
new URL(url);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
throw new Error(`${fieldName} 不是有效的URL格式`);
|
|
128
|
+
}
|
|
129
|
+
if (!url.startsWith('http://') && !url.startsWith('https://')) {
|
|
130
|
+
throw new Error(`${fieldName} 必须以 http:// 或 https:// 开头`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* 生成唯一的消息ID
|
|
135
|
+
*/
|
|
136
|
+
static generateMessageUuid() {
|
|
137
|
+
return `msg-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* 验证消息参数完整性
|
|
141
|
+
*/
|
|
142
|
+
static validateMessage(message) {
|
|
143
|
+
const errors = [];
|
|
144
|
+
try {
|
|
145
|
+
this.buildMessage(message);
|
|
146
|
+
return { valid: true, errors: [] };
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
errors.push(error.message);
|
|
150
|
+
return { valid: false, errors };
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* 获取消息类型的帮助信息
|
|
155
|
+
*/
|
|
156
|
+
static getMessageTypeHelp(messageType) {
|
|
157
|
+
const helpInfo = {
|
|
158
|
+
text: `文本消息格式:
|
|
159
|
+
{
|
|
160
|
+
"messageType": "text",
|
|
161
|
+
"content": "消息内容 (1-500字符)"
|
|
162
|
+
}`,
|
|
163
|
+
link: `链接消息格式:
|
|
164
|
+
{
|
|
165
|
+
"messageType": "link",
|
|
166
|
+
"title": "消息标题 (1-128字符)",
|
|
167
|
+
"text": "消息描述 (1-500字符)",
|
|
168
|
+
"messageUrl": "跳转链接 (https://...)",
|
|
169
|
+
"picUrl": "图片地址"
|
|
170
|
+
}`,
|
|
171
|
+
markdown: `Markdown消息格式:
|
|
172
|
+
{
|
|
173
|
+
"messageType": "markdown",
|
|
174
|
+
"title": "消息标题 (1-30字符)",
|
|
175
|
+
"text": "Markdown内容 (1-500字符)"
|
|
176
|
+
}`
|
|
177
|
+
};
|
|
178
|
+
return helpInfo[messageType] || '未知的消息类型';
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
ServiceWindowMessageBuilder.VALIDATION_RULES = {
|
|
182
|
+
// 文本消息验证规则
|
|
183
|
+
textContent: { required: true, minLength: 1, maxLength: 500 },
|
|
184
|
+
// 链接消息验证规则
|
|
185
|
+
linkTitle: { required: true, minLength: 1, maxLength: 128 },
|
|
186
|
+
linkText: { required: true, minLength: 1, maxLength: 500 },
|
|
187
|
+
linkUrl: { required: true, minLength: 1, maxLength: 500, pattern: /^https?:\/\/.+/ },
|
|
188
|
+
linkPicUrl: { required: true, minLength: 1, maxLength: 500 },
|
|
189
|
+
// Markdown消息验证规则
|
|
190
|
+
markdownTitle: { required: true, minLength: 1, maxLength: 30 },
|
|
191
|
+
markdownText: { required: true, minLength: 1, maxLength: 500 },
|
|
192
|
+
// 卡片消息验证规则
|
|
193
|
+
cardTitle: { required: true, minLength: 1, maxLength: 30 },
|
|
194
|
+
cardMarkdown: { required: true, minLength: 1, maxLength: 1000 },
|
|
195
|
+
cardSingleTitle: { required: false, minLength: 1, maxLength: 20 },
|
|
196
|
+
cardSingleUrl: { required: false, minLength: 1, maxLength: 500, pattern: /^https?:\/\/.+/ },
|
|
197
|
+
buttonTitle: { required: true, minLength: 1, maxLength: 20 },
|
|
198
|
+
buttonUrl: { required: true, minLength: 1, maxLength: 500, pattern: /^https?:\/\/.+/ }
|
|
199
|
+
};
|
|
200
|
+
//# sourceMappingURL=messageBuilder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messageBuilder.js","sourceRoot":"","sources":["../../src/utils/messageBuilder.ts"],"names":[],"mappings":"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"}
|