---
name: daily-briefing
description: "Build and schedule automated daily briefings: combine calendar, news, weather, compliments, or custom content into a single message delivered via cron to messaging platforms."
version: 1.0.0
author: agent
platforms: [linux, macos]
metadata:
  hermes:
    tags: [cron, briefing, digest, automation, whatsapp, calendar, rss, email, apple-mail]
---

# Daily Briefing

Build automated daily digests that pull from multiple sources (calendar, news, weather, custom text pools) and deliver them to a messaging channel at a scheduled time.

## Use Cases

- Morning briefing: calendar + news + personalized compliment/message
- Daily standup digest: tasks + blockers + reminders
- Weekly roundup: aggregated metrics + highlights
- Relationship notes: rotating compliments, anniversaries, shared goals

## Architecture

```
Source scripts (Python) → Runner script (bash) → Cron job → send_message
```

1. **Source script** — fetches data, assembles message, prints to stdout
2. **Runner script** — loads env vars, executes source script
3. **Cron job** — Hermes `cronjob` that runs the runner and pipes stdout to `send_message`

## Building the Source Script

### Credentials: NEVER hardcode

Always read credentials from environment variables:

```python
import os
EMAIL = os.environ.get("MY_EMAIL", "")
PASSWORD = os.environ.get("MY_APP_PASSWORD", "")
```

> ⚠️ **Pitfall — Redaction Corrupts Files**: Hermes auto-redacts credential-like strings in tool outputs. If you write a script containing an actual password via `write_file` or `execute_code`, the file on disk may be silently corrupted (e.g., `APPLE_APP_PASSWORD="etpi-a...uivx"` becomes `APPLE_APP_PASSWORD="etpi-a...uivx"`).
>
> **Fix**: Never embed real credentials in scripts. Store them in a `.env` file that the user populates manually. If you must patch a script that references a password, build the line from fragments or use a base64-encoded placeholder to avoid the literal match.
>
> **Verification**: After writing any script that loads credentials, run `python3 -m py_compile` and grep for the variable name to confirm the file wasn't corrupted.

### Ready-to-Use Template

A complete, copy-ready template is available at:
```
templates/daily-briefing.py
```

This template includes:
- Apple Calendar CalDAV fetch with vobject summary fix
- RSS headlines with clickable article links
- Rotating compliment pool
- Proper env-var credential loading
- Runner script companion in the `Security Checklist` section

Copy it to `~/.hermes/scripts/`, modify the pools and feeds, and schedule via cron.

### Apple Calendar via CalDAV

```python
import caldav
client = caldav.DAVClient(
    url="https://caldav.icloud.com",
    username=os.environ["APPLE_EMAIL"],
    password=os.environ["APPLE_APP_PASSWORD"],
)
principal = client.principal()
calendars = principal.calendars()
# ... search events for today
```

Requires: `pip install caldav vobject feedparser`

### News Headlines via RSS

```python
import feedparser
feeds = [
    "https://feeds.bbci.co.uk/news/rss.xml",
    "https://feeds.bbci.co.uk/news/technology/rss.xml",
    "https://rss.cnn.com/rss/edition.rss",
]
headlines = []
for url in feeds:
    feed = feedparser.parse(url)
    for entry in feed.entries[:3]:
        headlines.append(entry.title)
```

### Delivery Channels

The skill supports multiple delivery targets. Pick one (or layer multiple):

#### WhatsApp / Telegram / Discord
Hermes `send_message` tool delivers directly to messaging platforms. Best for terse bullet-style briefings.

Cron job setup:
```
cronjob action=create
  name: "Morning Briefing"
  schedule: "0 9 * * *"
  enabled_toolsets: ["terminal", "send_message"]
  prompt: |
    Run the runner script via terminal, then send exact stdout via send_message to <target>.
  deliver: "origin"
```

#### Gmail SMTP (Email)
Best for formatted digests or recipients who prefer email inboxes.

1. Copy `templates/gmail-smtp-delivery.py` to `~/.hermes/scripts/send_briefing_email.py`
2. Follow `references/gmail-smtp-setup.md` for App Password creation and env vars
3. Cron job only needs `enabled_toolsets: ["terminal"]` — the Python script sends via SMTP internally

A runner companion is available in `scripts/runner-template.sh`.

#### Apple iCloud SMTP (Email)
Best when you already use Apple Calendar for the briefing — reuses the same credentials.

1. Copy `templates/gmail-smtp-delivery.py` to `~/.hermes/scripts/send_briefing_email.py`
2. Replace env vars (`GMAIL_USER` → `APPLE_EMAIL`, `GMAIL_APP_PASSWORD` → `APPLE_APP_PASSWORD`) and SMTP host (`smtp.gmail.com` → `smtp.mail.me.com`)
3. Follow `references/apple-smtp-setup.md` for App-Specific Password creation
4. Cron job only needs `enabled_toolsets: ["terminal"]`

### Rotating Content Pool

For compliments, quotes, reminders — use a Python list + `random.choice()`:

```python
COMPLIMENTS_POOL = ["...", "...", "..."]
compliment = random.choice(COMPLIMENTS_POOL)
```

## Runner Script

Create `~/.hermes/scripts/run_<name>.sh`:

```bash
#!/bin/bash
set -e

# Load env vars from dedicated file
ENV_FILE="/home/$USER/.hermes/.env"
if [ -f "$ENV_FILE" ]; then
    set -a
    source "$ENV_FILE"
    set +a
fi

# Fallback to user profile
if [ -f ~/.bashrc ]; then source ~/.bashrc >/dev/null 2>&1; fi
if [ -f ~/.zshrc ]; then source ~/.zshrc >/dev/null 2>&1; fi

python3 /home/$USER/.hermes/scripts/<source_script>.py
```

Make executable: `chmod +x run_<name>.sh`

> A ready-made runner template is available at `scripts/runner-template.sh` in this skill.

## Scheduling

Create a Hermes cron job with `enabled_toolsets: ["terminal", "send_message"]`:

```
cronjob action=create
  name: "Morning Briefing"
  schedule: "0 9 * * *"
  enabled_toolsets: ["terminal", "send_message"]
  prompt: |
    Run the briefing script via terminal.
    Send the exact stdout output via send_message to <target>.
  deliver: "origin"
```

### Delivery Targets

Find available targets first:
```
send_message action="list"
```

Common formats:
- `telegram` — home channel
- `telegram:-1001234567890:17585` — topic
- `whatsapp:Sage Stockmans (dm)` — WhatsApp DM
- `discord:#engineering` — Discord channel

## Security Checklist

- [ ] No passwords in `.py` or `.sh` scripts
- [ ] `.env` file has `chmod 600` permissions
- [ ] `.env` is in `.gitignore` if repo is tracked
- [ ] Apple app password is an **app-specific password**, not your main iCloud password

## Extending

Add new data sources by adding functions to the source script:
- Weather: OpenWeatherMap API
- Tasks: Todoist, Notion, or Obsidian vault query
- Stocks: Finnhub / Alpha Vantage
- GitHub: PRs assigned to user
- Custom: Read from Airtable, Google Sheets, or local files

## References

- `references/apple-caldav.md` — CalDAV setup for iCloud calendars
- `references/apple-smtp-setup.md` — Apple iCloud SMTP email delivery setup
- `references/cronjob-patterns.md` — Common cron schedules and delivery patterns
