{"slug": "free-daily-ai-brief-from-your-garmin-data-gemini-and-github-actions", "title": "Free daily AI brief from your Garmin data (Gemini and GitHub Actions)", "summary": "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.", "body_md": "**Free daily AI brief on your Garmin data — full-history stats, Gemini insight, push to your phone. $0 to run.**\n\nFully 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.\n\n*Example notification layout — your numbers and wording change daily.*\n\n```\nWATCH\n• Stress 34 vs 30d avg 23 — worsening\n• Sleep 6.15h — under 7h target\n\nWINS\n• Intensity 63 min — all-time high\n• Resting HR improving, 2-day streak near ATL\n\nTODAY\nIn bed 30 minutes earlier tonight.\n\n—\nPoor sleep raises cortisol and daily stress.\n```\n\n**Cost:** $0 (Garmin via `garminconnect`\n\n, Gemini free tier, GitHub Actions, ntfy/Telegram/email).\n\n```\npython3.12 -m venv .venv\nsource .venv/bin/activate\npip install -r requirements.txt\npython scripts/mint_token.py\n```\n\nUse your Garmin email, password, and MFA code. Tokens are saved to `~/.garminconnect`\n\n(valid ~1 year).\n\n```\nBACKFILL_DAYS=180 python -m src.backfill\n```\n\nCreates `garmin.db`\n\n. Commit it to your repo after backfill completes (re-run backfill after schema changes to refresh columns).\n\nPackage tokens for CI:\n\n```\nbash scripts/pack_tokens.sh\n```\n\nCopy the **single long line** of output into repository secret `GARMIN_TOKENS_B64`\n\n(no quotes, no spaces, no line breaks in the secret value).\n\nIf Actions fails with `base64: invalid input`\n\n, the secret was pasted wrong — re-run `pack_tokens.sh`\n\nand replace the secret entirely.\n\nManual alternative:\n\n```\ntar -cf tokens.tar -C ~/.garminconnect .\nbase64 < tokens.tar | tr -d '\\n\\r '\n# paste that one line into GARMIN_TOKENS_B64\nrm -f tokens.tar\n```\n\n| Secret | Purpose |\n|---|---|\n`GARMIN_TOKENS_B64` |\nbase64 tar of `~/.garminconnect` |\n`GEMINI_API_KEY` |\n|\n\n`NOTIFIER`\n\n`ntfy`\n\n(default), `telegram`\n\n, or `email`\n\n`NTFY_TOPIC`\n\n`TELEGRAM_BOT_TOKEN`\n\n/ `TELEGRAM_CHAT_ID`\n\n`EMAIL_USER`\n\n/ `EMAIL_APP_PASSWORD`\n\n/ `EMAIL_TO`\n\n**ntfy (default):** Install the [ntfy app](https://ntfy.sh), subscribe to a long random topic, set `NTFY_TOPIC`\n\n.\n\n**Telegram:** Create a bot via @BotFather, get your chat id.\n\n**Email:** Gmail app password (not account password).\n\n```\ncp .env.example .env   # fill in secrets\npython -m src.main\n```\n\nCreate a GitHub repo, commit everything including `garmin.db`\n\n, add secrets, run **workflow_dispatch** on `garmin-daily`\n\nonce to verify CI. The repo can be **public** if you accept that `garmin.db`\n\nexposes daily health numbers (see below).\n\nOnly **scalar daily wellness metrics** are stored. There is **no raw JSON**, no GPS, no activity routes, no maps, and no activity list/workout details.\n\n| Stored | Not stored |\n|---|---|\n| Steps, resting HR, sleep (duration/score/stages), stress, Body Battery high/low, HRV, training readiness, intensity minutes, active kcal | Location, lat/long, track polyline |\nSpO2, VO2 max, Garmin fitness age, weight (g), body fat % |\nActivity names, routes, timestamps per lap |\nDate (`YYYY-MM-DD` ) only |\nFull API responses, heart-rate streams |\n\n**Fitness age** is Garmin’s estimated fitness age (a single number), not your birthdate or home address.\n\n`python -m src.main`\n\n— pull recent days → digest → Gemini brief → notification.\n\nGitHub Actions runs at **13:00 UTC** (~8am US Eastern), commits updated `garmin.db`\n\n, and pushes.\n\n**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. Committing`garmin.db`\n\neach run prevents this.**Token expiry:** Re-run`scripts/mint_token.py`\n\nwhen 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 see`limit: 0`\n\n429 errors, link a billing account on the GCP project tied to your API key (still $0 for one call/day within free tier).\n\n```\nsrc/\n  config.py       # env, metrics registry, goals\n  db.py           # SQLite\n  garmin_client.py\n  pull.py / backfill.py\n  features.py     # statistics digest\n  insight.py      # Gemini brief\n  notify.py\n  main.py\nscripts/mint_token.py\n.github/workflows/daily.yml\ndocs/sample-notification.png\n```\n\n", "url": "https://wpnews.pro/news/free-daily-ai-brief-from-your-garmin-data-gemini-and-github-actions", "canonical_source": "https://github.com/deep0410/garmin-ai-notifier", "published_at": "2026-06-03 02:12:09+00:00", "updated_at": "2026-06-03 02:48:08.410015+00:00", "lang": "en", "topics": ["ai-tools", "ai-products", "artificial-intelligence", "generative-ai", "machine-learning"], "entities": ["Garmin", "Gemini", "GitHub Actions", "SQLite", "ntfy", "Telegram"], "alternates": {"html": "https://wpnews.pro/news/free-daily-ai-brief-from-your-garmin-data-gemini-and-github-actions", "markdown": "https://wpnews.pro/news/free-daily-ai-brief-from-your-garmin-data-gemini-and-github-actions.md", "text": "https://wpnews.pro/news/free-daily-ai-brief-from-your-garmin-data-gemini-and-github-actions.txt", "jsonld": "https://wpnews.pro/news/free-daily-ai-brief-from-your-garmin-data-gemini-and-github-actions.jsonld"}}