dingtalk-wiki 1.2.5 → 1.2.7

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 +42 -19
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -510,7 +510,7 @@ class DingTalkClient {
510
510
  const url = `${DINGTALK_API_V2}${pathName}`;
511
511
 
512
512
  try {
513
- const response = await axios({
513
+ const requestConfig = {
514
514
  method,
515
515
  url,
516
516
  headers: {
@@ -522,10 +522,16 @@ class DingTalkClient {
522
522
  ...extraParams
523
523
  },
524
524
  data
525
- });
525
+ };
526
+ if (pathName.includes('blocks')) {
527
+ console.error(`[DEBUG] docRequest: ${method} ${url} operatorId=${resolvedOperatorId} extraParams=${JSON.stringify(extraParams)}`);
528
+ }
529
+ const response = await axios(requestConfig);
526
530
  return response.data;
527
531
  } catch (error) {
528
532
  if (error.response) {
533
+ const fullErr = JSON.stringify(error.response.data);
534
+ console.error(`[DEBUG] docRequest error (${pathName}): status=${error.response.status} data=${fullErr}`);
529
535
  throw new Error(`${error.response.data?.message || error.message} (code: ${error.response.data?.code})`);
530
536
  }
531
537
  throw error;
@@ -1158,22 +1164,27 @@ async function resolveDocKey(docKey, operatorId, dingtalkInstance) {
1158
1164
  // 从 URL 中提取 ID
1159
1165
  const urlMatch = String(docKey).match(/\/i\/nodes\/([^\/\?#]+)/);
1160
1166
  docKey = urlMatch ? urlMatch[1] : docKey;
1167
+ console.error(`[DEBUG] resolveDocKey: rawInput=${rawInput}, extracted=${docKey}`);
1161
1168
 
1162
1169
  try {
1163
1170
  const nodeInfo = await dingtalkInstance.docRequest('GET', `/v2.0/wiki/nodes/${docKey}`, { operatorId });
1164
1171
  const node = nodeInfo.node || nodeInfo;
1172
+ console.error(`[DEBUG] resolveDocKey: wiki/nodes response keys=${Object.keys(node).join(',')}`);
1165
1173
 
1166
1174
  // wiki/nodes 的 nodeId = dentryUuid,直接可用
1167
1175
  // 但 node.document.docKey 可能是不同的值,优先使用
1168
1176
  if (node.document?.docKey) {
1177
+ console.error(`[DEBUG] resolveDocKey: found document.docKey=${node.document.docKey}`);
1169
1178
  return node.document.docKey;
1170
1179
  }
1171
1180
  // 部分响应直接把 docKey 放在顶层
1172
1181
  if (node.docKey) {
1182
+ console.error(`[DEBUG] resolveDocKey: found top-level docKey=${node.docKey}`);
1173
1183
  return node.docKey;
1174
1184
  }
1185
+ console.error(`[DEBUG] resolveDocKey: no docKey in response, returning raw docKey=${docKey}`);
1175
1186
  } catch (e) {
1176
- // 传入 create nodeId 时 wiki/nodes 会拒绝,静默 fallback
1187
+ console.error(`[DEBUG] resolveDocKey: wiki/nodes failed: ${e.message}`);
1177
1188
  }
1178
1189
 
1179
1190
  return docKey;
@@ -1603,6 +1614,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1603
1614
  }
1604
1615
 
1605
1616
  let realDocKey = await resolveDocKey(docKey, operator_id || null, dingtalk);
1617
+ console.error(`[DEBUG] get_wiki_doc_content: input=${docKey}, resolved=${realDocKey}`);
1606
1618
 
1607
1619
  // 如果 resolve 后值没变(可能是 create 返回的 nodeId),尝试搜索 API 查找
1608
1620
  if (realDocKey === docKey && workspaceId) {
@@ -1615,26 +1627,37 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1615
1627
  const matched = docs.find(d => d.nodeBO?.nodeId === docKey || d.nodeBO?.nodeId === realDocKey) || docs[0];
1616
1628
  if (matched?.nodeBO?.nodeId) {
1617
1629
  realDocKey = matched.nodeBO.nodeId;
1630
+ console.error(`[DEBUG] get_wiki_doc_content: search fallback resolved to ${realDocKey}`);
1618
1631
  }
1619
- } catch (e) { /* ignore */ }
1632
+ } catch (e) { console.error(`[DEBUG] get_wiki_doc_content: search fallback failed: ${e.message}`); }
1620
1633
  }
1621
1634
 
1622
- const result = await dingtalk.docRequest('GET', `/v1.0/doc/suites/documents/${realDocKey}/blocks`, { operatorId: operator_id || null });
1623
- const blocks = result.result?.data || [];
1624
- let output = '';
1625
- blocks.forEach((block) => {
1626
- const text = extractBlockText(block);
1627
- output += text + '\n\n';
1628
- });
1629
- if (!blocks.length) {
1630
- output = '(文档为空或无可读内容)';
1635
+ try {
1636
+ const result = await dingtalk.docRequest('GET', `/v1.0/doc/suites/documents/${realDocKey}/blocks`, { operatorId: operator_id || null });
1637
+ const blocks = result.result?.data || [];
1638
+ let output = '';
1639
+ blocks.forEach((block) => {
1640
+ const text = extractBlockText(block);
1641
+ output += text + '\n\n';
1642
+ });
1643
+ if (!blocks.length) {
1644
+ output = '(文档为空或无可读内容)';
1645
+ }
1646
+ return {
1647
+ content: [{
1648
+ type: 'text',
1649
+ text: output.trim()
1650
+ }]
1651
+ };
1652
+ } catch (blocksErr) {
1653
+ return {
1654
+ content: [{
1655
+ type: 'text',
1656
+ text: `❌ blocks API 调用失败\n错误: ${blocksErr.message}\n\n调试信息:\n- 输入 doc_key: ${docKey}\n- 解析后 realDocKey: ${realDocKey}\n- workspaceId: ${workspaceId || '未提供'}\n- operator_id: ${operator_id || '未提供(将自动解析)'}`
1657
+ }],
1658
+ isError: true
1659
+ };
1631
1660
  }
1632
- return {
1633
- content: [{
1634
- type: 'text',
1635
- text: output.trim()
1636
- }]
1637
- };
1638
1661
  }
1639
1662
 
1640
1663
  case 'update_wiki_doc_content': {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dingtalk-wiki",
3
- "version": "1.2.5",
3
+ "version": "1.2.7",
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": {