Skip to content

coreywininger/DailyBriefing

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DailyBriefing

License: MIT Python 3.11+

An automated morning briefing that emails me weather, calendar, and tasks every weekday at 7 AM Eastern. Runs on GitHub Actions — no server, no local machine dependency.

Full write-up: Claude + GitHub Actions: an integration playbook on coreymark.com.

v2 note: This repo was redesigned in May 2026 to remove all Google OAuth dependencies. The blog post above covers the original OAuth-based approach; a follow-up post documents why the change was made and what replaced it.

DailyBriefing sample email — dark-themed cards showing weather, calendar, and tasks

What it does

A single HTML email each weekday morning covering:

  • Current weather + forecast (OpenWeatherMap, Bedford IN)
  • Personal + family Google Calendar events for the day (via iCal secret URLs — no OAuth)
  • Active task list (pulled from a private GitHub Gist)
  • An AI-generated daily greeting (Claude Haiku; template fallback)

Architecture

GitHub Actions (weekday cron, 7 AM ET)
        |
        └── briefing.py
                ├── OpenWeatherMap API    → weather
                ├── Google Calendar iCal  → events (personal + family, no OAuth)
                ├── GitHub Gist API       → TASKS.md
                ├── Anthropic API         → daily greeting
                └── Gmail SMTP            → HTML email (App Password, no OAuth)

No database, no server, no container. One Python script, one cron workflow, all secrets in GitHub Actions. No OAuth tokens — all credentials are static keys or App Passwords that don't expire on a schedule.

Tech stack

Component Tech
Orchestration GitHub Actions
Language Python 3.11+
Weather OpenWeatherMap
Calendar Google Calendar iCal secret URLs + icalendar / recurring-ical-events
Tasks GitHub Gist
Email delivery Gmail SMTP with App Password
Greeting Anthropic API (Claude Haiku)

Repo layout

briefing.py                # main script (data fetch + HTML render + SMTP send)
demo_data.py               # synthetic payloads for DEMO_MODE (no credentials)
.github/workflows/
  daily-briefing.yml       # weekday 7 AM ET cron trigger with DST gate
requirements.txt           # Python dependencies
docs/
  sample-briefing.png      # screenshot embedded above (rendered via DEMO_MODE)
LICENSE
README.md

Required GitHub Secrets

Set these under Settings → Secrets and variables → Actions:

Secret Purpose
OPENWEATHERMAP_API_KEY Weather API key
GMAIL_ADDRESS Your Gmail address (sender and recipient)
GMAIL_APP_PASSWORD Gmail App Password (Google Account → Security → 2-Step Verification → App passwords)
PERSONAL_CALENDAR_ICAL_URL Google Calendar iCal secret URL for your personal calendar
FAMILY_CALENDAR_ICAL_URL Google Calendar iCal secret URL for your family/shared calendar
GIST_ID ID of the private Gist containing your TASKS.md
GIST_TOKEN GitHub PAT with gist scope (set to no-expiry)
ANTHROPIC_API_KEY Claude API key (optional — falls back to template greeting if absent)

Setup

  1. Fork or clone this repo.
  2. Gmail App Password — go to myaccount.google.com → Security → 2-Step Verification → App passwords. Create one named "DailyBriefing." This is your GMAIL_APP_PASSWORD secret.
  3. Calendar iCal URLs — in Google Calendar, open Settings for each calendar and scroll to "Secret address in iCal format." Copy both URLs. These are your PERSONAL_CALENDAR_ICAL_URL and FAMILY_CALENDAR_ICAL_URL secrets. These URLs never expire unless you manually reset them.
  4. OpenWeatherMap — create a free account at openweathermap.org and grab an API key.
  5. GitHub Gist — create a private Gist with a TASKS.md file. Copy the Gist ID from the URL. Create a GitHub PAT with gist scope (no expiry) for GIST_TOKEN.
  6. Anthropic (optional) — add a Claude API key for the AI greeting. If absent, a deterministic template runs instead.
  7. Add all secrets to this repo under Settings → Secrets → Actions.
  8. Enable the workflow under the Actions tab. Trigger it manually once with workflow_dispatch to verify end-to-end.

Demo mode

To render a sample briefing with synthetic data — no API calls, no credentials, no email send:

DAILYBRIEFING_DEMO=1 python briefing.py

Writes the rendered HTML to docs/sample-briefing.html. Useful for iterating on the template without needing live data.

Notes

  • Cron runs in UTC. The workflow uses two cron entries with a time-gate step to hit 7 AM Eastern regardless of DST.
  • iCal secret URLs are stable indefinitely — Google only resets them if you manually click "Reset" in Calendar settings.
  • Gmail App Passwords remain valid as long as 2-Step Verification stays enabled on your account.
  • All APIs used are free at the volumes this project generates.

License

MIT — see LICENSE.

Author

Built by Corey Wininger. Sharing as a reference pattern; not accepting contributions.

About

Automated weekday morning briefing email — weather, calendar, tasks, and inbox highlights via GitHub Actions.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages