dingtalk-wiki 1.2.8 → 1.2.9

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.
Files changed (2) hide show
  1. package/index.js +68 -52
  2. 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
- const node = nodeRes.data;
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,81 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1421
1419
  });
1422
1420
  }
1423
1421
 
1424
- // Step 6: search docs API (requires workspaceId)
1425
- if (workspaceId) {
1422
+ // Step 6: search docs API (v1.0/doc/docs) — 需要 workspaceId
1423
+ if (effectiveWsId) {
1426
1424
  try {
1427
1425
  const searchRes = await axios({
1428
1426
  method: 'GET',
1429
1427
  url: `${DINGTALK_API_V2}/v1.0/doc/docs`,
1430
1428
  headers: { 'x-acs-dingtalk-access-token': token },
1431
- params: { operatorId: opId, workspaceId, maxResults: 10 }
1429
+ params: { operatorId: opId, workspaceId: effectiveWsId, maxResults: 50 }
1432
1430
  });
1433
1431
  const docs = searchRes.data?.docs || [];
1434
- const matched = docs.find(d => d.nodeBO?.nodeId === input || d.nodeBO?.dentryUuid === input || d.docKey === input);
1432
+ const matched = docs.find(d => d.nodeBO?.nodeId === input || d.nodeBO?.dentryUuid === input || d.docKey === input || d.nodeBO?.dentryId === input);
1435
1433
  steps.push({
1436
- step: 'doc search API (v1.0/doc/docs)',
1437
- result: `成功 (${docs.length} 篇文档)` + (matched ? ', 找到匹配' : ', 未找到匹配'),
1438
- raw: matched || `${docs.length} results, first doc docKey=${docs[0]?.docKey || '(none)'}`
1434
+ step: `doc search API (workspace=${effectiveWsId})`,
1435
+ result: `成功 (${docs.length} 篇文档)` + (matched ? ', 找到匹配!' : ', 未找到匹配'),
1436
+ raw: matched || `共 ${docs.length} 篇,第一篇 docKey=${docs[0]?.docKey || '()'}`
1439
1437
  });
1440
1438
  } catch (e) {
1441
1439
  steps.push({
1442
- step: 'doc search API (v1.0/doc/docs)',
1440
+ step: `doc search API (workspace=${effectiveWsId})`,
1443
1441
  result: '失败',
1444
1442
  raw: { message: e.response?.data?.message || e.message, code: e.response?.data?.code || '(无)', status: e.response?.status || '(无)' }
1445
1443
  });
1446
1444
  }
1447
1445
  } else {
1448
- steps.push({ step: 'doc search API (v1.0/doc/docs)', result: '跳过(需 workspace_id)' });
1446
+ steps.push({ step: 'doc search API', result: '跳过(无法获取 workspace_id)' });
1449
1447
  }
1450
1448
 
1451
- // Step 7: wiki workspaces + directories search (try all workspaces)
1452
- if (!workspaceId) {
1449
+ // Step 7: 在知识库目录中查找此节点 + 查看是否有 docKey 字段
1450
+ if (effectiveWsId) {
1453
1451
  try {
1454
- const wsRes = await axios({
1452
+ const dirRes = await axios({
1455
1453
  method: 'GET',
1456
- url: `${DINGTALK_API_V2}/v2.0/wiki/workspaces`,
1454
+ url: `${DINGTALK_API_V2}/v2.0/doc/spaces/${effectiveWsId}/directories`,
1457
1455
  headers: { 'x-acs-dingtalk-access-token': token },
1458
- params: { operatorId: opId }
1456
+ params: { operatorId: opId, maxResults: 500 }
1457
+ });
1458
+ const children = dirRes.data?.children || [];
1459
+ const match = children.find(c => c.dentryUuid === input || c.dentryId === input || c.id === input);
1460
+ // Show first few children's available fields so user can see what fields exist
1461
+ const sampleKeys = children.length > 0 ? Object.keys(children[0]) : [];
1462
+ steps.push({
1463
+ step: `知识库目录 (workspace=${effectiveWsId})`,
1464
+ result: `${children.length} 个子节点` + (match ? ', 找到匹配!' : ', 未找到匹配'),
1465
+ raw: match ? match : { sampleFields: sampleKeys, firstChildSample: children[0] || null }
1466
+ });
1467
+ } catch (e) {
1468
+ steps.push({
1469
+ step: `知识库目录 (workspace=${effectiveWsId})`,
1470
+ result: '失败',
1471
+ raw: { message: e.response?.data?.message || e.message, code: e.response?.data?.code || '(无)', status: e.response?.status || '(无)' }
1472
+ });
1473
+ }
1474
+ }
1475
+
1476
+ // Step 8: 用 workspaceId 再次尝试 overwriteContent(确认文档套件是否完全不可用)
1477
+ if (effectiveWsId) {
1478
+ try {
1479
+ const overwriteRes = await axios({
1480
+ method: 'POST',
1481
+ url: `${DINGTALK_API_V2}/v1.0/doc/suites/documents/${input}/overwriteContent`,
1482
+ headers: { 'x-acs-dingtalk-access-token': token, 'Content-Type': 'application/json' },
1483
+ params: { operatorId: opId },
1484
+ data: { content: 'test', contentType: 'markdown' }
1459
1485
  });
1460
- const workspaces = wsRes.data?.workspaces || [];
1461
- let found = null;
1462
- for (const ws of workspaces) {
1463
- if (found) break;
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
- }
1478
1486
  steps.push({
1479
- step: '遍历知识库目录匹配',
1480
- result: found ? `在知识库 ${found.workspaceName}(${found.workspaceId}) 中找到` : '在所有知识库中未找到匹配',
1481
- raw: found ? { workspaceId: found.workspaceId, name: found.node?.name, dentryUuid: found.node?.dentryUuid, dentryId: found.node?.dentryId, hasChildren: found.node?.hasChildren, contentType: found.node?.contentType, docKey: found.node?.docKey || '(无)' } : null
1487
+ step: 'overwriteContent(带 workspaceId)',
1488
+ result: '成功',
1489
+ raw: overwriteRes.data
1482
1490
  });
1483
1491
  } catch (e) {
1484
- steps.push({ step: '遍历知识库目录匹配', result: '失败', raw: e.message });
1492
+ steps.push({
1493
+ step: 'overwriteContent(带 workspaceId)',
1494
+ result: '失败',
1495
+ raw: { message: e.response?.data?.message || e.message, code: e.response?.data?.code || '(无)', status: e.response?.status || '(无)' }
1496
+ });
1485
1497
  }
1486
1498
  }
1487
1499
 
@@ -1494,12 +1506,16 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1494
1506
  }
1495
1507
  lines.push('');
1496
1508
  });
1497
- lines.push('💡 提示: 如果 wiki/nodes API 成功并返回了 docKey,请使用该 docKey 调用 get_wiki_doc_content');
1498
- lines.push(' 如果 doc metadata API 成功,说明该 docKey doc suite 中有效');
1499
- lines.push(' 如果 blocks API 失败但 overwriteContent 成功,问题在 blocks API 端');
1500
- lines.push(' 如果所有 API 都失败,说明该 docKey 在 doc suite 中不存在');
1501
- if (!workspaceId) {
1502
- lines.push(' 建议提供 workspace_id 参数以启用搜索回退路径');
1509
+ lines.push('💡 提示:');
1510
+ lines.push(' - wiki/nodes API 成功但无 docKey 此文档在 doc suite 中没有关联的 docKey');
1511
+ lines.push(' - docKey create_wiki_doc 返回的独立 ID,与 nodeId/dentryUuid 不同');
1512
+ lines.push(' - 对于已有文档(非新建),doc suite API 可能完全不支持');
1513
+ lines.push(' - overwriteContent 也失败 → 不是 blocks 特有的问题');
1514
+ if (effectiveWsId) {
1515
+ lines.push(` - 自动检测到 workspaceId: ${effectiveWsId}`);
1516
+ }
1517
+ if (workspaceId) {
1518
+ lines.push(' - 已提供 workspaceId: ' + workspaceId);
1503
1519
  }
1504
1520
 
1505
1521
  return { content: [{ type: 'text', text: lines.join('\n') }] };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dingtalk-wiki",
3
- "version": "1.2.8",
3
+ "version": "1.2.9",
4
4
  "description": "DingTalk Wiki / Docs read-write MCP server that fills the gap left by DingTalk official MCP.",
5
5
  "main": "index.js",
6
6
  "bin": {