Install
openclaw skills install @myd2002/skill-b-pre-brief【会前简报定时任务】每15分钟由 OpenClaw cron 触发一次。负责在会议开始前15分钟至6小时内自动生成并发送会前进度简报。不处理会议创建、会议修改、取消会议、会后纪要等场景。触发关键词:会前简报、pre_brief、发简报、会前准备报告。cron 场景下自动触发,无需用户主动输入。
openclaw skills install @myd2002/skill-b-pre-brief本技能是 cron 定时执行的会前简报流程总控。
职责分工:
OpenClaw(本次对话/cron 任务)
Skill-B(本技能)
gitea-routine-report
imap-smtp-email
配置文件:~/.config/skill-b-pre-brief/.env
首次使用前运行:
bash setup.sh
node main.js scan
返回 JSON,meetings 字段包含所有需要处理的会议,每条有以下字段:
action:"generate_brief" = 正常发简报;"mark_only" = 改期会议只改状态不发邮件repo:仓库全名,如 HKU-AIFusion/dexterous-handmeeting_dir:会议目录名,如 2026-04-22-1500topic:会议主题scheduled_time:会议时间(ISO8601)organizer:组织者 Gitea 用户名attendees:参会人 Gitea 用户名列表attendee_emails:参会人邮箱列表since:Gitea 活动统计开始时间(ISO8601)until:Gitea 活动统计结束时间(ISO8601)report_params:传给 gitea-routine-report 的参数 {repo, since, until}只有会议时间落在“开始前 15 分钟到 6 小时”这个窗口内,才会被 scan 命中。
如果 meetings 为空,本次 cron 无需继续执行。
action == "mark_only" 的会议,直接更新状态对每条 action == "mark_only" 的会议,运行:
node main.js commit \
--repo "HKU-AIFusion/dexterous-hand" \
--meeting-dir "2026-04-22-1500" \
--mark-only
这会直接将 meta.yaml status 改为 brief-sent,不生成简报、不发邮件。
action == "generate_brief" 的会议,逐条生成并发送简报对每条 action == "generate_brief" 的会议,按以下子步骤处理:
使用 scan 返回的 report_params:
python <gitea-routine-report路径>/scripts/generate_report.py \
--repo "HKU-AIFusion/dexterous-hand" \
--since "2026-04-15" \
--until "2026-04-22"
输出是 JSON 数组,取 [0] 元素作为本次会议仓库的数据。
注意:
since/until日期格式为YYYY-MM-DD,从 scan 返回的report_params.since/report_params.until字段取值(已格式化为此格式)。
严格按照 gitea-routine-report 的 SKILL.md 第三步格式输出,对上一步的数据生成:
{
"ai_overview": "...",
"ai_suggestion": "...",
"member_summaries": { "成员名": "一句话摘要" },
"risk_notes": "..."
}
规则同 gitea-routine-report:
member_summaries 键名必须与数据中成员用户名完全一致risk_notes 无风险时填空字符串 ""将上一步 JSON 内容存入 /tmp/ai_brief_{meeting_dir}.json(meeting_dir 中 / 替换为 _):
echo '{"ai_overview": "...", ...}' > /tmp/ai_brief_2026-04-22-1500.json
python -c "
import json, sys, os
sys.path.insert(0, '<gitea-routine-report路径>/scripts')
from render_email import render
data = json.loads(open('/tmp/report_data.json').read())
ai_content = json.loads(open('/tmp/ai_brief_MEETING_DIR.json').read())
repo_data = data[0]
html = render(repo_data, ai_content)
open('/tmp/brief_body_MEETING_DIR.html', 'w').write(html)
print('HTML 已生成,长度:', len(html))
"
注意:
generate_report.py的输出需要先保存到/tmp/report_data.json,再供 render 使用。MEETING_DIR替换为实际目录名(如2026-04-22-1500)。
node main.js commit \
--repo "HKU-AIFusion/dexterous-hand" \
--meeting-dir "2026-04-22-1500" \
--topic "v2 设计评审" \
--html-file "/tmp/brief_body_2026-04-22-1500.html" \
--attendee-emails "email1@163.com,email2@163.com" \
--since "2026-04-15" \
--until "2026-04-22"
返回 JSON,关键字段:
success:是否成功brief_email.to:收件人邮箱列表brief_email.subject:邮件主题brief_email.html:邮件 HTML 正文使用 commit 返回的 brief_email 字段,调用 imap-smtp-email 发送。
收件人:brief_email.to(全体参会人邮箱)
主题:brief_email.subject
正文:brief_email.html(HTML 格式)
| 错误场景 | 处理方式 |
|---|---|
| scan 无结果 | 正常退出,本次 cron 结束 |
| generate_report.py 失败 | 记录错误,跳过本条会议,继续处理下一条 |
| AI 内容生成失败 | 记录错误,跳过本条会议 |
| render_email 失败 | 记录错误,跳过本条会议 |
| commit 写 Gitea 失败 | 记录错误,不发邮件,下次 cron 重试(status 未变,仍为 scheduled) |
| 邮件发送失败 | 记录错误,但 status 已更新为 brief-sent(日志标注 email_failed) |
status == scheduled 且不含 rescheduled_from 的会议brief-sent