外观
夏小秘任务调度器开发文档
约 2418 字大约 8 分钟
OpenClawAI助手任务调度
2026-03-23
专为 OpenClaw Agent 系统设计的智能任务调度器 版本:1.1.0 | 最后更新:2026-03-23
一、项目概述
1.1 背景与目标
夏小秘任务调度器是为了解决 OpenClaw 系统中定时任务管理的需求而开发的。主要目标包括:
- 稳定性:避免 Cron 任务大规模失败问题
- 可控性:集中管理所有定时任务
- 可观测性:实时监控任务执行状态
- 灵活性:支持多种调度策略和优先级
- Agent 归属:每条消息从对应的 Agent 发送,实现"谁的任务谁来发"
1.2 解决的问题
在开发过程中,我们遇到了以下几个关键问题:
- 飞书 open_id 跨应用问题:每个飞书应用有独立的 open_id 上下文
- 消息发送方式:需要使用正确的账号和对应的 open_id
- 与 OpenClaw 集成:需要利用 OpenClaw 的消息系统来处理账号映射
- 配置管理:需要统一管理应用凭据和任务配置
二、系统架构
2.1 整体架构
用户 ↔ 飞书 ↔ OpenClaw Gateway ↔ 夏小秘调度器 ↔ 执行Agent/消息系统
↑
OpenClaw 消息系统
↑
各Agent账号 (default/health/work/...)2.2 核心组件
agents/secretary/
├── scheduler.py # 调度器核心
├── feishu_client.py # 飞书客户端(已废弃,使用OpenClaw消息系统)
├── config_manager.py # 配置管理
├── user_map.py # 用户open_id映射表 ⭐ 新增
├── event_server.py # 事件订阅服务器(可选)
├── start_scheduler.sh # 启动脚本
├── task_state.json # 任务状态文件
├── .env # 环境变量配置
├── venv/ # Python 虚拟环境
└── tasks/ # 任务配置文件
├── all-tasks.yaml # 所有任务配置 ⭐
├── health.yaml # 健康任务
├── daily.yaml # 每日任务
└── weather.yaml # 天气任务2.3 工作流程
1. 调度器启动
↓
2. 加载任务配置 (tasks/*.yaml)
↓
3. 每30分钟检查一次到期任务
↓
4. 按优先级排序(高→低)
↓
5. 最多并发执行3个任务
↓
6. 根据 target_agent 确定发送账号
↓
7. 从 user_map.py 获取对应的 open_id
↓
8. 使用正确的账号+open_id发送消息
↓
9. 更新任务状态和执行结果
↓
10. 生成监控报告三、关键问题与解决方案
3.1 问题一:飞书 open_id 跨应用问题
问题描述:
- 错误码:
99992361 - open_id cross app - 每个飞书应用有独立的 open_id 上下文
- A 应用的 open_id 不能在 B 应用中使用
解决方案:
- 获取每个应用对应的用户 open_id
- 在 user_map.py 中配置映射表
- 调度器根据账号自动选择对应的 open_id
# user_map.py
USER_OPEN_ID_MAP = {
'default': 'ou_xxx', # 夏小语
'health': 'ou_xxx', # 夏小康
'work': 'ou_xxx', # 夏小工
'finance': 'ou_xxx', # 夏小财
'system': 'ou_xxx', # 夏小护
'entertainment': 'ou_xxx', # 夏小趣
'stock': 'ou_xxx', # 夏小股
'website': 'ou_xxx', # 夏小网
}3.2 问题二:API 参数格式
问题描述:
- 错误:
receive_id_type is required - 飞书 API 的
receive_id_type应该在 URL 参数中
解决方案:
# 错误做法
data = {"receive_id": user_id, "receive_id_type": "open_id", ...}
response = requests.post(url, json=data)
# 正确做法
url_with_params = f"{url}?receive_id_type=open_id"
data = {"receive_id": user_id, ...}
response = requests.post(url_with_params, json=data)3.3 问题三:OpenClaw 配置
问题描述:
- 需要在
openclaw.json中配置飞书账号 - 需要添加 bindings 绑定
解决方案: 在 openclaw.json 中添加:
{
"channels": {
"feishu": {
"accounts": {
"secretary": {
"appId": "cli_xxxxxxxxxxxxxx",
"appSecret": "your_app_secret_here",
"receiver": "ou_xxxxxxxxxxxxxxxx"
}
}
}
},
"bindings": [
{
"type": "route",
"agentId": "main",
"match": {
"channel": "feishu",
"accountId": "secretary"
}
}
]
}四、完整配置指南
4.1 环境要求
- Python 3.8+
- OpenClaw 2026.3.11+
- 飞书企业账号
4.2 安装步骤
步骤 1:创建应用
- 登录飞书开放平台:https://open.feishu.cn/
- 创建应用(企业自建)
- 添加权限:
im:message- 发送消息im:message:send_as_bot- 以机器人身份发送
- 发布版本
- 重要:获取用户在应用中的 open_id(见下文)
步骤 2:获取用户的 open_id
每个应用都有自己的用户 open_id,获取方式:
方法1:通过事件订阅
- 配置应用的事件订阅
- 用户给应用发消息
- 从事件中获取用户的 open_id
方法2:通过已有 open_id 转换 如果知道用户在某个应用(如夏小语)的 open_id,可以联系管理员获取其他应用的 open_id
步骤 3:配置 OpenClaw
编辑 openclaw.json,添加相应的账号配置。
步骤 4:配置 user_map.py
创建 user_map.py 文件:
# 用户 open_id 映射表
# 每个应用对应的用户 open_id
USER_OPEN_ID_MAP = {
# 夏小语 (默认)
'default': 'ou_xxx',
# 夏康康 (健康) - 替换为实际ID
'health': 'ou_xxx',
# 夏小工 (工作) - 替换为实际ID
'work': 'ou_xxx',
# 继续添加其他应用...
}
# Agent 到账号的映射
AGENT_TO_ACCOUNT = {
'main': 'default',
'work': 'work',
'health': 'health',
'finance': 'finance',
'system': 'system',
'entertainment': 'entertainment',
'stock': 'stock',
'website': 'website',
}4.3 运行调度器
cd agents/secretary
source venv/bin/activate
./start_scheduler.sh start五、任务配置
5.1 任务文件格式
任务配置文件使用 YAML 格式,放在 tasks/ 目录下:
tasks:
task_id:
name: "任务名称"
description: "任务描述"
target_agent: "目标Agent"
execution_type: "send|call" # send=发送消息, call=调用功能
execution_data:
message: "消息内容" # send类型使用
target: "user:ou_xxx"
action: "action_name" # call类型使用
schedule_type: "time|cron"
schedule_config:
times: ["10:00", "15:00"] # time类型
expr: "0 8 * * *" # cron类型
priority: 8
enabled: true5.2 当前配置的任务(17个)
| 任务ID | 任务名称 | 执行时间 | 发送者 |
|---|---|---|---|
| morning_report | 每日早报(完整版) | 08:00 | 夏小语 |
| health_morning | 健康提醒-上午 | 10:00 | 夏康康 |
| health_afternoon | 健康提醒-下午 | 15:00 | 夏康康 |
| health_evening | 健康提醒-晚上 | 20:00 | 夏康康 |
| weather_check | 天气预警检查 | 07/10/13/16/19 | 夏小语 |
| daily_tech_news | 每日技术资讯 | 12:00 | 夏小工 |
| daily_stock_report | 每日股市报告 | 22:00 | 夏小股 |
| daily_investment | 每日投资建议 | 09:00 | 夏小股 |
| daily_lol_chess | 每日金铲铲资讯 | 09:00 | 夏小趣 |
| daily_game_news | 每日新游戏资讯 | 09:00 | 夏小趣 |
| daily_horoscope | 每日星座运势 | 08:00 | 夏小趣 |
| daily_finance_news | 每日财经新闻 | 12:00 | 夏小财 |
| daily_expense | 每日扣生活费 | 00:00 | 夏小股 |
| daily_system_briefing | 每日系统简报 | 20:00 | 夏小护 |
| weekly_file_check | 每周文件检查提醒 | 周一09:00 | 夏小语 |
| daily_baidu_push | 每日百度推送 | 01:00 | 夏小网 |
| health_noon | 健康资讯-中午 | 12:00 | 夏康康 |
六、使用指南
6.1 基本命令
# 启动调度器
./start_scheduler.sh start
# 停止调度器
./start_scheduler.sh stop
# 查看状态
./start_scheduler.sh status
# 重启调度器
./start_scheduler.sh restart6.2 测试任务执行
cd agents/secretary
source venv/bin/activate
python3 -c "
from scheduler import TaskRegistry, AgentClient
registry = TaskRegistry()
agent_client = AgentClient()
# 测试健康提醒任务
task = registry.tasks['health_morning']
result = agent_client.execute_task(task)
print(f'结果: {result}')
"6.3 查看任务状态
# 查看任务状态文件
cat task_state.json | python3 -m json.tool
# 查看调度器日志
tail -f logs/scheduler_*.log七、监控与维护
7.1 监控脚本
# 查看调度器状态
./start_scheduler.sh status
# 查看最近的任务执行报告
cat logs/latest-report.txt
# 运行监控检查
./monitor.sh7.2 常见问题排查
问题:调度器未运行
# 检查进程
ps aux | grep scheduler
# 启动调度器
./start_scheduler.sh start问题:任务执行失败
# 查看错误日志
grep -i error logs/*.log
# 检查任务配置
cat tasks/*.yaml问题:消息发送失败
# 检查 OpenClaw 配置
cat openclaw.json | grep -A 5 secretary
# 测试消息发送
openclaw message send --channel feishu --account health --target "ou_xxx" --message "测试"八、通过夏小语中转
8.1 架构说明
如果需要夏小秘支持实时交互,可以通过夏小语中转:
用户 → 夏小语 → 夏小秘调度器 → 返回结果 → 夏小语 → 用户8.2 配置方式
- 告诉夏小语调度任务
- 夏小语调用夏小秘的调度器执行任务
- 返回结果给用户
九、开发记录
9.1 关键决策
| 日期 | 决策 | 原因 |
|---|---|---|
| 2026-03-23 | 使用 OpenClaw 消息系统发送消息 | 解决直接使用飞书 API 的权限问题 |
| 2026-03-23 | 接收和发送使用不同账号 | secretary 接收,default 发送 |
| 2026-03-23 | 配置在 openclaw.json 中 | 统一管理,方便维护 |
| 2026-03-23 | 添加 user_map.py 映射表 | 解决 open_id 跨应用问题 |
| 2026-03-23 | 每个任务使用对应的账号发送 | 实现"谁的任务谁来发" |
9.2 经验教训
- 飞书应用是隔离的:每个应用有独立的 open_id 上下文,不能混用
- API 参数位置:飞书 API 的 receive_id_type 必须在 URL 参数中
- 利用现有系统:尽量使用 OpenClaw 的消息系统,而不是重新实现
- 获取正确的 open_id:每个应用都需要获取对应的用户 open_id
十、附录
10.1 命令参考
# 启动调度器
./start_scheduler.sh start
# 停止调度器
./start_scheduler.sh stop
# 查看状态
./start_scheduler.sh status
# 测试发送消息
openclaw message send --channel feishu --account health --target "ou_xxx" --message "内容"10.2 目录结构
agents/secretary/ # 调度器目录
├── scheduler.py # 核心调度器
├── config_manager.py # 配置管理
├── user_map.py # 用户映射(需自行配置)
├── tasks/ # 任务配置目录
│ ├── all-tasks.yaml # 所有任务
│ ├── health.yaml # 健康任务
│ ├── daily.yaml # 每日任务
│ └── weather.yaml # 天气任务
├── logs/ # 日志目录
├── task_state.json # 状态文件
└── start_scheduler.sh # 启动脚本10.3 用户 open_id 映射表(模板)
夏小语 (default): ou_xxx
夏康康 (health): ou_xxx
夏小工 (work): ou_xxx
夏小财 (finance): ou_xxx
夏小护 (system): ou_xxx
夏小趣 (entertainment): ou_xxx
夏小股 (stock): ou_xxx
夏小网 (website): ou_xxx> 注意:实际部署时需要替换为真实的 open_id
十一、总结
夏小秘任务调度器是一个功能完整的定时任务管理系统,集成在 OpenClaw 框架中。通过本文档,你应该能够:
- ✅ 理解系统架构和工作原理
- ✅ 快速搭建和配置调度器
- ✅ 创建和管理定时任务
- ✅ 解决飞书 open_id 跨应用问题
- ✅ 实现"谁的任务谁来发"的功能
- ✅ 监控和维护系统运行
希望这个文档对你有帮助!如果有任何问题,请随时询问。
文档版本:1.1.0最后更新:2026-03-23作者:夏小语 🧚
