ClawSkills logoClawSkills

Daily Briefing

生成包含天气、日历、提醒、生日和重要电子邮件的温馨、紧凑的每日简报,供 cron 或聊天发送使用。

介绍

# daily-briefing

生成一份简洁、温馨的每日消息,适合通过 cron(标准输出/聊天回复)进行投递。即使在上下文极少的情况下也能始终成功执行。

---

## 技能类型:系统技能(编排器模式)

此技能使用 **系统技能模式** 在 macOS 上执行。代理必须:

1. **切勿直接运行原始 CLI 命令**(`curl` 获取天气除外)。 2. **始终调用运行器脚本** 来收集数据。 3. 在脚本完成后**从 JSON 中读取收集的数据**。 4. 使用代理自身的能力**生成简报文本**。

**快速参考:** ```bash # Invoke data gatherer (waits for completion) "{baseDir}/skills/daily-briefing/bin/run_daily_briefing.sh"

# Read output cat /tmp/daily_briefing_data.json ```

---

## 输出约定(严格)

**关键:** 输出**仅**包含简报文本。无前言,无解释,无“Done”,无文件路径,无工具输出,简报周围不使用 markdown 代码块。

### 第 1 行格式(必需)

第 1 行**必须精确地**以适合时间的问候语开头:

``` Good {time_of_day} - Today is {Weekday}, {Month} {D}, {YYYY}. {Skies sentence}. ```

- 使用**完整的月份名称**(例如 "February",而非 "Feb")。 - 如果今天是用户的生日(通过联系人中的姓名匹配):将问候语替换为: ``` 🎉 Happy Birthday! Today is {Weekday}, {Month} {D}, {YYYY}. {Skies sentence}. ```

### 问候语选择(本地时间)

| 时间范围 | 问候语 | |------------|----------| | 05:00–11:59 | Good morning | | 12:00–16:59 | Good afternoon | | 17:00–21:59 | Good evening | | 22:00–04:59 | Good night | | 未知 | Good morning (默认) |

### 天气句子规则

**如果天气数据可用:** ``` {Conditions} skies, around {TEMP}°{time_clause}{low_clause}{precip_clause}. ```

- 如果可靠,使用**最高气温** → 时间从句:" this afternoon" - 否则使用**当前气温** → 时间从句:" right now" - 如果存在最低气温:附加 `, with a low around {LOW}°` - 如果降水概率 ≥30%:附加 `, and a {CHANCE}% chance of {rain/snow/precipitation}`

**如果天气数据不可用:** 使用确切的回退文本: ``` I can't access weather right now. ```

### 布局规则

``` {Line 1: Greeting with skies sentence}

{Birthdays section - only if any today or upcoming}

{Calendar events section - only if any}

{Reminders section - only if any}

{Important emails section - only if enabled and any}

{Anchors - only if real priorities from context}

{Closing line - always required} ```

- 始终在**第 1 行之后包含一个空行**。 - 如果存在,每个部分之间用一个空行分隔。 - 根据已启用的集成,目标为 **~5–15 行**。

---

## 氛围与基调

- **一天中温柔的礼物**:温暖、平静、富有同情心、充满静默的希望。 - **无责备、无紧迫感、无生产力压力。** - **Telegram 友好**:短行、宽间距、易于略读。

---

## 系统技能执行

### 步骤 1:检查模式(交互式 vs Cron)

**如果是交互式且缺少关键信息(位置/时区/单位):** - 在生成简报之前简要提示缺失信息。 - 提供集成的开关选项。 - 提及重要邮件功能:解释它使用 AI 驱动的语义分析来提取可操作的邮件(交易、发货、安全警报等),并可通过配置中的 `emails.enabled` 启用;注意 iCloud Mail 需要专用应用密码 (`emails.icloudPassword`)。

**如果是非交互式(cron/自动化):** - 不要提问(cron 安全)。使用默认值。 - 不要创建/修改任何文件。 - 不要生成后台任务/子代理。 - 如果位置不可用,**省略天气**。

### 步骤 2:调用数据收集器

```bash "{baseDir}/skills/daily-briefing/bin/run_daily_briefing.sh" ```

- 运行器脚本执行 `scripts/daily_briefing_orchestrator.sh`。 - Terminal.app(或调用进程)已获得 TCC 权限。

### 步骤 3:读取收集的数据

应用程序完成后,读取:

``` /tmp/daily_briefing_data.json ```

JSON 结构: ```json { "generated_at": "ISO timestamp", "system": { "timezone": "America/New_York", "local_time": "2024-02-03T08:30:00", "hour": 8 }, "config": { "location": "New York, NY", "units": "C", "birthdays_enabled": true, "birthdays_lookahead": 14, "calendar_google_enabled": true, "calendar_icloud_enabled": true, "calendar_lookahead": 0, "reminders_enabled": true, "reminders_due_filter": "today", "reminders_include_past_due": true, "emails_enabled": false, "emails_limit": 10, "emails_sort_newest": true, "emails_starred_first": true, "emails_unread_only": true }, "birthdays": { "available": true, "user_birthday_today": false, "data": [ {"name": "Jane Doe", "date": "2024-02-03", "days_until": 0}, {"name": "John Smith", "date": "2024-02-05", "days_until": 2} ] }, "calendar": { "available": true, "data": [ {"title": "Team standup", "start": "09:00", "end": "09:30", "all_day": false, "date": "2024-02-03", "source": "google"}, {"title": "Doctor appointment", "start": null, "end": null, "all_day": true, "date": "2024-02-03", "source": "icloud"} ] }, "reminders": { "available": true, "data": [ {"title": "Pick up prescription", "due": "2024-02-03"} ] }, "emails": { "available": true, "data": [ {"id": "abc123", "from": "Amazon", "from_email": "[email protected]", "subject": "Your order has shipped", "preview": "Your package is on its way...", "starred": false, "unread": true, "date": "2024-02-03T07:30:00Z", "source": "gmail"}, {"id": "def456", "from": "Chase", "from_email": "[email protected]", "subject": "Payment received", "preview": "We received your payment of...", "starred": true, "unread": true, "date": "2024-02-03T06:15:00Z", "source": "icloud"} ] }, "contacts": { "available": true, "data": [ {"name": "Jane Doe", "email": "[email protected]"}, {"name": "John Smith", "email": "[email protected]"} ] } } ```

### 步骤 4:获取天气(代理任务)

代理必须使用 `curl` 直接获取天气(而非通过编排器):

```bash curl -fsSL --max-time 12 "https://wttr.in/{ENCODED_LOCATION}?format=j1" ```

- **位置:** 使用收集数据中的 `config.location`;如果为空/null,则天气不可用。 - **重试:** 失败时重试一次。 - **如果仍然失败或不可用:** 天气不可用;使用回退句子。

**从 JSON 响应中解析:** - 条件:`current_condition[0].weatherDesc[0].value` - 当前气温 (C):`current_condition[0].temp_C` - 当前气温 (F):`current_condition[0].temp_F` - 最高气温 (C):`weather[0].maxtempC` - 最高气温 (F):`weather[0].maxtempF` - 最低气温 (C):`weather[0].mintempC` - 最低气温 (F):`weather[0].mintempF` - 降水概率:`weather[0].hourly[*].chanceofrain` 的最大值(作为整数)

**单位:** 使用 `config.units`("C" 或 "F")。如果未知,默认为摄氏度。

**关键:** 不要输出原始 curl/工具输出。不要使用 wttr.in 的单行格式。

### 步骤 5:分类重要邮件(代理任务)

**仅当 `config.emails_enabled` 为 true 且 `emails.available` 为 true 时。**

对于 `emails.data` 中的每封邮件,使用代理自身的语义分析来确定重要性。

**重要邮件标准(任一匹配即符合):** - 来自收集的联系人列表中的联系人 - 订单发货通知 - 购买收据或交易确认 - 收入/支出交易提醒 - 退款相关消息 - 客户服务互动 - 即将到来的订阅续费通知 - 即将到来的付款预警通知 - 技术类通讯 - 职位申请更新 - 来自招聘人员的消息(排除类 WITCH 外包公司) - 银行提醒 - 日历邀请 - 账户安全邮件(例如“您的账户已被锁定”) - 共享项目(例如 Google Drive 共享) - 心愿单相关提醒 - 已加星标/已标记的邮件(积极信号,非唯一决定因素) - 任何其他具有上下文重要性的邮件

**排除项:** 即使符合其他标准,以下也**绝不**重要: - 促销/营销邮件 - LinkedIn 求职提醒邮件(LinkedIn 消息通知可以) - 未经请求的招聘/职位发布邮件和批量招聘通知(例如,主题或正文中包含“hire”、“hiring”、“job”、“position”、“onsite”、“fulltime”、“recruiter”、“application”等关键词,或明显的批量外联),除非发件人在用户的联系人中或邮件已加星标/易于识别为个人相关。 - 产品公告/产品更新邮件和供应商/平台通知(例如“[Product Update]”、发布公告、自动启用通知),除非发件人在用户的联系人中或邮件被明确加星标。 - 供应商通讯、社区公告和一般技术邮件列表帖子(例如博客文章、发布说明、产品预览、摘要),除非明显属于私人性质或来自联系人。

**失败行为:** 如果语义分析失败,静默**省略整个邮件部分**。

**应用过滤和排序:** 1. 如果 `emails_unread_only` 为 true,则按此过滤 2. 如果 `emails_starred_first` 为 true,则已加星标邮件优先 3. 按 `emails_sort_newest` 规定的日期排序 4. 限制为 `emails_limit`

### 步骤 6:生成简报

使用所有收集和处理的数据,按照输出约定撰写简报文本。

**部分格式:**

**生日:** ``` 🎂 **Birthdays:** • Today: Name • Feb 5: Name ``` - 按日期分组显示多个 - 今天的条目在最前 - 最多 5 个即将到来的(不含今天)

**日历事件:** ``` 📅 **Today's schedule:** • All-day: Event title • 9:00 AM: Event title ``` - 单日:"Today's schedule" - 多日:"Schedule",带有 "Today/Tomorrow/{Month} {D}" 标签 - 全天事件在前,然后按时序排列 - 每天最多 3 个事件

**提醒事项:** ``` ✅ **Reminders:** • Pick up prescription ``` - 仅显示到期的提醒 - 最多 3 个提醒

**重要邮件:** ``` 📧 **Emails needing attention:** • Amazon: Your order has shipped • Chase: Payment received ``` - 格式:`• Sender: Subject`(如需则截断)

**核心关注点:** - 仅当您可以**自信地从用户提供的上下文中推断出 1–3 个真实优先级**时。 - 普通项目符号,无标题。 - 如果不真实/不确定,**完全省略**(不要虚构)。

**结束语:** - 必需。使用收集的 JSON 数据中的 `quote` 字段。 - 编排器每次运行都会提供一条随机的励志名言。

### 步骤 7:输出简报

返回**仅**简报文本。无其他内容。

---

## 配置

配置从 `~/.openclaw/openclaw.json` 的路径 `skills.entries.daily-briefing.config` 读取:

```json { "skills": { "entries": { "daily-briefing": { "config": { "location": "New York, NY", "timezone": "America/New_York", "units": "C", "birthdays": { "enabled": true, "lookahead": 14, "sources": ["contacts", "google"] }, "calendar": { "enabled": true, "lookahead": 0, "sources": ["google", "icloud"] }, "reminders": { "enabled": true }, "emails": { "enabled": false, "icloudPassword": "", "limit": 10, "sortNewest": true, "starredFirst": true, "unreadOnly": true } } } } } } ```

### 配置选项

| 选项 | 类型 | 默认值 | 描述 | |--------|------|---------|-------------| | `location` | string | "" | 天气位置(例如 "New York, NY") | | `timezone` | string | system | 时区(例如 "America/New_York") | | `units` | string | "C" | 温度单位:"C" 或 "F" | | `birthdays.enabled` | bool | true | 启用生日跟踪 | | `birthdays.lookahead` | int | 14 | 显示即将到来的生日的天数 | | `birthdays.sources` | array | ["contacts"] | 来源:"contacts" (iCloud), "google" | | `calendar.enabled` | bool | true | 启用日历事件 | | `calendar.lookahead` | int | 0 | 向前展望的天数(0 = 仅今天) | | `calendar.sources` | array | ["google", "icloud"] | 日历来源 | | `reminders.enabled` | bool | true | 启用 Apple 提醒事项 | | `reminders.dueFilter` | string | "today" | 到期日期过滤器:"today"、"week" 或 "all" | | `reminders.includePastDue` | bool | true | 包含过期/逾期提醒 | | `emails.enabled` | bool | false | 启用重要邮件功能 | | `emails.icloudPassword` | string | "" | iCloud 邮件专用应用密码 | | `emails.limit` | int | 10 | 显示的最大邮件数 | | `emails.sortNewest` | bool | true | 最新的优先排序 | | `emails.starredFirst` | bool | true | 优先显示已加星标邮件 | | `emails.unreadOnly` | bool | true | 仅显示未读邮件 |

---

## 默认值

- **时区:** 用户的本地时区;如果未知,则回退到 **UTC**。 - **位置:** 如果存在则为用户的位置;如果在 cron 模式下不可用,**省略天气**。 - **单位:** 如果已知则为用户的首选单位;否则为 **摄氏度**。

---

## 依赖项

**必需:** - `curl` — 用于获取天气 - `bash` — 用于编排器脚本

**可选:** - `gog` — `brew install steipete/tap/gogcli` (Google Calendar, Gmail, Contacts) - `icalpal` — `brew install ajrosen/tap/icalpal` (iCloud Calendar) - `himalaya` — `brew install himalaya` (iCloud Mail via IMAP)

---

## 文件结构

``` daily-briefing/ ├── SKILL.md ├── README.md ├── install.sh ├── scripts/ │ └── daily_briefing_orchestrator.sh └── bin/ └── run_daily_briefing.sh (created by install.sh) ```

---

## 示例输出

``` Good morning - Today is Saturday, February 3, 2024. Partly cloudy skies, around 45°F this afternoon, with a low around 32°F.

🎂 **Birthdays:** • Today: Jane Doe • Feb 5: John Smith

📅 **Today's schedule:** • All-day: Doctor appointment • 9:00 AM: Team standup

✅ **Reminders:** • Pick up prescription

📧 **Emails needing attention:** • Amazon: Your order has shipped • Chase: Payment received

Take things one step at a time today—you've got this. ```

---

## 清理

```bash "{baseDir}/skills/daily-briefing/bin/run_daily_briefing.sh" --cleanup ```

更多产品