不是教程,是朋友之间的经验分享。不追求完美,追求能跑起来。
一、为什么我要写这个?
"听起来很爽,但技能开发是不是很难?我没编程基础能行吗?"
"配置环境就要搞一天吧?"
"有没有现成的模板可以抄?"
二、OpenClaw 到底是啥?
"当用户说 XXX 的时候,你可以用 YYY 工具去做 ZZZ 的事"
| 触发条件 | |
| 工具调用 | |
| 结果输出 |
三、准备工作:这些东西你得有
# 1. Node.js(v18 以上) node -v 查看版本,没有的话去 nodejs.org 下载# 2. Git(用于克隆项目) git --version # 大部分电脑自带# 3. 一个能跑代码的地方 # 可以是你的本地电脑,也可以是云服务器
| 合计 | 约 3 小时 |
允许自己犯错,踩坑是学习的一部分。
四、核心教程:手把手写第一个技能
cd ~/.openclaw/workspace/skillsmkdir file-organizercd file-organizer
file-organizer/├── SKILL.md技能说明文件 ├── index.js # 主逻辑 └── package.json # 依赖配置
{"name": "file-organizer","version": "1.0.0","description": "自动整理下载文件夹的 AI 技能","main": "index.js","dependencies": {"fs": "^0.0.1-security","path": "^0.12.7"}}
npm install # File Organizer Skill#触发条件 当用户提到以下关键词时触发此技能:- 整理文件夹- 整理下载目录- 文件分类- 清理下载文件夹## 输入参数- folderPath: 要整理的文件夹路径(可选,默认为~/Downloads)## 输出结果- 整理报告:各类文件数量及移动位置## 使用示例用户:帮我整理一下下载文件夹AI:好的,正在整理 ~/Downloads 文件夹...
// index.jsconst fs = require('fs');const path = require('path');// 文件类型映射表const FILE_TYPE_MAP = {image: ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg'],document: ['.pdf', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.txt', '.md'],archive: ['.zip', '.rar', '.7z', '.tar', '.gz'],video: ['.mp4', '.avi', '.mov', '.mkv', '.flv'],audio: ['.mp3', '.wav', '.flac', '.aac'],installer: ['.exe', '.dmg', '.pkg', '.deb']};// 主函数:整理文件夹async function organizeFolder(folderPath) {// 1. 验证路径是否存在if (!fs.existsSync(folderPath)) {throw new Error(`文件夹不存在:${folderPath}`);}// 2. 读取文件夹内容const files = fs.readdirSync(folderPath);// 3. 统计结果const stats = {total: 0,byType: {},errors: []};// 4. 遍历文件for (const file of files) {// 跳过隐藏文件和目录if (file.startsWith('.')) continue;const filePath = path.join(folderPath, file);// 只处理文件,跳过子文件夹if (!fs.statSync(filePath).isFile()) continue;stats.total++;// 5. 判断文件类型const ext = path.extname(file).toLowerCase();let fileType = 'other';for (const [type, extensions] of Object.entries(FILE_TYPE_MAP)) {if (extensions.includes(ext)) {fileType = type;break;}}// 6. 创建目标文件夹并移动文件try {const targetDir = path.join(folderPath, fileType);if (!fs.existsSync(targetDir)) {fs.mkdirSync(targetDir, { recursive: true });}const targetPath = path.join(targetDir, file);// 如果目标文件已存在,添加时间戳let finalPath = targetPath;let counter = 1;while (fs.existsSync(finalPath)) {const name = path.basename(file, ext);finalPath = path.join(targetDir, `${name}_${counter}${ext}`);counter++;}fs.renameSync(filePath, finalPath);// 统计stats.byType[fileType] = (stats.byType[fileType] || 0) + 1;}catch (error) {stats.errors.push({ file, error: error.message });}}return stats;}// 生成报告function generateReport(stats){ let report = `✅ 整理完成!\n\n`;report += `📊 共处理 ${stats.total} 个文件\n\n`;report += `📁 分类结果:\n`;for (const [type, count] of Object.entries(stats.byType)) {const emoji = {image: '🖼️',document: '📄',archive: '📦',video: '🎬',audio: '🎵',installer: '📥',other: '📎'}[type];report += ` ${emoji}${type}: ${count} 个\n`; }if (stats.errors.length > 0) {report += `\n⚠️ 有 ${stats.errors.length} 个文件处理失败\n`;}return report; }// 导出给 OpenClaw 调用module.exports = {name: 'file-organizer',description: '自动整理文件夹,按文件类型分类',execute: async (params) => {const folderPath = params.folderPath || path.join(require('os').homedir(), 'Downloads');console.log(`🔍 开始整理:${folderPath}`);const stats = await organizeFolder(folderPath);const report = generateReport(stats);console.log(report);return report;}};
#创建测试文件夹mkdir -p /test-downloads# 放几个测试文件进去touch /test-downloads/test.jpgtouch /test-downloads/report.pdftouch /test-downloads/archive.zip# 运行技能node -e " const organizer = require('./index.js'); organizer.execute({ folderPath: '/Users/your-name/test-downloads' }); "
🔍 开始整理:/Users/your-name/test-downloads✅ 整理完成!📊 共处理 3 个文件📁 分类结果:🖼️ image: 1 个📄 document: 1 个📦 archive: 1 个
Error: EACCES: permission denied 文件夹路径:/Users/xxx/My Downloads 目标文件夹已有同名文件,直接覆盖会丢数据 五、进阶:让技能更聪明一点
// 保存用户配置const config = {lastFolder: '~/Downloads',customRules: {'.sketch': 'design','.fig': 'design'}};// 下次自动用上次的文件夹
文件整理 + 云盘同步 + 通知推送↓整理完自动上传到百度网盘,然后发微信通知你
// 不好的做法throw new Error(error.stack);// 好的做法return `⚠️ 整理过程中遇到一点问题:${error.message},请稍后再试`;
六、实战案例:我写的这个技能能干嘛
Downloads/├── 截图 2026-03-30 10.23.png├── 截图 2026-03-30 11.45.png├── 合同.pdf├── 报价单.xlsx├── node-v24.11.1.pkg├── 某软件.dmg└── ... (还有 80+ 个文件)
Downloads/├── image/ │├── 截图 2026-03-30 10.23.png │└── 截图 2026-03-30 11.45.png├── document/ │├── 合同.pdf │└── 报价单.xlsx├── installer/ │├── node-v24.11.1.pkg │└── 某软件.dmg└── ... (清爽了)
按日期分类:创建 2026-03/、2026-02/ 这样的文件夹 按项目分类:识别文件名中的项目关键词 自动删除旧文件:超过 30 天的安装包直接删 云同步:整理完自动上传到网盘
夜雨聆风