Files
workspace/MEMORY.md

169 lines
4.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# MEMORY.md - 长期记忆
这个文件用于记录重要的长期知识和经验教训。
---
## DingTalk媒体发送成功经验
**日期**: 2026-03-05
**重要性**: ⭐⭐⭐⭐⭐
### 问题背景
尝试通过DingTalk发送文件时遇到多次失败反复尝试了多种方法
- 使用message工具 - 失败("Failed to upload media"
- 直接调用robot/send API - 失败("token is not exist" / "缺少参数 access_token"
- 尝试不同的API端点和消息格式 - 大部分失败
### 解决方案(成功方式)
#### Token获取
```javascript
// 关键使用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中直接拼接参数
#### 文件上传
```javascript
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;
```
#### 消息发送(关键成功点)
```javascript
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. 标注日期和重要性