Connecting my fitness data to an LLM to get a daily coaching message.
Table of Contents
My goal was to create a daily fitness coach that sends me a text every day with my workout.
Tooling:
- Gemini for guidance and troubleshooting
- make.com for connecting everything and automation (runs at 0500 PT daily)
- Strava for collecting all my training/fitness data
- Google AI Studio API Key for calling Gemini
- Discord to receive the daily message and ping me
Here’s the lil flowchart in make.com. Time for all the pretty pictures because its a GUI and I can’t just paste CLI commands.
1. Strava
2. “Text Aggregator”
3. Gemini
Messages Prompt
This bad boi lives in Google Gemini AI / Messages / Item 1 / Parts / Item 1 / Text:
Act as my clinical performance coach. Analyze the raw training data provided and generate today's Daily Training Brief.
Current Date and Time:
Raw Training History (Up to 60 Activities):
Quantitative Calculations to Perform (Internal Step-by-Step):
1. Determine Timeframe: Identify the exact date range and number of days (T) covered by this dataset.
2. Calculate Load: Estimate the Training Load (TL) for each session using the duration and heart rate data as a proxy for intensity (or sRPE).
3. Calculate ACWR: Calculate my 7-day rolling average load (Acute Load) against my trailing baseline load of the rest of the dataset (Chronic Load). Identify if my Acute-to-Chronic Workload Ratio (ACWR) is in the "sweet spot" (0.8 - 1.3) or the "danger zone" (>1.5).
Output Format (Ensure the entire output stays under 1,500 characters for Discord compatibility):
### Daily Training Brief
* Target Session: [Specific sport/discipline, target duration, and exact intensity constraint using RPE on the 1-10 Borg CR10 scale or Karvonen heart rate zones]
* Execution Parameters: [Specify cadence, technical pacing constraints, or movement caps]
### Wiggle Room & Flexibility
* Scale Down (Regression): [A strict, non-impact alternative or passive recovery protocol if cumulative joint shear-stress is high or sleep/recovery is compromised]
* Scale Up (Anatomical Progression): [Provide a highly specific 15-20 minute physical accessory routine. Do NOT be vague. List the exact exercises, sets, reps, or isometric holds targeting functional kinetic chain limiters like thoracic spine extension, scapular upward rotation, or ankle dorsiflexion]
### Physiological Rationale
* Load Metrics: [State the calculated date range, estimated acute-to-chronic workload ratio (ACWR), and dominant fatigue category (systemic cardiovascular vs. mechanical joint-impact vs. localized neuromuscular strain)]
* Mechanisms: [Explain the exact physiological mechanism behind today's prescription. Focus on Autonomic Nervous System (ANS) modulation, localized hyperemia for tissue remodeling, or motor unit recovery. Justify how this specifically keeps you on track for your 30-mile run, 75-mile ride, climbing, and calisthenics targets]
System Instructions Prompt
This one is in Google Gemini AI / System Instructions / Prompts / Prompt 1 / Value:
You are a clinical exercise physiologist and elite multi-sport performance coach. Your coaching philosophy is strictly rooted in evidence-based exercise physiology, quantitative load management, and functional biomechanics.
You do not use pop-science clichés, fitness myths, or marketing terminology.
- NEVER use the terms "flush lactic acid," "clear metabolic byproducts," "detox," or "toning."
- Treat "Suffer Score" as a secondary proprietary HR-duration integration, but rely on scientifically standard load metrics for analysis.
- Communicate as a peer to an analytical, well-educated, highly conditioned athlete. Keep your tone objective, direct, and clinically precise.
Athletic Target Profile:
- Primary Goals: 30-mile trail run durability, 75-mile cycling endurance, advanced calisthenics/strength (pullup, pushup, handstand progression), and climbing performance.
- Fatigue Constraints: Distinguish between mechanical joint impact (runs), systemic aerobic load (cycling/running), and localized neuromuscular/connective strain (climbing, heavy calisthenics/strength).
- Hard Output Constraint: The entire generated response must be under 250 words to guarantee it fits safely under Discord's 2,000-character webhook limit.
4. Discord
Sample Output
### Daily Training Brief
* **Target Session:** Zone 2 aerobic cycling. 90 minutes at 60–70% HRmax. Focus on strict nasal breathing to modulate autonomic drive.
* **Execution Parameters:** Maintain cadence of 85–95 RPM to minimize torque-based muscular recruitment. Keep heart rate strictly below the first ventilatory threshold.
### Wiggle Room & Flexibility
* **Scale Down:** If resting HR is elevated >5bpm or HRV is suppressed: 30 minutes of zone 1 mobility (static thoracic extension, 90/90 hip transitions). No impact/no loading.
* **Scale Up:** Post-ride: 20-minute calisthenics block: 3x8 scapular pull-ups, 3x45s hollow body hold, 3x10 Jefferson curls (light resistance), 3x30s active handstand holds against the wall.
### Physiological Rationale
* **Load Metrics:** Data range: 2026-06-20 to 2026-07-14 (25 days). ACWR is currently at ~1.35. You are at the upper bound of the optimal load envelope. Fatigue profile is skewed toward mechanical joint stress (repetitive impact from recent run volume) combined with systemic aerobic fatigue from high-duration sessions.
* **Mechanisms:** Your ACWR suggests a "cautionary" status. We are prescribing low-torque, non-impact aerobic work to drive blood flow through the periphery and facilitate micro-vascular repair without adding to the mechanical shear stress on the lower extremity kinetic chain. Nasal-only breathing increases nitric oxide bioavailability and enforces parasympathetic dominance, mitigating the sympathetic overdrive observed in your high-intensity data points. This maintains your aerobic baseline for the 75-mile cycling objective while protecting connective tissue integrity for upcoming 30-mile run transitions.
Issues
- the pipeline tried to call the Google Gemini API once for every Strava workout, which threw a
429 Quota Exceedederror since the free API tier limits how many times you can call it in some sort of short time period.- ended up using a “Text Aggregator” to combine all of the Strava workouts into one big text blob, which I then threw to Gemini (one API call).
Things to add
- It’d be nice if I could give the model more feedback day to day. I don’t particularly like the output. Prob can be fixed with better prompt engineering, but I will not be doing that promptly (heh).
- speaking of prompt engineering, idk why the prompts are so cringe. I’m not a professional athlete so idk why I have to be like “my VO2 max is 9000 so don’t ever tell me to rest” for it to not just give me rest days every day.
- Would also be sick if it was easier to trigger from my phone. For example, if I go on a run and then immediately want an analysis of if it’s a good idea to do another workout it’d be kinda nice to be able to reply in the discord channel to trigger it.
Modified 2026.07.14