晨间报告 Cron 迁移计划
For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
Goal: 將 OpenClaw cron 晨间报告遷移到獨立 Python 腳本 + Systemd Timer,消除每日 Kimi token 消耗
Architecture:
- Python 腳本直接調用 API(Moonshot balance、Vikunja tasks、Docker status)
- Discord Webhook 推送報告(無需 OpenClaw message 工具)
- Systemd Timer 替代 OpenClaw cron,每天 10:00 JST 運行
- 保留現有報告格式,僅改變執行方式
Tech Stack: Python 3.12+、Systemd、Discord Webhook、Vikunja API、Moonshot API
Related: 項目規則、Obsidian文檔規則
背景與問題
當前 OpenClaw cron 任務 晨间报告 - 东京时间10点 使用 kimi-k2.5 模型,每次運行消耗約 15k-35k tokens:
- 過去幾週多次運行記錄顯示 input tokens 持續累積
- 高峰期單次運行達 169k input tokens
- 對於單純的數據收集和格式化任務,這是不必要的 AI 資源消耗
解決方案: 將報告邏輯遷移到純 Python 腳本,通過 systemd timer 觸發,完全消除 AI token 消耗。
數據需求分析
原始 cron prompt 要求收集以下數據:
| 數據類別 | 來源 | API/命令 |
|---|---|---|
| Moonshot API 餘額 | Moonshot API | GET /v1/users/me/balance |
| 服務器運行時間 | System | uptime |
| 系統負載 | System | cat /proc/loadavg |
| 內存使用 | System | free -h 或 /proc/meminfo |
| 磁盤空間 | System | df -h / |
| Docker 容器狀態 | Docker | docker ps -a --format |
| Vikunja Doing 任務 | Vikunja API | GET /api/v1/projects/{id}/views/{vid}/tasks |
Task 1: 創建 Python 腳本目錄結構
Files:
- Create:
~/.openclaw/workspace/projects/morning-report/(項目目錄) - Create:
~/.openclaw/workspace/projects/morning-report/src/(源碼目錄) - Create:
~/.openclaw/workspace/projects/morning-report/.env.example(環境變量模板)
Step 1: 創建目錄結構
bash
mkdir -p ~/.openclaw/workspace/projects/morning-report/src
cd ~/.openclaw/workspace/projects/morning-report
touch .env.example README.mdStep 2: Commit
bash
cd ~/.openclaw/workspace
git add projects/morning-report/
git commit -m "infra: create morning-report project structure"Task 2: 實現配置管理模塊
Files:
- Create:
~/.openclaw/workspace/projects/morning-report/src/config.py - Create:
~/.openclaw/workspace/projects/morning-report/.env(gitignored)
Step 1: 創建配置模塊
python
"""Configuration management for morning report."""
import os
from dataclasses import dataclass
from pathlib import Path
@dataclass
class Config:
# Moonshot API
moonshot_api_key: str
# Vikunja API
vikunja_base_url: str = "http://localhost:8081"
vikunja_token: str = ""
# Discord Webhook
discord_webhook_url: str = ""
discord_channel_id: str = "1470638978716668061" # #healthcheck
# Report settings
timezone: str = "Asia/Tokyo"
@classmethod
def from_env(cls) -> "Config":
"""Load configuration from environment variables."""
return cls(
moonshot_api_key=os.getenv("MOONSHOT_API_KEY", ""),
vikunja_base_url=os.getenv("VIKUNJA_BASE_URL", "http://localhost:8081"),
vikunja_token=os.getenv("VIKUNJA_TOKEN", ""),
discord_webhook_url=os.getenv("DISCORD_WEBHOOK_URL", ""),
discord_channel_id=os.getenv("DISCORD_CHANNEL_ID", "1470638978716668061"),
timezone=os.getenv("TIMEZONE", "Asia/Tokyo"),
)
def validate(self) -> None:
"""Validate required configuration."""
required = ["moonshot_api_key", "vikunja_token", "discord_webhook_url"]
missing = [f for f in required if not getattr(self, f)]
if missing:
raise ValueError(f"Missing required config: {', '.join(missing)}")Step 2: 創建 .env.example
bash
cat > ~/.openclaw/workspace/projects/morning-report/.env.example << 'EOF'
# Moonshot API
MOONSHOT_API_KEY=sk-...
# Vikunja API
VIKUNJA_BASE_URL=http://localhost:8081
VIKUNJA_TOKEN=tk_...
# Discord Webhook
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/...
DISCORD_CHANNEL_ID=1470638978716668061
# Timezone
TIMEZONE=Asia/Tokyo
EOFStep 3: 創建 .gitignore
bash
cat > ~/.openclaw/workspace/projects/morning-report/.gitignore << 'EOF'
.env
__pycache__/
*.pyc
*.pyo
*.pyd
.Python
*.so
*.egg
*.egg-info/
dist/
build/
.venv/
venv/
EOFStep 4: Commit
bash
cd ~/.openclaw/workspace
git add projects/morning-report/
git commit -m "feat(morning-report): add config management"後續任務摘要
由於內容較長,以下為剩餘任務的概要:
Task 3: 實現數據收集模塊 (collectors.py)
- SystemCollector: 收集 uptime、load avg、memory、disk
- MoonshotCollector: 調用 Moonshot API 獲取餘額
- DockerCollector: 調用 docker ps 獲取容器狀態
- VikunjaCollector: 調用 Vikunja API 獲取 Doing 任務
Task 4: 實現報告生成模塊 (report.py)
- ReportGenerator.generate(): 將數據格式化為 Markdown 報告
- 保持與現有報告格式一致
Task 5: 實現 Discord 發送模塊 (notifier.py)
- DiscordNotifier.send(): 通過 webhook 發送報告
Task 6: 實現主入口腳本 (main.py)
- 整合所有模塊
- 加載配置、收集數據、生成報告、發送通知
Task 7: 創建 Systemd Service 和 Timer
- starsoup-morning-report.service: oneshot service
- starsoup-morning-report.timer: 每天 10:00 JST 運行
- install.sh: 自動安裝腳本
Task 8-12: 配置、測試、安裝、移除舊 Cron、文檔
成本節省估算
| 指標 | 之前 (OpenClaw cron) | 之後 (Python 腳本) |
|---|---|---|
| 每日 Token 消耗 | ~20k-35k | 0 |
| 每日成本 | ~¥0.10-0.20 | ¥0 |
| 每月節省 | ~¥3-6 | - |