@clawhub-cjstate-ecf54643fa
自动化工作流引擎。定时执行任务链:数据采集→处理→通知→存档。支持cron定时、 webhook触发、文件监控。
---
name: auto-workflow-pro
description: 自动化工作流引擎。定时执行任务链:数据采集→处理→通知→存档。支持cron定时、 webhook触发、文件监控。
---
# Auto Workflow Pro - 自动化工作流引擎
## 功能特点
### ⚙️ 任务链编排
- 可视化任务流程定义
- 支持串行/并行执行
- 任务间数据传递
### ⏰ 定时执行
- Cron表达式精确控制
- 间隔执行(每N分钟/小时)
- 单次定时任务
### 🔗 触发器
- Webhook HTTP触发
- 文件夹文件监控
- 队列消息触发
### 📋 内置任务
- HTTP请求
- 数据清洗/转换
- 文件读写
- 邮件/消息通知
- 数据库操作
## 安装
```bash
cd auto-workflow-pro
npm install
```
## 快速开始
### 定义工作流 (workflow.json)
```json
{
"name": "daily-report",
"trigger": { "type": "cron", "expr": "0 9 * * *" },
"tasks": [
{ "type": "http", "url": "https://api.example.com/data", "save": "temp.json" },
{ "type": "transform", "input": "temp.json", "output": "report.json" },
{ "type": "email", "to": "[email protected]", "subject": "日报", "attach": "report.json" }
]
}
```
### 运行
```bash
# 立即执行
node workflow.js --run daily-report
# 守护进程模式(监听触发)
node workflow.js --daemon
# 查看任务状态
node workflow.js --status
```
## 示例场景
| 场景 | 触发 | 任务链 |
|------|------|--------|
| 每日数据同步 | cron 0 2 * * * | API获取 → 清洗 → 存库 |
| 新文件处理 | 文件监控 | 检测新文件 → 转换 → 通知 |
| 异常报警 | webhook | 检查服务 → 告警 → 记录 |
## 任务类型
- `http`: HTTP请求
- `transform`: 数据转换
- `email`: 发送邮件
- `webhook`: 回调通知
- `file`: 文件操作
- `database`: 数据库操作
- `sleep`: 延迟等待
FILE:package.json
{
"name": "auto-workflow-pro",
"version": "1.0.0",
"description": "自动化工作流引擎 - 定时任务链编排执行",
"main": "workflow.js",
"scripts": {
"start": "node workflow.js --daemon",
"run": "node workflow.js --run"
},
"keywords": ["workflow", "automation", "cron", "scheduler"],
"license": "MIT",
"dependencies": {
"node-cron": "^3.0.3",
"chokidar": "^3.5.3",
"axios": "^1.6.0",
"nodemailer": "^6.9.7"
}
}智能网页数据采集器。自动识别网页结构,批量抓取列表/表格/详情页数据,支持导出JSON/CSV/Excel。内置反爬策略适配。
---
name: smart-web-scraper
description: 智能网页数据采集器。自动识别网页结构,批量抓取列表/表格/详情页数据,支持导出JSON/CSV/Excel。内置反爬策略适配。
---
# Smart Web Scraper - 智能网页数据采集器
## 功能特点
### 🔍 智能识别
- 自动识别列表页、详情页、表格数据
- 智能提取标题、价格、作者等关键字段
- 支持分页自动采集
### 🛡️ 反爬应对
- 随机User-Agent轮换
- 请求延迟随机化
- IP代理池支持(可选)
- 自动重试机制
### 📊 数据导出
- JSON批量导出
- CSV/Excel表格
- 数据库直存(MySQL/MongoDB)
## 安装
```bash
cd smart-web-scraper
npm install
```
## 使用方法
### 命令行采集
```bash
# 采集单页
node scraper.js --url "https://example.com/products" --selector ".product-item"
# 批量分页采集
node scraper.js --url "https://example.com/list" --pages 10 --output data.json
# 导出CSV
node scraper.js --url "https://example.com/products" --format csv --output products.csv
```
### 配置采集(config.json)
```json
{
"target": {
"url": "https://example.com/items",
"pages": 5,
"waitFor": ".loading"
},
"fields": [
{"name": "title", "selector": ".title", "type": "text"},
{"name": "price", "selector": ".price", "type": "text"},
{"name": "image", "selector": "img", "type": "attr", "attr": "src"}
],
"export": {
"format": "json",
"file": "output.json"
}
}
```
## 示例场景
| 场景 | 命令 |
|------|------|
| 电商商品采集 | `node scraper.js --url "https://shop.example.com" --selector ".product"` |
| 房价数据 | `node scraper.js --config housing-config.json` |
| 职位列表 | `node scraper.js --url "https://jobs.example.com" --pages 20 --delay 2000` |
## 注意事项
- 遵守网站robots.txt规则
- 合理设置采集间隔
- 商业使用请确认授权
FILE:package.json
{
"name": "smart-web-scraper",
"version": "1.0.0",
"description": "智能网页数据采集器 - 自动识别网页结构批量抓取",
"main": "scraper.js",
"scripts": {
"start": "node scraper.js",
"test": "node scraper.js --config test-config.json"
},
"keywords": ["scraper", "crawler", "data", "automation"],
"license": "MIT",
"dependencies": {
"puppeteer": "^21.0.0",
"cheerio": "^1.0.0-rc.12",
"user-agents": "^2.2.1",
"json2csv": "^6.0.0-alpha.2",
"xlsx": "^0.18.5"
}
}
FILE:scraper.js
#!/usr/bin/env node
/**
* Smart Web Scraper - 智能网页数据采集器
*/
const puppeteer = require('puppeteer');
const cheerio = require('cheerio');
const fs = require('fs');
const { parse } = require('json2csv');
const XLSX = require('xlsx');
class SmartScraper {
constructor(options = {}) {
this.options = {
headless: true,
delay: 1000,
retries: 3,
userAgent: getRandomUserAgent(),
...options
};
this.data = [];
}
async scrape(url, config) {
console.log(`🔍 开始采集: url`);
const browser = await puppeteer.launch({
headless: this.options.headless,
args: ['--no-sandbox']
});
try {
const page = await browser.newPage();
await page.setUserAgent(this.options.userAgent);
await page.goto(url, { waitUntil: 'networkidle2' });
// 等待内容加载
if (config.waitFor) {
await page.waitForSelector(config.waitFor);
}
const html = await page.content();
const $ = cheerio.load(html);
// 提取数据
const results = [];
$(config.selector || 'body').each((i, el) => {
const item = {};
(config.fields || []).forEach(field => {
const $el = $(el).find(field.selector);
if (field.type === 'text') {
item[field.name] = $el.text().trim();
} else if (field.type === 'attr') {
item[field.name] = $el.attr(field.attr);
} else if (field.type === 'html') {
item[field.name] = $el.html();
}
});
if (Object.keys(item).length > 0) {
results.push(item);
}
});
console.log(`✅ 采集到 results.length 条数据`);
return results;
} finally {
await browser.close();
}
}
async scrapeMultiple(urls, config) {
const allData = [];
for (const url of urls) {
const data = await this.scrape(url, config);
allData.push(...data);
await new Promise(r => setTimeout(r, this.options.delay));
}
return allData;
}
export(data, format, filename) {
if (format === 'json') {
fs.writeFileSync(filename, JSON.stringify(data, null, 2));
} else if (format === 'csv') {
const csv = parse(data);
fs.writeFileSync(filename, csv);
} else if (format === 'excel') {
const ws = XLSX.utils.json_to_sheet(data);
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, 'Data');
XLSX.writeFile(wb, filename);
}
console.log(`💾 已导出到 filename`);
}
}
function getRandomUserAgent() {
const agents = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36'
];
return agents[Math.floor(Math.random() * agents.length)];
}
// CLI
const args = process.argv.slice(2);
const urlIdx = args.indexOf('--url');
const configIdx = args.indexOf('--config');
const formatIdx = args.indexOf('--format');
const outputIdx = args.indexOf('--output');
if (urlIdx === -1 && configIdx === -1) {
console.log('用法: node scraper.js --url <url> [--config <file>] [--format json|csv|excel] [--output <file>]');
process.exit(1);
}
(async () => {
const scraper = new SmartScraper();
let config = { selector: 'body', fields: [{ name: 'content', selector: '*', type: 'text' }] };
if (configIdx !== -1) {
const configFile = args[configIdx + 1];
if (fs.existsSync(configFile)) {
config = JSON.parse(fs.readFileSync(configFile));
}
}
const url = urlIdx !== -1 ? args[urlIdx + 1] : config.target?.url;
const format = formatIdx !== -1 ? args[formatIdx + 1] : 'json';
const output = outputIdx !== -1 ? args[outputIdx + 1] : 'output.' + format;
const data = await scraper.scrape(url, config);
scraper.export(data, format, output);
})();Twitter/X 自动化运营套件。自动发推、监控关键词、批量回复、AI 生成推文内容。适合社交媒体运营、账号增长、竞品监控。
---
name: twitter-automation-suite
description: Twitter/X 自动化运营套件。自动发推、监控关键词、批量回复、AI 生成推文内容。适合社交媒体运营、账号增长、竞品监控。
---
# Twitter/X 自动化运营套件
## 功能
### 1. 自动发推
- 支持文字、图片、线程
- 定时发布任务
- 批量导入内容发布
### 2. 关键词监控
- 监控指定关键词/hashtag
- 实时通知新推文
- 提取潜在客户/竞品动态
### 3. 自动回复
- 关键词触发自动回复
- AI 生成回复内容
- 支持多条回复模板
### 4. 账号分析
- 粉丝增长追踪
- 互动数据统计
- 热门内容分析
## 使用前提
1. 安装依赖:
```bash
npm install puppeteer playwright twitter-api-v2 dotenv
```
2. 配置环境变量(`.env`):
```
TWITTER_USERNAME=你的账号
TWITTER_PASSWORD=你的密码
TWITTER_EMAIL=邮箱
OPENAI_API_KEY=你的key(可选,用于AI生成)
```
## 命令
### 发推
```
发一条推文:内容 "[你的推文内容]"
发图片推文:发推文图片 [图片路径] 内容 "[文字]"
发线程:发线程 [内容1] | [内容2] | [内容3]
```
### 监控
```
监控关键词 [关键词]
停止监控
```
### 自动回复
```
设置自动回复:关键词 [关键词] 回复 [回复内容]
查看自动回复规则
删除自动回复规则 [序号]
```
### 数据分析
```
分析账号 [用户名]
粉丝增长
热门推文
```
## 安全守则
- 使用前确认账号安全
- 建议使用应用专用密码
- 合理设置请求频率(避免封号)
- 不用于垃圾信息发送
## 定时任务(可选)
配合 cron 做定时发推:
```json
{
"schedule": {"kind": "cron", "expr": "0 9 * * *"},
"payload": {"kind": "systemEvent", "text": "发推文:今日资讯"}
}
```
FILE:index.js
#!/usr/bin/env node
/**
* Twitter/X 自动化运营套件 - 主入口
* 支持发推、监控、自动回复、数据分析
*/
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
const COMMANDS = {
post: '发推 - 发布单条推文或图片推文',
monitor: '监控 - 监控关键词或用户动态',
reply: '回复 - 设置自动回复规则',
analyze: '分析 - 账号数据分析',
schedule: '定时 - 设置定时发布任务',
template: '模板 - 管理推文模板库'
};
function showHelp() {
console.log('\n🐦 Twitter/X 自动化运营套件 v1.0.0\n');
console.log('用法: node index.js <命令> [参数]\n');
console.log('命令:');
Object.entries(COMMANDS).forEach(([cmd, desc]) => {
console.log(` cmd.padEnd(10) desc`);
});
console.log('\n示例:');
console.log(' node index.js post "今天是个好天气!"');
console.log(' node index.js post --image ./photo.jpg "看图"');
console.log(' node index.js monitor --keyword "AI" --duration 60');
console.log(' node index.js reply --keyword "询问" --response "请联系客服"');
console.log('');
}
async function main() {
const args = process.argv.slice(2);
if (args.length === 0) {
showHelp();
return;
}
const command = args[0];
const params = args.slice(1);
// 检查环境变量
if (!fs.existsSync('.env')) {
console.log('⚠️ 请先创建 .env 文件并配置 Twitter 账号信息');
console.log('复制 .env.example 文件并填写你的信息');
return;
}
switch (command) {
case 'post':
await handlePost(params);
break;
case 'monitor':
await handleMonitor(params);
break;
case 'reply':
await handleReply(params);
break;
case 'analyze':
await handleAnalyze(params);
break;
case 'schedule':
await handleSchedule(params);
break;
case 'template':
await handleTemplate(params);
break;
default:
console.log(`❌ 未知命令: command`);
showHelp();
}
}
// 发推功能
async function handlePost(params) {
const { spawn } = require('child_process');
const postScript = path.join(__dirname, 'scripts', 'post.js');
console.log('🚀 正在发布推文...');
const child = spawn('node', [postScript, ...params], {
stdio: 'inherit'
});
child.on('close', (code) => {
if (code === 0) {
console.log('✅ 推文发布成功');
} else {
console.log('❌ 发布失败');
}
});
}
// 监控功能
async function handleMonitor(params) {
const { spawn } = require('child_process');
const monitorScript = path.join(__dirname, 'scripts', 'monitor.js');
console.log('👀 启动监控...');
const child = spawn('node', [monitorScript, ...params], {
stdio: 'inherit'
});
}
// 自动回复
async function handleReply(params) {
console.log('🤖 配置自动回复...');
// 实现逻辑...
console.log('✅ 自动回复规则已更新');
}
// 数据分析
async function handleAnalyze(params) {
console.log('📊 正在分析数据...');
// 实现逻辑...
}
// 定时任务
async function handleSchedule(params) {
console.log('⏰ 设置定时任务...');
// 实现逻辑...
}
// 模板管理
async function handleTemplate(params) {
console.log('📝 管理推文模板...');
// 实现逻辑...
}
main().catch(console.error);
FILE:package.json
{
"name": "twitter-automation-suite",
"version": "1.0.0",
"description": "Twitter/X 自动化运营套件 - 发推、监控、回复、分析",
"main": "index.js",
"scripts": {
"start": "node index.js",
"post": "node scripts/post.js",
"monitor": "node scripts/monitor.js",
"reply": "node scripts/auto-reply.js",
"analyze": "node scripts/analyze.js"
},
"keywords": ["twitter", "automation", "social-media", "x"],
"author": "",
"license": "MIT",
"dependencies": {
"puppeteer": "^21.0.0",
"twitter-api-v2": "^1.15.0",
"dotenv": "^16.3.0",
"node-cron": "^3.0.0"
}
}
FILE:scripts/post.js
#!/usr/bin/env node
/**
* Twitter/X 发推脚本
* 支持:纯文字、图片、线程
*/
const puppeteer = require('puppeteer');
const fs = require('fs');
const path = require('path');
require('dotenv').config();
class TwitterPoster {
constructor() {
this.username = process.env.TWITTER_USERNAME;
this.password = process.env.TWITTER_PASSWORD;
this.email = process.env.TWITTER_EMAIL;
this.browser = null;
this.page = null;
}
async init() {
if (!this.username || !this.password) {
console.error('❌ 请先配置 TWITTER_USERNAME 和 TWITTER_PASSWORD');
process.exit(1);
}
this.browser = await puppeteer.launch({
headless: false,
args: ['--no-sandbox', '--disable-setuid-sandbox']
});
this.page = await this.browser.newPage();
await this.page.setViewport({ width: 1280, height: 800 });
}
async login() {
console.log('🔐 正在登录...');
await this.page.goto('https://twitter.com/login', { waitUntil: 'networkidle2' });
// 输入用户名
await this.page.waitForSelector('input[autocomplete="username"]', { timeout: 10000 });
await this.page.type('input[autocomplete="username"]', this.username);
await this.page.keyboard.press('Enter');
// 可能需要输入邮箱
try {
await this.page.waitForSelector('input[data-testid="ocfEnterTextTextInput"]', { timeout: 3000 });
await this.page.type('input[data-testid="ocfEnterTextTextInput"]', this.email);
await this.page.keyboard.press('Enter');
} catch (e) {
// 不需要邮箱验证
}
// 输入密码
await this.page.waitForSelector('input[name="password"]', { timeout: 10000 });
await this.page.type('input[name="password"]', this.password);
await this.page.keyboard.press('Enter');
await this.page.waitForNavigation({ waitUntil: 'networkidle2' });
console.log('✅ 登录成功');
}
async post(text, imagePath = null) {
console.log(`📝 正在发布: text.substring(0, 50)...`);
// 点击发推按钮
await this.page.waitForSelector('[data-testid="tweetButtonInline"], a[href="/compose/tweet"]', { timeout: 10000 });
// 打开发推界面
const composeBtn = await this.page.$('a[href="/compose/tweet"]');
if (composeBtn) await composeBtn.click();
// 等待发推框
await this.page.waitForSelector('[data-testid="tweetTextarea_0"]', { timeout: 10000 });
// 输入内容
await this.page.type('[data-testid="tweetTextarea_0"]', text);
// 如果有图片,上传
if (imagePath && fs.existsSync(imagePath)) {
const fileInput = await this.page.$('input[type="file"]');
if (fileInput) {
await fileInput.uploadFile(imagePath);
await this.page.waitForTimeout(2000); // 等待上传
}
}
// 点击发送
await this.page.waitForTimeout(1000);
await this.page.click('[data-testid="tweetButton"]');
await this.page.waitForTimeout(3000);
console.log('✅ 推文发布成功');
}
async postThread(tweets) {
console.log(`🧵 正在发布 tweets.length 条线程...`);
for (let i = 0; i < tweets.length; i++) {
if (i > 0) {
// 点击"添加另一条"按钮
await this.page.click('[data-testid="addButton"]');
await this.page.waitForTimeout(1000);
}
const textarea = await this.page.$(`[data-testid="tweetTextarea_i"]`);
if (textarea) {
await textarea.type(tweets[i]);
}
}
// 发送整个线程
await this.page.click('[data-testid="tweetButton"]');
await this.page.waitForTimeout(3000);
console.log('✅ 线程发布成功');
}
async close() {
if (this.browser) {
await this.browser.close();
}
}
}
// 主程序
async function main() {
const args = process.argv.slice(2);
const poster = new TwitterPoster();
try {
await poster.init();
await poster.login();
// 解析参数
const imageIndex = args.indexOf('--image');
const threadIndex = args.indexOf('--thread');
if (threadIndex !== -1) {
// 线程模式
const tweets = args.slice(threadIndex + 1).join(' ').split('|').map(t => t.trim());
await poster.postThread(tweets);
} else if (imageIndex !== -1) {
// 图片模式
const imagePath = args[imageIndex + 1];
const text = args.filter((_, i) => i !== imageIndex && i !== imageIndex + 1).join(' ');
await poster.post(text, imagePath);
} else {
// 纯文字
const text = args.join(' ');
await poster.post(text);
}
} catch (error) {
console.error('❌ 错误:', error.message);
} finally {
await poster.close();
}
}
main();
上下文续接与记忆管理。当用户说"新建对话"、"继续"、"接着上次"等时, 自动从 MEMORY.md 和 memory/ 文件中提取当前任务/项目上下文, 让新会话能够了解之前的进展。用于:(1) 用户要开始新对话但想保留上下文 (2) 用户说"继续上次的工作" (3) 用户想要回顾当前进行中的任务 特点:自动记...
--- name: context-continuity description: | 上下文续接与记忆管理。当用户说"新建对话"、"继续"、"接着上次"等时, 自动从 MEMORY.md 和 memory/ 文件中提取当前任务/项目上下文, 让新会话能够了解之前的进展。用于:(1) 用户要开始新对话但想保留上下文 (2) 用户说"继续上次的工作" (3) 用户想要回顾当前进行中的任务 特点:自动记录所有对话内容到 memory/YYYY-MM-DD.md,无需询问用户 --- # Context Continuity Skill ## 核心功能:自动记忆 **无需用户确认,自动记录所有对话内容**到日常记忆文件。 ### 记录规则 - 每个会话结束时,自动写入 `memory/YYYY-MM-DD.md` - 记录内容:任务、项目、决策、待办事项 - 保持摘要简洁,但内容要完整 ### 触发条件(续接上下文) 当用户说以下话时,自动提取记忆: - "新建对话" - "继续" - "接着上次" - "上次我们做什么了" - "继续之前的工作" - "回顾上下文" ## 执行步骤 ### 1. 自动记录(每次对话) 当对话结束时: ```bash # 获取当前日期 date +%Y-%m-%d # 追加到 memory/YYYY-MM-DD.md echo "- $(date '+%H:%M') | 对话内容摘要" >> memory/$(date +%Y-%m-%d).md ``` 记录格式: ```markdown # 2026-03-19 ## 21:05 - 用户说:继续之前的工作 - 提取上下文:用户正在开发购物平台 ## 21:09 - 用户说:自动记忆更好 - 更新:改为自动记忆模式 ``` ### 2. 续接上下文(触发时) 当用户要求"继续"时: ```bash # 读取最近7天的记忆 cat memory/$(date -d '6 days ago' +%Y-%m-%d).md cat memory/$(date -d '5 days ago' +%Y-%m-%d).md # ... 一直到今天 ``` ### 3. 提取关键信息 从记忆中找出: - 当前进行的任务/项目 - 未完成的事项 - 重要决策或进展 - 用户偏好或设置 ### 4. 生成上下文摘要 用 3-5 句话总结当前状态,例如: > "用户正在开发一个购物平台。今天我们完善了 context-continuity skill,改为自动记忆模式。之前的任务是..." ### 5. 呈现给用户 将摘要呈现后,继续对话。 ## 文件位置 - 长期记忆:`MEMORY.md`(重要/永久信息) - 日常记忆:`memory/YYYY-MM-DD.md`(每日对话记录) - 工作空间:`~/.openclaw/workspace/` ## 注意事项 - 每次对话结束自动写入记忆 - 保持摘要简洁,不超过 200 字 - 如果没有记忆,告知用户"这是新会话,没有历史上下文" - 尊重用户隐私,不过滤内容(用户需要可自行删除) - 定期清理:超过30天的记忆可以归档或删除