Files
workspace/MEMORY.md

4.5 KiB
Raw Permalink Blame History

MEMORY.md - 长期记忆

这个文件用于记录重要的长期知识和经验教训。


DingTalk媒体发送成功经验

日期: 2026-03-05
重要性:

问题背景

尝试通过DingTalk发送文件时遇到多次失败反复尝试了多种方法

  • 使用message工具 - 失败("Failed to upload media"
  • 直接调用robot/send API - 失败("token is not exist" / "缺少参数 access_token"
  • 尝试不同的API端点和消息格式 - 大部分失败

解决方案(成功方式)

Token获取

// 关键使用GET + URL参数非params
const tokenUrl = `https://oapi.dingtalk.com/gettoken?appkey=${APP_KEY}&appsecret=${APP_SECRET}`;
const response = await axios.get(tokenUrl);
const accessToken = response.data.access_token;

重要:不要使用axios.get(url, {params: {...}})必须在URL中直接拼接参数

文件上传

const uploadUrl = `https://oapi.dingtalk.com/media/upload?access_token=${accessToken}`;
const form = new FormData();
form.append('media', fs.createReadStream(filePath));
form.append('type', 'file');
const upload = await axios.post(uploadUrl, form, {headers: form.getHeaders()});
const media_id = upload.data.media_id;

消息发送(关键成功点)

const url = "https://api.dingtalk.com/v1.0/robot/groupMessages/send";

const headers = {
  "x-acs-dingtalk-access-token": accessToken,  // ← 关键在Header中
  "Content-Type": "application/json"
};

const body = {
  robotCode: ROBOT_CODE,
  openConversationId: OPEN_CONVERSATION_ID,
  msgKey: "sampleFile",  // ← 文件用sampleFile图片用sampleMarkdown
  msgParam: JSON.stringify({  // ← 关键:必须是字符串!
    mediaId: media_id,
    fileName: fileName
  })
};

const result = await axios.post(url, body, { headers });

关键msgKey对应关系

媒体类型 msgKey 测试状态
文件 sampleFile 验证成功
图片 sampleMarkdown 验证成功
视频 sampleVideo 待测试

失败原因总结

  1. 使用旧的robot/send API

    • 返回 "token is not exist"
    • 使用v1.0 API后解决
  2. msgParam使用对象而非字符串

    • 返回 "MissingmsgParam"
    • 必须使用JSON.stringify()
  3. access_token放在错误位置

    • 在URL中会失败
    • 必须在Header中x-acs-dingtalk-access-token

验证的端点差异

API端点 状态 说明
https://oapi.dingtalk.com/gettoken 可用 必须用URL参数
https://oapi.dingtalk.com/media/upload 可用 支持文件上传
https://api.dingtalk.com/v1.0/robot/groupMessages/send 可用 成功发送消息
https://oapi.dingtalk.com/robot/send 失败 返回token错误

配置信息

AppKey: ding4ursdp0l2giat4bj
AppSecret: J0gBicjKiIHoKla7WfKKhRs1Tv8L6Xd5UhW3EVQByF16G7Vn7UUcRhP6u-PBCQNo
RobotCode: ding4ursdp0l2giat4bj
OpenConversationId: cidcjYshXVtKck5LfOO9AqOJg==

成功案例

2026-03-05 18:44

  • 项目database_analysis_summary.txt
  • 文件大小3,155 bytes
  • media_id: @lAjPM2GaR32g2U3OC2pNq84Clg_0
  • msgKey: sampleFile
  • API: /v1.0/robot/groupMessages/send
  • ProcessQueryKey: lXs/uLRd0YxJVk1x0VyTLfSdY2YKCE1yrGn2vGlQ+GM=
  • 状态:成功发送到钉钉群聊

经验教训

  1. 不要在OpenClaw环境中直接调用原始钉钉API

    • OpenClaw插件会拦截请求
    • 认证可能不匹配
  2. msgKey是关键

    • 文件 → sampleFile
    • 图片 → sampleMarkdown
    • 视频 → sampleVideo
  3. msgParam必须是JSON字符串

    • 这是容易出错的地方
    • 必须用JSON.stringify()包裹
  4. 使用正确的API版本

    • v1.0 API是正确选择
    • 旧版API不再有效

Python环境问题

日期: 2026-03-05
重要性:

问题: PowerShell直接调用Python时遇到路径和编码问题

解决方案:

  1. 设置PATH: $env:PATH = "F:\pyenv\pyenv-win\pyenv-win\pyenv-win\versions\3.14.2;$env:PATH"
  2. 使用UTF-8编码: sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

Git配置

日期: 2026-03-05
重要性:

Git服务器: git.alicorns.co.jp (Gitea)
用户: aitest
密码: Aiitest123456

主要仓库:

  • aitest/office-file-handler.git
  • aitest/dingtalk-media-sender.git
  • aitest/workspace.git

记录准则

  1. 只记录重要且会重复用到的信息
  2. 包括成功和失败的经验
  3. 提供可执行的代码示例
  4. 标注日期和重要性