返回顶部
w

weixin-send-media微信发媒体

微信发图片/文件技能 - 解决 contextToken 持久化问题

作者: admin | 来源: ClawHub
源自
ClawHub
版本
V 1.1.0
安全检测
已通过
123
下载量
免费
免费
0
收藏
概述
安装方式
版本历史

weixin-send-media

微信发媒体技能

本技能解决了微信渠道发送媒体消息的核心问题:contextToken 持久化。

⚠️ 前提条件:微信渠道必须已登录并处于活动状态。


🔒 安全说明(重要)

为什么需要修改核心文件?

本技能需要修改 ~/.openclaw/extensions/openclaw-weixin/src/messaging/inbound.ts,这是因为:

  1. 1. contextToken 的生成和存储逻辑在核心扩展中
- setContextToken() 和 getContextToken() 是内部函数 - 没有公开 API 可以外部调用
  1. 2. 这是唯一可行的方案
- 微信 API 要求发送消息时必须提供 contextToken - Token 只在收到用户消息时生成 - 原始设计只缓存在内存,重启即丢失
  1. 3. 修改是安全可控的
- 只添加了文件读写逻辑,不改变原有功能 - 所有数据存储在用户本地 ~/.openclaw/openclaw-weixin/context-tokens/ - 不会外传任何敏感信息

安全最佳实践

bash

1. 限制 token 文件权限


chmod 600 ~/.openclaw/openclaw-weixin/context-tokens/*.json

2. 定期清理过期 token

find ~/.openclaw/openclaw-weixin/context-tokens/ -mtime +30 -delete

3. 检查 token 文件

cat ~/.openclaw/openclaw-weixin/context-tokens/*.json

ClawHub 安全警告说明

ClawHub 可能显示 Security: SUSPICIOUS,这是因为:

  • - 技能修改了 OpenClaw 核心扩展文件
  • 使用了补丁(patch)方式注入

这是误报,本技能:

  • - ✅ 不窃取任何数据
  • ✅ 不连接外部服务器
  • ✅ 所有操作在本地完成
  • ✅ 代码完全开源可审计



背景问题

微信渠道的 contextToken(会话上下文令牌)原本只缓存在 gateway 进程内存中,导致:

  • - ❌ CLI 命令无法发送媒体消息
  • ❌ 自动化脚本无法调用
  • ❌ 重启 gateway 后 token 丢失

本技能通过持久化 contextToken 到磁盘文件,解决了这个问题。



使用方式

方法 1:CLI 发送图片

bash
openclaw message send \
--channel openclaw-weixin \
--account d72d5b576646-im-bot \
--target o9cq802hhREiOXPlXq_Tgb0MjPTo@im.wechat \
--media /path/to/image.png \
--message 图片说明

方法 2:CLI 发送文件

bash
openclaw message send \
--channel openclaw-weixin \
--account d72d5b576646-im-bot \
--target o9cq802hhREiOXPlXq_Tgb0MjPTo@im.wechat \
--media /path/to/document.pdf \
--message 文件说明

方法 3:CLI 发送网络图片

bash
openclaw message send \
--channel openclaw-weixin \
--account d72d5b576646-im-bot \
--target o9cq802hhREiOXPlXq_Tgb0MjPTo@im.wechat \
--media https://example.com/image.jpg \
--message 网络图片

方法 4:Node.js 脚本调用

javascript
const { execSync } = require(child_process);

function sendWeixinMedia(userId, mediaPath, caption = ) {
const cmd = openclaw message send \\
--channel openclaw-weixin \\
--account \\
--target ${userId} \\
--media ${mediaPath} \\
--message ${caption};

return execSync(cmd, { encoding: utf8 });
}

// 使用示例
sendWeixinMedia(
o9cq802hhREiOXPlXq_Tgb0MjPTo@im.wechat,
/path/to/qr.png,
这是二维码
);

方法 5:使用封装脚本

bash

发送图片


./scripts/send-image.js [caption]

示例

./scripts/send-image.js o9cq802hhREiOXPlXq_Tgb0MjPTo@im.wechat ./qr.png 扫码绑定

核心修改

修改文件

~/.openclaw/extensions/openclaw-weixin/src/messaging/inbound.ts

修改内容

在文件开头添加:
typescript
import fs from node:fs;
import path from node:path;

添加持久化目录和文件路径函数:
typescript
// Persist context tokens to disk for CLI access
const CONTEXTTOKENDIR = path.join(process.env.HOME!, .openclaw/openclaw-weixin/context-tokens);
try { fs.mkdirSync(CONTEXTTOKENDIR, { recursive: true }); } catch {}

function contextTokenFile(accountId: string, userId: string): string {
const safeId = accountId.replace(/[@:]/g, _);
const safeUser = userId.replace(/[@:]/g, _);
return path.join(CONTEXTTOKENDIR, ${safeId}${safeUser}.json);
}

修改 setContextToken 函数(添加磁盘持久化):
typescript
export function setContextToken(accountId: string, userId: string, token: string): void {
const k = contextTokenKey(accountId, userId);
logger.debug(setContextToken: key=${k});
contextTokenStore.set(k, token);

// Persist to disk
const file = contextTokenFile(accountId, userId);
try {
fs.writeFileSync(file, JSON.stringify({
accountId,
userId,
token,
savedAt: new Date().toISOString()
}, null, 2));
logger.debug(setContextToken: persisted to ${file});
} catch (e) {
logger.warn(setContextToken: failed to persist to disk: ${e});
}
}

修改 getContextToken 函数(添加磁盘回退):
typescript
export function getContextToken(accountId: string, userId: string): string | undefined {
const k = contextTokenKey(accountId, userId);
const val = contextTokenStore.get(k);
logger.debug(
getContextToken: key=${k} found=${val !== undefined} storeSize=${contextTokenStore.size},
);
if (val) return val;

// Fallback to disk
const file = contextTokenFile(accountId, userId);
try {
if (fs.existsSync(file)) {
const data = JSON.parse(fs.readFileSync(file, utf8));
logger.debug(getContextToken: loaded from disk ${file});
return data.token;
}
} catch (e) {
logger.warn(getContextToken: failed to load from disk: ${e});
}
return undefined;
}



文件结构

weixin-send-media/
├── SKILL.md # 本文件 - 完整文档
├── README.md # 快速入门
├── CHANGELOG.md # 更新日志
├── scripts/
│ ├── send-image.js # 发图片脚本
│ ├── send-file.js # 发文件脚本
│ └── export-context-token.js # 导出 token 工具
├── patches/
│ └── inbound.ts.patch # 补丁文件
├── references/
│ └── api-docs.md # API 文档
└── tests/
└── test-token-persistence.sh # 测试脚本



安装步骤

自动安装(推荐)

bash
npx clawhub@latest install weixin-send-media

手动安装

  1. 1. 应用补丁
bash cd ~/.openclaw/workspace/skills/weixin-send-media ./install.sh
  1. 2. 重启 gateway
bash openclaw gateway restart
  1. 3. 发送一条消息触发 token 保存
(任意微信消息即可)
  1. 4. 验证 token 文件
bash cat ~/.openclaw/openclaw-weixin/context-tokens/*.json

典型工作流

发送二维码给家人

用户 query 示例

  • - 把绑定二维码发给我老婆
  • 发一下配对码

执行流程

  1. 1. 生成二维码图片(openclaw qr)
  2. 保存二维码到文件
  3. 调用 openclaw message send --media 发送
  4. 家人

标签

skill ai

通过对话安装

该技能支持在以下平台通过对话安装:

OpenClaw WorkBuddy QClaw Kimi Claude

方式一:安装 SkillHub 和技能

帮我安装 SkillHub 和 weixin-send-media-1776078249 技能

方式二:设置 SkillHub 为优先技能安装源

设置 SkillHub 为我的优先技能安装源,然后帮我安装 weixin-send-media-1776078249 技能

通过命令行安装

skillhub install weixin-send-media-1776078249

下载

⬇ 下载 weixin-send-media v1.1.0(免费)

文件大小: 19.8 KB | 发布时间: 2026-4-14 13:48

v1.1.0 最新 2026-4-14 13:48
**Version 1.1.0 – 安全增强与脚本支持**

- 新增 CHANGELOG.md、脚本(send-image.js, send-file.js, export-context-token.js)、API 参考文档和测试用例
- 完善安全说明,新增专节说明补丁方式和本地 token 文件保护建议
- 新增封装脚本,支持一行命令发送图片或文件
- README/文档全面完善,补充故障排查、FAQ、可用命令及典型用例
- 安装流程支持 install.sh 自动化;不再包含原 ClawHub 发布相关文件
- 强化 contextToken 持久化设计说明,强调本地安全和误报风险

Archiver·手机版·闲社网·闲社论坛·羊毛社区· 多链控股集团有限公司 · 苏ICP备2025199260号-1

Powered by Discuz! X5.0   © 2024-2025 闲社网·线报更新论坛·羊毛分享社区·http://xianshe.com

p2p_official_large
返回顶部