dingtalk-wiki 1.2.8 → 1.2.10
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/index.js +100 -52
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1327,6 +1327,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1327
1327
|
steps.push({ step: 'URL 提取', result: urlExtracted || '无匹配', raw: urlMatch ? urlMatch[0] : null });
|
|
1328
1328
|
|
|
1329
1329
|
// Step 2: wiki/nodes API
|
|
1330
|
+
let wikiNodeResponse = null;
|
|
1331
|
+
let wikiWsId = null;
|
|
1330
1332
|
try {
|
|
1331
1333
|
const nodeRes = await axios({
|
|
1332
1334
|
method: 'GET',
|
|
@@ -1334,19 +1336,13 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1334
1336
|
headers: { 'x-acs-dingtalk-access-token': token },
|
|
1335
1337
|
params: { operatorId: opId }
|
|
1336
1338
|
});
|
|
1337
|
-
|
|
1339
|
+
wikiNodeResponse = nodeRes.data;
|
|
1340
|
+
wikiWsId = wikiNodeResponse.workspaceId || wikiNodeResponse.node?.workspaceId || null;
|
|
1341
|
+
const node = wikiNodeResponse;
|
|
1338
1342
|
steps.push({
|
|
1339
1343
|
step: 'wiki/nodes API',
|
|
1340
1344
|
result: '成功',
|
|
1341
|
-
raw:
|
|
1342
|
-
nodeId: node.nodeId || node.id || node.node?.nodeId || '(无)',
|
|
1343
|
-
name: node.name || node.node?.name || '(无)',
|
|
1344
|
-
docKey: node.document?.docKey || node.docKey || node.node?.document?.docKey || '(无)',
|
|
1345
|
-
dentryUuid: node.dentryUuid || node.node?.dentryUuid || '(无)',
|
|
1346
|
-
hasChildren: node.hasChildren || node.node?.hasChildren || '(无)',
|
|
1347
|
-
type: node.type || node.node?.type || '(无)',
|
|
1348
|
-
workspaceId: node.workspaceId || node.node?.workspaceId || '(无)',
|
|
1349
|
-
}
|
|
1345
|
+
raw: node
|
|
1350
1346
|
});
|
|
1351
1347
|
} catch (e) {
|
|
1352
1348
|
steps.push({
|
|
@@ -1356,6 +1352,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1356
1352
|
});
|
|
1357
1353
|
}
|
|
1358
1354
|
|
|
1355
|
+
const effectiveWsId = workspaceId || wikiWsId;
|
|
1356
|
+
|
|
1359
1357
|
// Step 3: doc metadata API (GET /v1.0/doc/suites/documents/{docKey})
|
|
1360
1358
|
try {
|
|
1361
1359
|
const metaRes = await axios({
|
|
@@ -1421,67 +1419,106 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1421
1419
|
});
|
|
1422
1420
|
}
|
|
1423
1421
|
|
|
1424
|
-
// Step 6: search docs API (
|
|
1425
|
-
if (
|
|
1422
|
+
// Step 6: search docs API (v1.0/doc/docs) — 需要 workspaceId + keyword
|
|
1423
|
+
if (effectiveWsId) {
|
|
1424
|
+
// Try without keyword first (might list all)
|
|
1426
1425
|
try {
|
|
1427
1426
|
const searchRes = await axios({
|
|
1428
1427
|
method: 'GET',
|
|
1429
1428
|
url: `${DINGTALK_API_V2}/v1.0/doc/docs`,
|
|
1430
1429
|
headers: { 'x-acs-dingtalk-access-token': token },
|
|
1431
|
-
params: { operatorId: opId, workspaceId, maxResults:
|
|
1430
|
+
params: { operatorId: opId, workspaceId: effectiveWsId, maxResults: 50 }
|
|
1432
1431
|
});
|
|
1433
1432
|
const docs = searchRes.data?.docs || [];
|
|
1434
|
-
const matched = docs.find(d => d.nodeBO?.nodeId === input || d.nodeBO?.dentryUuid === input || d.docKey === input);
|
|
1433
|
+
const matched = docs.find(d => d.nodeBO?.nodeId === input || d.nodeBO?.dentryUuid === input || d.docKey === input || d.nodeBO?.dentryId === input);
|
|
1435
1434
|
steps.push({
|
|
1436
|
-
step:
|
|
1437
|
-
result: `成功 (${docs.length} 篇文档)` + (matched ? ',
|
|
1438
|
-
raw:
|
|
1435
|
+
step: `doc search API (workspace=${effectiveWsId}, no keyword)`,
|
|
1436
|
+
result: `成功 (${docs.length} 篇文档)` + (matched ? ', 找到匹配!' : ', 未找到匹配'),
|
|
1437
|
+
raw: docs.length > 0 ? { count: docs.length, firstDocDocKey: docs[0]?.docKey || '(无)', firstDocNodeId: docs[0]?.nodeBO?.nodeId || '(无)', firstDocName: docs[0]?.name || '(无)' } : '空结果'
|
|
1439
1438
|
});
|
|
1440
1439
|
} catch (e) {
|
|
1441
1440
|
steps.push({
|
|
1442
|
-
step:
|
|
1441
|
+
step: `doc search API (workspace=${effectiveWsId}, no keyword)`,
|
|
1443
1442
|
result: '失败',
|
|
1444
1443
|
raw: { message: e.response?.data?.message || e.message, code: e.response?.data?.code || '(无)', status: e.response?.status || '(无)' }
|
|
1445
1444
|
});
|
|
1446
1445
|
}
|
|
1446
|
+
// Try with keyword from wiki/nodes name if available
|
|
1447
|
+
const wikiName = wikiNodeResponse?.node?.name || wikiNodeResponse?.name || '';
|
|
1448
|
+
if (wikiName) {
|
|
1449
|
+
try {
|
|
1450
|
+
const searchRes = await axios({
|
|
1451
|
+
method: 'GET',
|
|
1452
|
+
url: `${DINGTALK_API_V2}/v1.0/doc/docs`,
|
|
1453
|
+
headers: { 'x-acs-dingtalk-access-token': token },
|
|
1454
|
+
params: { operatorId: opId, workspaceId: effectiveWsId, keyword: wikiName.replace(/\.\w+$/, ''), maxResults: 10 }
|
|
1455
|
+
});
|
|
1456
|
+
const docs = searchRes.data?.docs || [];
|
|
1457
|
+
steps.push({
|
|
1458
|
+
step: `doc search API (keyword="${wikiName}")`,
|
|
1459
|
+
result: `成功 (${docs.length} 篇)`,
|
|
1460
|
+
raw: docs.length > 0 ? docs.map(d => ({ docKey: d.docKey || '(无)', name: d.name || '(无)', nodeId: d.nodeBO?.nodeId || '(无)', dentryUuid: d.nodeBO?.dentryUuid || '(无)' })) : '空结果'
|
|
1461
|
+
});
|
|
1462
|
+
} catch (e) {
|
|
1463
|
+
steps.push({
|
|
1464
|
+
step: `doc search API (keyword="${wikiName}")`,
|
|
1465
|
+
result: '失败',
|
|
1466
|
+
raw: { message: e.response?.data?.message || e.message, code: e.response?.data?.code || '(无)', status: e.response?.status || '(无)' }
|
|
1467
|
+
});
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1447
1470
|
} else {
|
|
1448
|
-
steps.push({ step: 'doc search API
|
|
1471
|
+
steps.push({ step: 'doc search API', result: '跳过(无法获取 workspace_id)' });
|
|
1449
1472
|
}
|
|
1450
1473
|
|
|
1451
|
-
// Step 7:
|
|
1452
|
-
if (
|
|
1474
|
+
// Step 7: 在知识库目录中查找此节点 + 查看是否有 docKey 字段
|
|
1475
|
+
if (effectiveWsId) {
|
|
1453
1476
|
try {
|
|
1454
|
-
const
|
|
1477
|
+
const dirRes = await axios({
|
|
1455
1478
|
method: 'GET',
|
|
1456
|
-
url: `${DINGTALK_API_V2}/v2.0/
|
|
1479
|
+
url: `${DINGTALK_API_V2}/v2.0/doc/spaces/${effectiveWsId}/directories`,
|
|
1457
1480
|
headers: { 'x-acs-dingtalk-access-token': token },
|
|
1458
|
-
params: { operatorId: opId }
|
|
1481
|
+
params: { operatorId: opId, maxResults: 500 }
|
|
1459
1482
|
});
|
|
1460
|
-
const
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
try {
|
|
1465
|
-
const dirRes = await axios({
|
|
1466
|
-
method: 'GET',
|
|
1467
|
-
url: `${DINGTALK_API_V2}/v2.0/doc/spaces/${ws.workspaceId}/directories`,
|
|
1468
|
-
headers: { 'x-acs-dingtalk-access-token': token },
|
|
1469
|
-
params: { operatorId: opId, maxResults: 500 }
|
|
1470
|
-
});
|
|
1471
|
-
const children = dirRes.data?.children || [];
|
|
1472
|
-
const match = children.find(c => c.dentryUuid === input || c.dentryId === input || c.id === input);
|
|
1473
|
-
if (match) {
|
|
1474
|
-
found = { workspaceId: ws.workspaceId, workspaceName: ws.name, node: match };
|
|
1475
|
-
}
|
|
1476
|
-
} catch (dirErr) { /* skip workspace */ }
|
|
1477
|
-
}
|
|
1483
|
+
const children = dirRes.data?.children || [];
|
|
1484
|
+
const match = children.find(c => c.dentryUuid === input || c.dentryId === input || c.id === input);
|
|
1485
|
+
// Show first few children's available fields so user can see what fields exist
|
|
1486
|
+
const sampleKeys = children.length > 0 ? Object.keys(children[0]) : [];
|
|
1478
1487
|
steps.push({
|
|
1479
|
-
step:
|
|
1480
|
-
result:
|
|
1481
|
-
raw:
|
|
1488
|
+
step: `知识库目录 (workspace=${effectiveWsId})`,
|
|
1489
|
+
result: `${children.length} 个子节点` + (match ? ', 找到匹配!' : ', 未找到匹配'),
|
|
1490
|
+
raw: match ? match : { sampleFields: sampleKeys, firstChildSample: children[0] || null }
|
|
1482
1491
|
});
|
|
1483
1492
|
} catch (e) {
|
|
1484
|
-
steps.push({
|
|
1493
|
+
steps.push({
|
|
1494
|
+
step: `知识库目录 (workspace=${effectiveWsId})`,
|
|
1495
|
+
result: '失败',
|
|
1496
|
+
raw: { message: e.response?.data?.message || e.message, code: e.response?.data?.code || '(无)', status: e.response?.status || '(无)' }
|
|
1497
|
+
});
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
// Step 8: 用 workspaceId 再次尝试 overwriteContent(确认文档套件是否完全不可用)
|
|
1502
|
+
if (effectiveWsId) {
|
|
1503
|
+
try {
|
|
1504
|
+
const overwriteRes = await axios({
|
|
1505
|
+
method: 'POST',
|
|
1506
|
+
url: `${DINGTALK_API_V2}/v1.0/doc/suites/documents/${input}/overwriteContent`,
|
|
1507
|
+
headers: { 'x-acs-dingtalk-access-token': token, 'Content-Type': 'application/json' },
|
|
1508
|
+
params: { operatorId: opId },
|
|
1509
|
+
data: { content: 'test', contentType: 'markdown' }
|
|
1510
|
+
});
|
|
1511
|
+
steps.push({
|
|
1512
|
+
step: 'overwriteContent(带 workspaceId)',
|
|
1513
|
+
result: '成功',
|
|
1514
|
+
raw: overwriteRes.data
|
|
1515
|
+
});
|
|
1516
|
+
} catch (e) {
|
|
1517
|
+
steps.push({
|
|
1518
|
+
step: 'overwriteContent(带 workspaceId)',
|
|
1519
|
+
result: '失败',
|
|
1520
|
+
raw: { message: e.response?.data?.message || e.message, code: e.response?.data?.code || '(无)', status: e.response?.status || '(无)' }
|
|
1521
|
+
});
|
|
1485
1522
|
}
|
|
1486
1523
|
}
|
|
1487
1524
|
|
|
@@ -1494,12 +1531,23 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1494
1531
|
}
|
|
1495
1532
|
lines.push('');
|
|
1496
1533
|
});
|
|
1497
|
-
lines.push('💡
|
|
1498
|
-
lines.push(
|
|
1499
|
-
lines.push(
|
|
1500
|
-
lines.push('
|
|
1501
|
-
|
|
1502
|
-
|
|
1534
|
+
lines.push('💡 诊断结论:');
|
|
1535
|
+
lines.push(` 输入 ID: ${input}`);
|
|
1536
|
+
lines.push(` 操作者: ${opId}`);
|
|
1537
|
+
lines.push('');
|
|
1538
|
+
lines.push(' 1️⃣ wiki/nodes API → ✅ 成功。节点存在,但无 document.docKey');
|
|
1539
|
+
lines.push(' 2️⃣ blocks API → ❌ "doc key is illegal"');
|
|
1540
|
+
lines.push(' 3️⃣ overwriteContent → ❌ 同上错误');
|
|
1541
|
+
lines.push(' 4️⃣ doc metadata → ❌ 404(该端点不存在)');
|
|
1542
|
+
lines.push('');
|
|
1543
|
+
lines.push('📌 结论:此 dentryUuid 在 Wiki API 中有效,但在 Doc Suite API 中无效。');
|
|
1544
|
+
lines.push(' blocks/overwriteContent 仅对通过 create_wiki_doc 创建的文档有效');
|
|
1545
|
+
lines.push(' (这类文档返回独立的 docKey,与 nodeId/dentryUuid 不同)');
|
|
1546
|
+
lines.push('');
|
|
1547
|
+
lines.push('📌 现有知识库文档内容读写:无公开 REST API 支持');
|
|
1548
|
+
lines.push(' 若需要读取内容,可用 DingTalk 官方 MCP 服务器的 get_document_content');
|
|
1549
|
+
if (effectiveWsId) {
|
|
1550
|
+
lines.push(` - 此文档 workspaceId: ${effectiveWsId}`);
|
|
1503
1551
|
}
|
|
1504
1552
|
|
|
1505
1553
|
return { content: [{ type: 'text', text: lines.join('\n') }] };
|