写在前面

前面的文章我们学会了让AI帮你操作浏览器,但这些都需要你手动触发。

真正的私人AI助手,应该能「主动干活」:

  • 每天早上自动推送热榜资讯
  • 定时检查邮件并提醒重要来信
  • 监控某个API异常时主动报警

本文将从实际场景出发,手把手教你实现定时任务与主动推送,让你的AI真正「活」起来。


真实场景分析

在我日常工作中,有三个痛点特别适合自动化:

场景一:每日热点资讯推送

作为一个技术博主,我需要每天了解各平台热点,但一个个手动去查太费时间。

解决方案:每天早上8点,自动抓取6大平台热榜,推送到飞书。

场景二:GitHub项目Star监控

我维护的开源项目,如果Star数突然暴涨,需要第一时间知道(可能是被大V转发了)。

解决方案:每半小时检查一次GitHub API,超过阈值立即推送。

场景三:服务器异常报警

线上服务挂了,不能等用户反馈才知道。

解决方案:每5分钟ping一次API接口,连续3次失败则触发报警。


核心概念

1. Cron表达式 — 定时任务的大脑

Cron是一个时间调度器,用字符串表示执行时间:

┌───────────── 分钟 (0-59)
│ ┌─────────── 小时 (0-23)
│ │ ┌───────── 日期 (1-31)
│ │ │ ┌─────── 月份 (1-12)
│ │ │ │ ┌───── 星期 (0-7, 0和7都是周日)
│ │ │ │ │
* * * * *

实战例子:

  • 0 8 * * * = 每天早上8点
  • 0 */2 * * * = 每隔2小时
  • 0 9-18 * * * = 早上9点到下午6点每小时
  • 0 8 * * 1-5 = 工作日早上8点(周一到周五)
  • */30 * * * * = 每30分钟

💡 小技巧:如果你不确定cron表达式,可以访问 https://crontab.guru/ 在线验证。

2. 任务链 — 让多个动作串联

实际的定时任务往往不是单一动作,而是一串操作:

获取数据 → 清洗数据 → 格式化 → 推送消息

OpenClaw的任务链机制支持这种串联,每个步骤的输出可以作为下一个步骤的输入。


实战:每日热榜自动推送

这是我自己正在用的真实方案,可以直接抄作业。

架构概览

┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│  定时触发   │────▶│  获取热榜   │────▶│  推送到飞书  │
│ (cron 8点)  │     │ (6个平台)   │     │  (富文本)   │
└─────────────┘     └─────────────┘     └─────────────┘

步骤1:部署热榜API服务

我之前写了一个DailyHotApi服务,已经部署在服务器上:

# 服务器上运行
pm2 start daily-hot-api.js --name daily-hot
# 端口6688

这个服务提供了统一的API接口:

# 获取所有平台热榜
curl http://localhost:6688/api/hot

# 返回格式
{
  "weibo": [{"word": "微博热搜1", "raw_hot": 1000000}, ...],
  "zhihu": [{"title": "知乎热榜1", "url": "..."}, ...],
  "bilibili": [{"title": "B站热门1", "aid": 123}, ...],
  "juejin": [{"title": "掘金热榜1", "url": "..."}, ...],
  "douyin": [{"title": "抖音热点1", "url": "..."}, ...],
  "csdn": [{"title": "CSDN热榜1", "url": "..."}, ...]
}

如果你不想自己写API,可以直接用现成的开源项目,或者用上一文学到的浏览器自动化去抓取。

步骤2:创建定时任务配置

openclaw.yaml中配置:

# openclaw.yaml
cron:
  daily-hot-push:
    enabled: true
    schedule: "0 8 * * *"  # 每天早上8点
    timezone: "Asia/Shanghai"
    
    steps:
      - name: fetch-hot
        http:
          url: "http://localhost:6688/api/hot"
          timeout: 10000
      
      - name: format-message
        template: |
          🌅 每日热榜 - {{ .Date }}
          
          🔥 微博热搜 Top5:
          {{ range $i, $item := .Data.weibo }}
          {{ add $i 1 }}. {{ $item.word }}
          {{ end }}
          
          💡 知乎热榜 Top5:
          {{ range $i, $item := .Data.zhihu }}
          {{ add $i 1 }}. {{ $item.title }}
          {{ end }}
          
          📺 B站热门 Top5:
          {{ range $i, $item := .Data.bilibili }}
          {{ add $i 1 }}. {{ $item.title }}
          {{ end }}
          
          ⌨️ 掘金热榜 Top5:
          {{ range $i, $item := .Data.juejin }}
          {{ add $i 1 }}. {{ $item.title }}
          {{ end }}
          
          🎵 抖音热点 Top5:
          {{ range $i, $item := .Data.douyin }}
          {{ add $i 1 }}. {{ $item.title }}
          {{ end }}
          
          💻 CSDN热榜 Top5:
          {{ range $i, $item := .Data.csdn }}
          {{ add $i 1 }}. {{ $item.title }}
          {{ end }}
          
          ---
          📅 推送时间:{{ .Now }}
      
      - name: send-to-feishu
        channel: feishu
        action: send
        receive_id: "ou_your_open_id"  # 替换为你的飞书ID
        msg_type: "text"

步骤3:测试运行

# 手动触发一次测试
openclaw cron run daily-hot-push

# 查看日志
openclaw logs --tail 50

进阶:GitHub Star异常监控

这个场景非常真实,我来说说具体实现。

需求分析

  • 每30分钟检查一次指定仓库的Star数
  • 如果Star数单次增长超过50,触发报警
  • 报警内容包含增长趋势和可能的原因

实现代码

cron:
  github-star-monitor:
    enabled: true
    schedule: "*/30 * * * *"  # 每30分钟
    timeout: 15000
    
    # 上一次检查的Star数(持久化存储)
    state_file: /tmp/github-stars.json
    
    steps:
      - name: fetch-github-stars
        http:
          url: "https://api.github.com/repos/openclaw/openclaw"
          headers:
            User-Agent: "OpenClaw-Monitor"
          timeout: 10000
      
      - name: parse-stars
        # 从响应中提取star数
        assign:
          current_stars: "{{ .Response.stargazers_count }}"
      
      - name: compare-with-last
        # 读取上次状态
        file:
          path: /tmp/github-stars.json
          create: true
      
      - name: check-threshold
        # 计算增长
        set:
          growth: "{{ .current_stars - .last_stars }}"
      
      - name: conditional-push
        # 只有增长超过50才推送
        if: "{{ .growth > 50 }}"
        then:
          - channel: feishu
            action: send
            receive_id: "ou_your_open_id"
            template: |
              🚀 GitHub Star暴涨!
              
              仓库:openclaw/openclaw
              当前Star:{{ .current_stars }}
              增长数:+{{ .growth }}
              
              💡 推测:可能被大V转发了,快去看看GitHub首页!

持久化存储

定时任务需要跨次记忆上次的状态,OpenClaw支持多种状态存储:

# 文件存储(简单场景)
state_file: /tmp/stars.json

# 数据库存储(复杂场景)
state:
  type: redis
  host: localhost
  port: 6379
  key: "github:stars"

条件触发:真正的智能监控

除了时间触发,还可以根据条件触发。

场景:服务器健康检查

cron:
  server-health-check:
    enabled: true
    schedule: "*/5 * * * *"  # 每5分钟
    timeout: 30000
    
    # 连续失败次数(关键!)
    max_retries: 3
    
    steps:
      - name: ping-services
        parallel:
          - name: api
            http:
              url: "https://api.example.com/health"
              timeout: 5000
          - name: db
            http:
              url: "https://db.example.com/health"
              timeout: 5000
          - name: cache
            http:
              url: "https://cache.example.com/health"
              timeout: 5000
      
      - name: check-results
        # 检查是否有服务挂掉
        assign:
          failed_services: "{{ range .Results }}{{ if .Error }}{{ .Name }}{{ end }}{{ end }}"
      
      - name: alert-on-failure
        if: "{{ len .failed_services > 0 }}"
        then:
          - channel: feishu
            action: send
            receive_id: "ou_your_open_id"
            template: |
              🐛 服务异常警告!
              
              失败服务:{{ .failed_services }}
              检查时间:{{ .Now }}
              
              ⚡ 请立即检查!

常见错误排查

❌ 任务没执行

  1. 检查日志openclaw logs -f 查看是否有定时任务触发日志
  2. 验证cron表达式:用在线工具确认表达式正确
  3. 检查时区timezone: "Asia/Shanghai" 是否配置正确
  4. 确认任务启用enabled: true 是否设置

❌ 推送失败

  1. 飞书Bot配置:确认APP_IDAPP_SECRET正确
  2. 权限问题:Bot是否有发消息到对应用户的权限
  3. 网络问题:服务器能否访问open.feishu.cn
  4. Rate Limit:飞书API有频率限制,避免短时间内大量推送

❌ 状态不持久

  1. 文件权限:确保state文件目录可写
  2. Redis连接:如果用Redis,确认连接正常
  3. 路径正确:state_file路径使用绝对路径

❌ 时区问题

最容易踩的坑!OpenClaw默认使用UTC时区:

# ❌ 错误:0 8 UTC = 北京时间16点
cron:
  daily-push:
    schedule: "0 8 * * *"

# ✅ 正确:明确指定时区
cron:
  daily-push:
    schedule: "0 8 * * *"
    timezone: "Asia/Shanghai"

进阶技巧

1. 任务编排:失败重试

cron:
  reliable-task:
    retry:
      max_attempts: 3
      delay: 5000  # 重试间隔5秒

2. 任务编排:超时控制

cron:
  timeout-task:
    timeout: 30000  # 30秒超时

3. 任务编排:并发执行

steps:
  - name: parallel-fetch
    parallel: true  # 同时获取多个数据源
    tasks:
      - http: { url: "https://api1.com" }
      - http: { url: "https://api2.com" }
      - http: { url: "https://api3.com" }

4. 任务编排:依赖链

steps:
  - name: step1
    # ...
  - name: step2
    depends_on: step1  # 等step1完成后再执行
    # ...

总结

本文我们介绍了:

  • Cron表达式:定时任务的时间调度
  • 任务链:多个动作的有序串联
  • 实战案例:每日热榜推送、GitHub监控、服务器报警
  • 常见问题:时区、权限、状态持久化

当你学会定时任务和主动推送后,你的AI助手就真正「活」起来了——它会在指定时间去执行任务,发现异常主动报警,而不需要你每次手动触发。

快去试试吧!

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐