OpenClaw 微信文件投递踩坑:iLinkai API 大小写陷阱
#OpenClaw #微信 #调试踩坑
记录一次通过微信发送文件附件(xlsx)时遭遇的连环报错,以及最终定位到 iLinkai API 大小写敏感问题的全过程。
本系列:部署实录 · 配置续集 · 公网访问 · Headroom 接入 · 后续规划
背景
用 OpenClaw Agent 生成了一份评分标准表格(.xlsx),希望通过微信渠道直接投递给对话方,无需额外步骤。整个流程应该是:
-
Agent 调用
message工具,指定media参数(文件路径) -
openclaw-weixin插件将文件上传到 iLinkai CDN -
CDN 地址写入微信文件消息,发送给对方
听起来很顺,实际踩了好几个坑。
一、连环报错
报错 1:sendMessage ret=-3 errmsg=invalid arguments
1 | [tools] message failed: sendMessage ret=-3 errmsg=invalid arguments |
原因:指定了错误的 accountId——两个机器人账号中,目标用户只与其中一个有聊天记录,用了另一个账号发送自然被拒。
报错 2:weixin not configured
1 | [tools] message failed: weixin not configured: please run `openclaw channels login --channel openclaw-weixin` |
原因:accountId 填写了 "default" 这个逻辑名称,插件实际使用运行时账号 ID,无法识别字符串 "default"。
报错 3:cannot determine which account to use
1 | weixin: cannot determine which account to use for to=<OPENID> |
原因:两个机器人账号都没有与该用户的活跃 session,插件无法自动判断用哪个账号发送。解决方法是让用户先从微信发一条消息过来,触发 session 建立。
报错 4:getUploadUrl returned no upload URL(持续失败)
1 | [tools] message failed: uploadFileAttachmentToWeixin: getUploadUrl returned no upload URL |
文字消息已经可以正常发出,但文件发送始终在这一步失败。看起来是接口问题——但为什么同样的配置文字能过、文件不行?
二、从日志中发现成功案例
翻 Docker 日志时,发现同一天早些时候有一次成功记录:
1 | [weixin] sendWeixinMediaFile: file upload done filekey=<KEY> size=8208 |
成功发送的是另一个版本的同类文件。对比成功和失败时的请求参数,发现了关键差异:
| 场景 | target 参数 |
|---|---|
| ✅ 成功(13:13) | <OPENID_原始混合大小写> |
| ❌ 失败(15:xx) | <openid_全小写> |
三、根本原因:getuploadurl API 大小写敏感
深入分析插件代码(@tencent-weixin/openclaw-weixin v2.4.6):
1 | getUploadUrl → ilink/bot/getuploadurl |
当 to_user_id 使用全小写 openid 时,API 返回 {"ret":-1},没有错误说明,只有一个 -1。
当 to_user_id 使用原始混合大小写 openid(即 getupdates API 返回的原始格式)时,正常返回 upload_param,上传成功。
而文字消息的 sendmessage 接口对大小写相对宽松,全小写也能发出去。所以才出现了「文字消息能发、文件发不了」的奇怪现象。
结论:ilink/bot/getuploadurl 的 to_user_id 参数严格区分大小写。
四、修复方法
用正确大小写的 openid 重试,约 6 秒内上传完成,消息发送成功。
实际操作建议:
-
不要手动拼写 openid——从 incoming 消息上下文中取原始值,保持格式不变
-
不要指定
accountId——让插件通过 context-token 自动解析(resolveOutboundAccountId),它会匹配有活跃 session 的账号 -
文字消息对大小写宽松,文件上传严格,两者要区别对待
五、附:插件文件上传流程
openclaw-weixin 发文件的完整链路如下:
-
读取文件,计算 MD5 和 AES-128-ECB 加密后的大小
-
调用
ilink/bot/getuploadurl获取 CDN 预签名参数 -
将文件内容加密后 PUT 到 CDN
-
调用
ilink/bot/sendmessage,附上 CDN 引用,发出文件消息
第 2 步是这次问题的发生点。对于图片类型(IMAGE)和普通文件(FILE)都走同一流程,都受大小写限制影响。
六、调试技巧
插件有独立日志文件,路径通常在 /tmp/openclaw/openclaw-<date>.log(容器重启后丢失)。日志为 JSON 格式,包含完整的 resp= 字段,能看到 API 原始返回,比 Docker 日志详细得多:
1 | "uploadFileAttachmentToWeixin: getUploadUrl returned no upload URL |
遇到文件投递问题,优先查这个日志。
