openclaw-qqbot-send-skill
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseOpenClaw QQBot Send Skill
OpenClaw QQBot Send Skill
Skill by ara.so — Hermes Skills collection.
An OpenClaw skill for safely sending local files, images, audio, video, and other media through QQBot. This skill stages local files into the QQBot media relay directory, sends them with tags, and cleans up only the temporary staged copy after sending.
<qqmedia>...</qqmedia>由ara.so开发的Skill — 属于Hermes Skills集合。
这是一款OpenClaw Skill,用于通过QQBot安全发送本地文件、图片、音频、视频等媒体内容。该Skill会将本地文件暂存到QQBot媒体中转目录,使用标签发送,并在发送完成后仅清理暂存的临时副本。
<qqmedia>...</qqmedia>What It Does
功能介绍
- Stages local files into with unique filenames
~/.openclaw/media/qqbot/ - Sends media through QQBot using XML tags
<qqmedia>...</qqmedia> - Cleans up safely by removing only the staged temporary copy, never the original
- Enforces 10 MB limit for file size safety
- Supports HTTP(S) URLs directly without staging or cleanup
- Normalizes extensions to lowercase for consistency
- 暂存本地文件:将文件以唯一文件名保存到目录
~/.openclaw/media/qqbot/ - 发送媒体内容:通过QQBot使用XML标签发送媒体
<qqmedia>...</qqmedia> - 安全清理:仅删除暂存的临时副本,绝不触碰原始文件
- 文件大小限制:为保障安全,强制限制文件大小为10 MB
- 支持HTTP(S) URL:可直接发送链接,无需暂存或清理
- 统一扩展名:将文件扩展名统一转换为小写,保持一致性
Installation
安装步骤
Clone the repository:
bash
git clone https://github.com/ZJunCher/openclaw-qqbot-send-skill.git
cd openclaw-qqbot-send-skillThe skill uses Python's standard library only (no external dependencies required).
克隆仓库:
bash
git clone https://github.com/ZJunCher/openclaw-qqbot-send-skill.git
cd openclaw-qqbot-send-skill该Skill仅使用Python标准库(无需额外依赖)。
Key Components
核心组件
scripts/stage_media.py
scripts/stage_media.pyscripts/stage_media.py
scripts/stage_media.pyThe core staging and cleanup script with two operations:
- Stage: Copy a local file to with a unique name
~/.openclaw/media/qqbot/ - Cleanup: Delete the staged temporary copy after sending
核心暂存与清理脚本,包含两种操作:
- 暂存:将本地文件复制到并生成唯一文件名
~/.openclaw/media/qqbot/ - 清理:发送完成后删除暂存的临时副本
SKILL.md
SKILL.mdSKILL.md
SKILL.mdOpenClaw skill definition that tells the AI agent when and how to stage, send, and clean up media files.
OpenClaw Skill定义文件,用于告知AI Agent何时以及如何暂存、发送和清理媒体文件。
Usage Patterns
使用模式
Pattern 1: Send a Local File
模式1:发送本地文件
python
import subprocess
import ospython
import subprocess
import osStep 1: Stage the local file
步骤1:暂存本地文件
source_file = "/home/user/Pictures/photo.jpg"
result = subprocess.run(
["python", "scripts/stage_media.py", source_file],
capture_output=True,
text=True,
check=True
)
staged_path = result.stdout.strip()
source_file = "/home/user/Pictures/photo.jpg"
result = subprocess.run(
["python", "scripts/stage_media.py", source_file],
capture_output=True,
text=True,
check=True
)
staged_path = result.stdout.strip()
Step 2: Send with QQBot using qqmedia tags
步骤2:使用qqmedia标签通过QQBot发送
qqbot_message = f"<qqmedia>{staged_path}</qqmedia>"
qqbot_message = f"<qqmedia>{staged_path}</qqmedia>"
... send qqbot_message through your QQBot integration ...
... 通过你的QQBot集成发送qqbot_message ...
Step 3: Clean up the staged copy
步骤3:清理暂存副本
subprocess.run(
["python", "scripts/stage_media.py", "--cleanup", staged_path],
check=True
)
undefinedsubprocess.run(
["python", "scripts/stage_media.py", "--cleanup", staged_path],
check=True
)
undefinedPattern 2: Send an HTTP(S) URL
模式2:发送HTTP(S)链接
python
undefinedpython
undefinedNo staging or cleanup needed for URLs
链接无需暂存或清理
url = "https://example.com/image.png"
qqbot_message = f"<qqmedia>{url}</qqmedia>"
url = "https://example.com/image.png"
qqbot_message = f"<qqmedia>{url}</qqmedia>"
... send directly through QQBot ...
... 直接通过QQBot发送 ...
undefinedundefinedPattern 3: Batch Send Multiple Files
模式3:批量发送多个文件
python
import subprocess
files = [
"/path/to/image1.png",
"/path/to/video.mp4",
"/path/to/audio.mp3"
]
staged_files = []
try:
# Stage all files
for source in files:
result = subprocess.run(
["python", "scripts/stage_media.py", source],
capture_output=True,
text=True,
check=True
)
staged_path = result.stdout.strip()
staged_files.append(staged_path)
# Send each file
qqbot_message = f"<qqmedia>{staged_path}</qqmedia>"
# ... send through QQBot ...
finally:
# Always clean up all staged files
for staged in staged_files:
subprocess.run(
["python", "scripts/stage_media.py", "--cleanup", staged],
check=False # Don't fail if cleanup fails
)python
import subprocess
files = [
"/path/to/image1.png",
"/path/to/video.mp4",
"/path/to/audio.mp3"
]
staged_files = []
try:
# 暂存所有文件
for source in files:
result = subprocess.run(
["python", "scripts/stage_media.py", source],
capture_output=True,
text=True,
check=True
)
staged_path = result.stdout.strip()
staged_files.append(staged_path)
# 发送每个文件
qqbot_message = f"<qqmedia>{staged_path}</qqmedia>"
# ... 通过QQBot发送 ...
finally:
# 始终清理所有暂存文件
for staged in staged_files:
subprocess.run(
["python", "scripts/stage_media.py", "--cleanup", staged],
check=False # 清理失败不终止流程
)Command-Line Interface
命令行界面
Stage a File
暂存文件
bash
python scripts/stage_media.py <source_path>Input: Path to the original file
Output: Absolute path to the staged copy in
Output: Absolute path to the staged copy in
~/.openclaw/media/qqbot/Example:
bash
python scripts/stage_media.py "/home/user/document.pdf"bash
python scripts/stage_media.py <source_path>输入:原始文件路径
输出:暂存副本在中的绝对路径
输出:暂存副本在
~/.openclaw/media/qqbot/示例:
bash
python scripts/stage_media.py "/home/user/document.pdf"Output: /home/user/.openclaw/media/qqbot/a1b2c3d4.pdf
输出:/home/user/.openclaw/media/qqbot/a1b2c3d4.pdf
undefinedundefinedClean Up a Staged File
清理暂存文件
bash
python scripts/stage_media.py --cleanup <staged_path>Input: The exact path returned by the staging command
Output: Success or error message
Output: Success or error message
Example:
bash
python scripts/stage_media.py --cleanup "/home/user/.openclaw/media/qqbot/a1b2c3d4.pdf"bash
python scripts/stage_media.py --cleanup <staged_path>输入:暂存命令返回的准确路径
输出:成功或错误信息
输出:成功或错误信息
示例:
bash
python scripts/stage_media.py --cleanup "/home/user/.openclaw/media/qqbot/a1b2c3d4.pdf"Configuration
配置说明
File Size Limit
文件大小限制
Default: 10 MB
The script enforces this limit during staging. To modify:
python
undefined默认值:10 MB
脚本在暂存阶段会强制执行该限制。如需修改:
python
undefinedIn scripts/stage_media.py, locate:
在scripts/stage_media.py中找到:
MAX_FILE_SIZE = 10 * 1024 * 1024 # 10 MB
MAX_FILE_SIZE = 10 * 1024 * 1024 # 10 MB
Change to desired size, e.g., 20 MB:
修改为目标大小,例如20 MB:
MAX_FILE_SIZE = 20 * 1024 * 1024
undefinedMAX_FILE_SIZE = 20 * 1024 * 1024
undefinedMedia Relay Directory
媒体中转目录
Default:
~/.openclaw/media/qqbot/The script automatically creates this directory if it doesn't exist. To change the location, modify the constant in .
MEDIA_DIRscripts/stage_media.py默认路径:
~/.openclaw/media/qqbot/脚本会自动创建该目录(如果不存在)。如需修改路径,可修改中的常量。
scripts/stage_media.pyMEDIA_DIRSafety Rules
安全规则
Critical: Only Clean Up Staged Paths
重要提示:仅清理暂存路径
DO:
python
staged = subprocess.run(["python", "scripts/stage_media.py", source], ...).stdout.strip()
subprocess.run(["python", "scripts/stage_media.py", "--cleanup", staged], ...)DON'T:
python
undefined正确操作:
python
staged = subprocess.run(["python", "scripts/stage_media.py", source], ...).stdout.strip()
subprocess.run(["python", "scripts/stage_media.py", "--cleanup", staged], ...)错误操作:
python
undefinedNEVER clean up the original source
绝不要清理原始文件
subprocess.run(["python", "scripts/stage_media.py", "--cleanup", source], ...)
subprocess.run(["python", "scripts/stage_media.py", "--cleanup", source], ...)
NEVER clean up HTTP(S) URLs
绝不要清理HTTP(S)链接
subprocess.run(["python", "scripts/stage_media.py", "--cleanup", url], ...)
subprocess.run(["python", "scripts/stage_media.py", "--cleanup", url], ...)
NEVER guess or construct the staged path
绝不要猜测或构造暂存路径
subprocess.run(["python", "scripts/stage_media.py", "--cleanup", "~/.openclaw/media/qqbot/file.txt"], ...)
undefinedsubprocess.run(["python", "scripts/stage_media.py", "--cleanup", "~/.openclaw/media/qqbot/file.txt"], ...)
undefinedWhat Gets Deleted
清理范围
- ✅ Staged copy in
~/.openclaw/media/qqbot/ - ❌ Original source file (never touched)
- ✅ 中的暂存副本
~/.openclaw/media/qqbot/ - ❌ 原始源文件(绝不会被触碰)
Troubleshooting
故障排查
File Too Large
文件过大
Error: "File size exceeds 10 MB limit"
Solution: Reduce file size or increase in the script.
MAX_FILE_SIZE错误信息:"File size exceeds 10 MB limit"
解决方案:缩小文件大小或修改脚本中的值。
MAX_FILE_SIZEFile Not Found
文件未找到
Error: "Source file does not exist"
Solution: Verify the path is correct and the file exists:
python
import os
if os.path.exists(source_file):
# proceed with staging
else:
print(f"File not found: {source_file}")错误信息:"Source file does not exist"
解决方案:验证路径是否正确,文件是否存在:
python
import os
if os.path.exists(source_file):
# 继续执行暂存
else:
print(f"文件未找到:{source_file}")Permission Denied
权限不足
Error: "Permission denied" or "Access denied"
Solution: Check file permissions and ensure the script has read access to the source file and write access to .
~/.openclaw/media/qqbot/错误信息:"Permission denied"或"Access denied"
解决方案:检查文件权限,确保脚本对源文件有读取权限,对目录有写入权限。
~/.openclaw/media/qqbot/Cleanup Fails After Successful Send
发送成功但清理失败
Best Practice: Always attempt cleanup even if sending fails:
python
staged_path = None
try:
staged_path = stage_file(source)
send_to_qqbot(staged_path)
except Exception as e:
print(f"Send failed: {e}")
finally:
if staged_path:
try:
cleanup_file(staged_path)
except Exception as e:
print(f"Cleanup failed for {staged_path}: {e}")
# Log but don't delete manually最佳实践:即使发送失败,也要尝试执行清理:
python
staged_path = None
try:
staged_path = stage_file(source)
send_to_qqbot(staged_path)
except Exception as e:
print(f"发送失败:{e}")
finally:
if staged_path:
try:
cleanup_file(staged_path)
except Exception as e:
print(f"清理失败 {staged_path}:{e}")
# 记录日志,但不要手动删除Integration Example
集成示例
Complete flow for OpenClaw QQBot integration:
python
#!/usr/bin/env python3
import subprocess
import sys
import os
def send_media_to_qqbot(source_path):
"""Stage, send, and clean up media for QQBot."""
# Check if it's a URL
if source_path.startswith(("http://", "https://")):
print(f"Sending URL directly: {source_path}")
qqbot_message = f"<qqmedia>{source_path}</qqmedia>"
# Send through QQBot API here
return True
# Check if file exists
if not os.path.exists(source_path):
print(f"Error: File not found: {source_path}")
return False
staged_path = None
try:
# Stage the file
result = subprocess.run(
["python", "scripts/stage_media.py", source_path],
capture_output=True,
text=True,
check=True
)
staged_path = result.stdout.strip()
print(f"Staged to: {staged_path}")
# Send through QQBot
qqbot_message = f"<qqmedia>{staged_path}</qqmedia>"
print(f"Sending: {qqbot_message}")
# ... actual QQBot send logic here ...
return True
except subprocess.CalledProcessError as e:
print(f"Staging failed: {e.stderr}")
return False
finally:
# Always clean up the staged file
if staged_path:
try:
subprocess.run(
["python", "scripts/stage_media.py", "--cleanup", staged_path],
check=True
)
print(f"Cleaned up: {staged_path}")
except subprocess.CalledProcessError as e:
print(f"Cleanup failed: {e.stderr}")
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: send_media.py <file_path_or_url>")
sys.exit(1)
send_media_to_qqbot(sys.argv[1])OpenClaw QQBot完整集成流程:
python
#!/usr/bin/env python3
import subprocess
import sys
import os
def send_media_to_qqbot(source_path):
"""暂存、发送并清理QQBot媒体文件。"""
# 判断是否为链接
if source_path.startswith(("http://", "https://")):
print(f"直接发送链接:{source_path}")
qqbot_message = f"<qqmedia>{source_path}</qqmedia>"
# 在此处调用QQBot API发送
return True
# 检查文件是否存在
if not os.path.exists(source_path):
print(f"错误:文件未找到:{source_path}")
return False
staged_path = None
try:
# 暂存文件
result = subprocess.run(
["python", "scripts/stage_media.py", source_path],
capture_output=True,
text=True,
check=True
)
staged_path = result.stdout.strip()
print(f"暂存路径:{staged_path}")
# 通过QQBot发送
qqbot_message = f"<qqmedia>{staged_path}</qqmedia>"
print(f"发送内容:{qqbot_message}")
# ... 此处添加实际QQBot发送逻辑 ...
return True
except subprocess.CalledProcessError as e:
print(f"暂存失败:{e.stderr}")
return False
finally:
# 始终清理暂存文件
if staged_path:
try:
subprocess.run(
["python", "scripts/stage_media.py", "--cleanup", staged_path],
check=True
)
print(f"已清理:{staged_path}")
except subprocess.CalledProcessError as e:
print(f"清理失败:{e.stderr}")
if __name__ == "__main__":
if len(sys.argv) < 2:
print("使用方法:send_media.py <文件路径或链接>")
sys.exit(1)
send_media_to_qqbot(sys.argv[1])License
许可证
MIT License
MIT License