cd /news/ai-tools/free-daily-ai-brief-from-your-garmin… · home topics ai-tools article
[ARTICLE · art-19823] src=github.com pub= topic=ai-tools verified=true sentiment=↑ positive

Free daily AI brief from your Garmin data (Gemini and GitHub Actions)

A free, fully automated pipeline now pulls daily health data from Garmin Connect into a SQLite database, computes percentiles and trends across a user's entire history, and delivers a short coached brief via ntfy, Telegram, or email. The system runs on GitHub Actions with no server to maintain, using the free tiers of Garmin's API, Google's Gemini, and GitHub to keep costs at zero. Users can set up the pipeline in minutes by cloning a public repository, running a backfill script, and configuring notification secrets.

read3 min publishedJun 3, 2026

Free daily AI brief on your Garmin data — full-history stats, Gemini insight, push to your phone. $0 to run.

Fully automated pipeline: pull Garmin Connect into SQLite, compute percentiles and trends over your whole history, and deliver a short coached brief via ntfy, Telegram, or email. Runs on GitHub Actions; no server to maintain.

Example notification layout — your numbers and wording change daily.

WATCH
• Stress 34 vs 30d avg 23 — worsening
• Sleep 6.15h — under 7h target

WINS
• Intensity 63 min — all-time high
• Resting HR improving, 2-day streak near ATL

TODAY
In bed 30 minutes earlier tonight.

—
Poor sleep raises cortisol and daily stress.

Cost: $0 (Garmin via garminconnect

, Gemini free tier, GitHub Actions, ntfy/Telegram/email).

python3.12 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python scripts/mint_token.py

Use your Garmin email, password, and MFA code. Tokens are saved to ~/.garminconnect

(valid ~1 year).

BACKFILL_DAYS=180 python -m src.backfill

Creates garmin.db

. Commit it to your repo after backfill completes (re-run backfill after schema changes to refresh columns).

Package tokens for CI:

bash scripts/pack_tokens.sh

Copy the single long line of output into repository secret GARMIN_TOKENS_B64

(no quotes, no spaces, no line breaks in the secret value).

If Actions fails with base64: invalid input

, the secret was pasted wrong — re-run pack_tokens.sh

and replace the secret entirely.

Manual alternative:

tar -cf tokens.tar -C ~/.garminconnect .
base64 < tokens.tar | tr -d '\n\r '
rm -f tokens.tar
Secret Purpose
GARMIN_TOKENS_B64
base64 tar of ~/.garminconnect
GEMINI_API_KEY

NOTIFIER

ntfy

(default), telegram

, or email

NTFY_TOPIC

TELEGRAM_BOT_TOKEN

/ TELEGRAM_CHAT_ID

EMAIL_USER

/ EMAIL_APP_PASSWORD

/ EMAIL_TO

ntfy (default): Install the ntfy app, subscribe to a long random topic, set NTFY_TOPIC

.

Telegram: Create a bot via @BotFather, get your chat id.

Email: Gmail app password (not account password).

cp .env.example .env   # fill in secrets
python -m src.main

Create a GitHub repo, commit everything including garmin.db

, add secrets, run workflow_dispatch on garmin-daily

once to verify CI. The repo can be public if you accept that garmin.db

exposes daily health numbers (see below).

Only scalar daily wellness metrics are stored. There is no raw JSON, no GPS, no activity routes, no maps, and no activity list/workout details.

Stored Not stored
Steps, resting HR, sleep (duration/score/stages), stress, Body Battery high/low, HRV, training readiness, intensity minutes, active kcal Location, lat/long, track polyline
SpO2, VO2 max, Garmin fitness age, weight (g), body fat %
Activity names, routes, timestamps per lap
Date (YYYY-MM-DD ) only
Full API responses, heart-rate streams

Fitness age is Garmin’s estimated fitness age (a single number), not your birthdate or home address.

python -m src.main

— pull recent days → digest → Gemini brief → notification.

GitHub Actions runs at 13:00 UTC (~8am US Eastern), commits updated garmin.db

, and pushes.

Cron drift: Scheduled runs may start a few minutes late; fine for a daily brief.Workflow auto-disable: Repos with no commits for 60 days disable scheduled workflows. Committinggarmin.db

each run prevents this.Token expiry: Re-runscripts/mint_token.py

when Actions fail auth (~yearly).Gemini privacy: Free tier may use inputs for training. The digest contains only aggregated numbers — no names or emails.Rate limits: One Gemini call/day; flash → flash-lite fallback on 429.Thin data: Metrics with fewer than 14 days skip percentile/record claims.NULL: Missing Garmin fields are stored as NULL, never zero.Gemini quota 0: If you seelimit: 0

429 errors, link a billing account on the GCP project tied to your API key (still $0 for one call/day within free tier).

src/
  config.py       # env, metrics registry, goals
  db.py           # SQLite
  garmin_client.py
  pull.py / backfill.py
  features.py     # statistics digest
  insight.py      # Gemini brief
  notify.py
  main.py
scripts/mint_token.py
.github/workflows/daily.yml
docs/sample-notification.png
── more in #ai-tools 4 stories · sorted by recency
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/free-daily-ai-brief-…] indexed:0 read:3min 2026-06-03 ·