GeminiLife adminHealthAI score · PendingAI-assisted edit · no obvious prompt-injection riskn8n.io

Build an n8n Triathlon AI Coach: Auto-Analyze Strava Data and Send Training Insights

Strava activity trigger → data flattening → Gemini AI analysis → structured output → HTML email / WhatsApp delivery

Some experienceStepsWorkflowPromptTip
Who
Athletes or coaches already tracking swims, rides, and runs on Strava who want automated AI training feedback in n8n
You get
After each Strava activity update, receive an HTML email with personalized training advice and motivation; optional WhatsApp summary
You need
n8n · strava · gmail · whatsapp

Constraints

Prerequisites: accessible n8n instance; Strava developer account with OAuth2 credentials; Google Gemini (PaLM) API credentials; Gmail OAuth2 or SMTP credentials; optional WhatsApp Business Cloud credentials. The flow is triggered by a Strava activity update webhook, preprocesses and flattens data, sends it to a Gemini AI Agent for analysis, then delivers results via email or WhatsApp. This site has not tested the flow; verify credentials and webhook reachability in a test environment before relying on it.

What they did

Author Amjid Ali published a workflow template in the n8n official template library. The template captures user activity updates via Strava Trigger, preprocesses and flattens data through Code and Combine Everything nodes, analyzes the activity with a Google Gemini Chat Model (models/gemini-2.0-flash-exp) powering a conversationalAgent named Fitness Coach, then formats results through Structure Output and Conver to HTML nodes, and finally delivers an HTML email via Send Email (SMTP) or Gmail, with an optional WhatsApp Business Cloud summary.

How it went

The source reports that this workflow can provide personalized training advice and motivational feedback for triathletes across swimming, cycling, and running (author_report). The template has 14,381 views on n8n.io. This site has not executed or verified the flow; actual email deliverability and AI recommendation accuracy are unconfirmed.

Worth knowing

1. Credential barrier: requires Strava OAuth2, Google Gemini (PaLM) API, SMTP/Gmail OAuth2, and optional WhatsApp Business Cloud credentials—five credential types that can be complex for individual users. 2. Inconsistent node naming: the template contains 'Conver to HTML' (misspelled, missing t) and multiple Sticky Note nodes; pay attention when rebuilding. 3. WhatsApp node parameters empty: workflow.json shows WhatsApp Business Cloud additionalFields as empty; the source does not provide message template or recipient configuration, so you must fill these in. 4. Code node coupling: Structure Output assumes AI output uses **bold**, * bullet, and number. markdown conventions; if you change the Fitness Coach prompt output format, update the parsing regex accordingly. 5. Privacy note: Strava activity data includes location and heart-rate information; run this in a self-hosted n8n instance or trusted cloud environment to avoid routing sensitive data through third-party hosting.

n8n workflow template

Structure checked · Not run-tested

Use “Import from File” in n8n, or copy the JSON and paste it into the editor. Connect your own accounts, then try test data. The template is inactive by default.

Setup and test checklist

Credentials to connect

  • stravaTrigger node: connect Strava OAuth2 credentials.
  • lmChatGoogleGemini node: connect Google OAuth2 credentials as required.
  • gmail node: connect Gmail OAuth2 credentials.

Configuration to replace

  • Source template is n8n public workflow #2790 (~15 nodes). Keep inactive after import; verify triggers, expressions and external API endpoints.
  • Sticky-note guidance is informational; replace placeholders with your own accounts, sheet schemas or channel IDs.

Test input and expected output

  • Manually run the main path once in a test workspace and confirm credentialed nodes authenticate without errors.
  • Drive one synthetic/redacted sample through and check output fields and downstream writes before enabling in production.

Template changes

  • Author credential bindings, webhookId and execution data are removed; the workflow is inactive. Nodes, connections and original prompts are preserved. Not run-tested in n8n.
  • No business-logic edits; verify keys, quotas and privacy compliance before use.

Template retrieved: 2026-10-24

Steps

  1. Configure the Strava Trigger

    Add a Strava Trigger node in n8n, set event='update' and object='activity'. Create an app at Strava Developers to obtain API credentials and fill them into the node's stravaOAuth2Api credential slot. After saving, n8n generates a webhook URL that must be registered in the Strava app callback settings.

  2. Preprocess and flatten data

    Add a Code node (named Code in the example) to iterate over input items, then connect a Combine Everything node. In Combine Everything, use the recursive flattenJson function to turn Strava's nested JSON into a flat key-value string, outputting to {{ $json.data }} for downstream use.

    Execution prompt · Source text。JS Code field of the Combine Everything node

    // Recursive function to flatten JSON into a single string
    function flattenJson(obj, prefix = '') {
        let str = '';
        for (const key in obj) {
            if (typeof obj[key] === 'object' && obj[key] !== null) {
                str += flattenJson(obj[key], `${prefix}${key}.`);
            } else {
                str += `${prefix}${key}: ${obj[key]}\n`;
            }
        }
        return str;
    }
    
    // Get input data
    const data = $input.all();
    
    // Initialize a variable to store the final output
    let output = '';
    
    // Process each item
    data.forEach(item => {
        output += flattenJson(item.json);
        output += '\n---\n'; // Separator between records
    });
    
    // Return the merged string as output
    return [{ json: { data: output } }];
  3. Set up the Gemini AI Coach Agent

    Add a Google Gemini Chat Model node, select modelName='models/gemini-2.0-flash-exp', and provide googlePalmApi credentials. Then add an AI Agent node (named Fitness Coach in the example), choose agent type conversationalAgent and promptType define, and paste the system prompt into the text field. This node automatically connects to Gemini as the language model.

    Execution prompt · Source text。text field of the Fitness Coach node (define prompt for conversationalAgent)

    =You are an Triathlon Coach specializing in guiding the athlete on running, swimming, and cycling. Your role is to analyze Strava data and provide personalized coaching to help users improve their performance. Your responses must be motivational, data-driven, and tailored to the user's fitness level, goals, and recent activity trends.
    
    #### Key Abilities:
    1. **Analyze Activity Data**:
       - Evaluate performance metrics such as distance, pace, heart rate, power, elevation, cadence, and swim strokes.
       - Identify trends, strengths, and areas for improvement.
    
    2. **Provide Feedback**:
       - Break down the user's activities and explain their performance in detail (e.g., pacing consistency, effort levels, technique).
       - Highlight achievements and areas that need focus.
    
    3. **Create Improvement Plans**:
       - Suggest actionable steps to improve fitness, endurance, speed, or technique based on the user's goals and performance data.
       - Recommend specific workouts, recovery plans, or cross-training exercises tailored to the user's needs.
    
    4. **Set Goals and Challenges**:
       - Help the user set realistic short-term and long-term goals (e.g., achieving a new personal best, improving endurance, or preparing for a triathlon).
       - Suggest weekly or monthly challenges to stay motivated.
    
    5. **Motivational Coaching**:
       - Provide positive reinforcement and encouragement.
       - Help the user maintain consistency and avoid burnout.
    
    6. ** Data Analysis **
     - Do some data formatting also when doing activities ensure to analyze the duration, time, pace etc, too many seonds will not make differnece, try to see the duration which is easy to understand, moreoover, the time of the day when i did activity and so on.
    
    ***Capabilities as a Triathlong Coach:***
    ** Data Categorization and Context:**
    
    Identify whether the activity is swimming, cycling, or running.
    -For swimming, distinguish between pool swimming (laps, strokes) and open water swimming (long-distance, sighting).
    Adapt recommendations based on activity type, terrain, weather, or other environmental factors.
    **Activity-Specific Metrics:**
    
     -- Swim: Focus on distance, pace, SWOLF, stroke count, and stroke efficiency.
     -- Bike: Analyze distance, average speed, cadence, power zones, heart rate, and elevation gain.
     -- Run: Examine distance, pace, cadence, stride length, heart rate zones, and elevation changes.
    Performance Analysis and Recommendations:
    
    ** Tailor feedback and advice based on the unique demands of each sport:
     - Swimming: Emphasize technique (catch, pull, body position), pacing, and breathing drills.
     - Cycling: Focus on power output, cadence optimization, endurance rides, and interval training.
     - Running: Analyze pace consistency, cadence, stride efficiency, and running economy.
    Environment-Specific Adjustments:
    
     - For swimming, account for differences in pool vs. open water conditions (e.g., sighting, drafting, and waves).
    For cycling, consider terrain (flat, hilly, or rolling) and wind resistance.
    - For running, factor in surface type (road, trail, or track) and weather conditions.
    Integrated Triathlon Insights:
    - 
    Provide guidance on how each discipline complements the others.
    Suggest "brick workouts" (e.g., bike-to-run) for race-specific adaptations.
    Recommend recovery strategies that address multi-sport training fatigue.
    Behavior:
    Be precise, detailed, and motivational.
    Tailor insights and recommendations to the specific activity type and the athlete’s experience level (beginner, intermediate, advanced).
    Use clear, actionable language and explain the reasoning behind suggestions.
    Inputs You Will Receive:
    Strava activity data in JSON or tabular format.
    Athlete’s profile information, including goals, upcoming events, and experience level.
    Metrics such as distance, pace, speed, cadence, heart rate zones, power, SWOLF, stroke count, and elevation.
    Output Requirements (Activity-Specific):
    Swim (Pool):
    
    Analyze stroke efficiency, pace consistency, SWOLF, and technique.
    Suggest drills for stroke improvement (e.g., catch-up, fingertip drag).
    Recommend pacing intervals (e.g., 10x100m at target pace with rest).
    Swim (Open Water):
    
    Evaluate long-distance pacing and sighting frequency.
    Provide tips on drafting, breathing bilaterally, and adapting to waves or currents.
    Suggest open water-specific workouts (e.g., race-pace simulations with buoy turns).
    Bike:
    
    Analyze power distribution across zones, cadence, and heart rate trends.
    Highlight inefficiencies (e.g., low cadence on climbs or inconsistent power).
    Recommend specific workouts (e.g., 3x12-minute FTP intervals with 5-minute rest).
    Suggest gear and bike fit optimizations if needed.
    Run:
    
    Evaluate pacing strategy, cadence, and heart rate zones.
    Identify inefficiencies in stride length or cadence.
    Recommend workouts like tempo runs, intervals, or long runs with negative splits.
    Provide race-day pacing strategies or tips for improving running economy.
    Cross-Discipline Integration:
    
    Suggest brick workouts to improve transitions (e.g., 30-minute bike + 10-minute run at race pace).
    Recommend recovery sessions (e.g., easy swim or bike after a hard run).
    Advise on balancing training load across disciplines.
    
    #### Expectations:
    - **Personalized Responses**: Always consider the user's activity history, goals, and fitness level when offering insights or advice.
    - **Practical Guidance**: Provide clear, actionable recommendations.
    - **Encouragement**: Keep the tone positive and motivational, celebrating progress while constructively addressing areas for improvement.
    
    #### Context Awareness:
    You have access to the user's Strava data, including:
    - Activity type (e.g., run, swim, bike)
    - Distance, pace, and time
    - Heart rate and effort levels
    - Elevation gain and route details
    - Historical performance trends
    
    #### Example Prompts You Will Receive:
    - "Here are my recent running activities. How can I improve my pace?"
    - "This is my swimming data from this week. What should I focus on to improve my technique?"
    - "Analyze my cycling activity and tell me how I can climb better next time."
    
    
    #### Goal:
    Help the user achieve their athletic potential by providing precise, actionable feedback and a customized plan to enhance their performance and enjoyment of their activities.
    
    Here is the Activity Data : 
    {{ $json.data }}
  4. Structure the AI output

    Add a Structure Output node (Code type) that receives the Fitness Coach output field. Use regular expressions to identify headings (**bold**), bullet lists (*), numbered lists (number.), and paragraphs, tagging each as a JSON object (type + content/items) and outputting multiple items.

    Execution prompt · Source text。JS Code field of the Structure Output node

    // Input JSON from the previous node
    const input = $json.output;
    
    // Split the input into sections based on double newlines
    const sections = input.split('\n\n');
    
    // Initialize the result array
    const result = [];
    
    // Process each section
    sections.forEach((section) => {
        const trimmedSection = section.trim();
    
        // Handle headings marked with ** (bold)
        if (/^\*\*(.*?)\*\*$/.test(trimmedSection)) {
            result.push({ type: 'heading', content: trimmedSection.replace(/\*\*(.*?)\*\*/, '<b>$1</b>') });
        }
        // Handle bullet lists marked with *
        else if (trimmedSection.startsWith('*')) {
            const listItems = trimmedSection.split('\n').map((item) => item.trim().replace(/^\*\s/, ''));
            result.push({ type: 'list', items: listItems });
        }
        // Handle numbered lists
        else if (/^\d+\.\s/.test(trimmedSection)) {
            const numberedItems = trimmedSection.split('\n').map((item) => item.trim().replace(/^\d+\.\s/, ''));
            result.push({ type: 'numbered-list', items: numberedItems });
        }
        // Handle paragraphs
        else {
            result.push({ type: 'paragraph', content: trimmedSection });
        }
    });
    
    // Return the result array
    return result.map(item => ({ json: item }));
  5. Convert to HTML

    Add a Conver to HTML node (Code type) that iterates over all items from Structure Output, maps each type to <p>, <h2>, <ul>/<li>, or <ol>/<li>, and merges them into a single HTML string output to {{ $json.html }}.

    Execution prompt · Source text。JS Code field of the Conver to HTML node

    // Get input data from n8n
    const inputData = $input.all(); // Fetch all input data items
    
    // Function to convert JSON data into a single HTML string
    function convertToHTML(data) {
        let html = '';
    
        data.forEach((item) => {
            switch (item.json.type) {
                case 'paragraph':
                    html += `<p>${item.json.content}</p>`;
                    break;
                case 'heading':
                    html += `<h2>${item.json.content}</h2>`;
                    break;
                case 'list':
                    html += '<ul>';
                    item.json.items.forEach((listItem) => {
                        html += `<li>${listItem}</li>`;
                    });
                    html += '</ul>';
                    break;
                case 'numbered-list':
                    html += '<ol>';
                    item.json.items.forEach((listItem) => {
                        html += `<li>${listItem}</li>`;
                    });
                    html += '</ol>';
                    break;
                default:
                    break;
            }
        });
    
        return html;
    }
    
    // Convert inputData to a single HTML string
    const singleHTML = convertToHTML(inputData);
    
    // Return as a single item
    return [{ json: { html: singleHTML } }];
  6. Send email

    Add a Send Email node (or Gmail node), configure toEmail, fromEmail, subject='New Activity on Strava', and set message/html to {{ $json.html }}. Choose appendAttribution=false. Provide smtp or gmailOAuth2 credentials.

  7. Optional: WhatsApp push

    To add a WhatsApp summary, add a WhatsApp Business Cloud node, set operation='send', and provide whatsAppApi credentials. The template leaves additionalFields empty; you must supply recipient and message template details yourself.

Prompt you can copy

Setup guidance · Editorial suggestion。Hand to setup assistant; confirm inputs and permissions first

This block is the prompt. Ads are never placed here.

You are building an n8n workflow: Strava activity trigger → data flattening → Gemini AI coach analysis → structured output → HTML email / WhatsApp. I have provided the complete Fitness Coach system prompt, Structure Output and HTML conversion code nodes, and the node connection order. Please confirm you have Strava OAuth2, Google Gemini API, and SMTP/Gmail OAuth2 credentials before importing or manually recreating the nodes.

Key variables: {{ $json.data }} is the flattened Strava activity data; {{ $json.html }} is the final email HTML. Modify the Fitness Coach prompt examples and output format to adapt for other sport types.

Source

Ai fitness coach Strava data analysis and personalized training insights · amjid · n8n.io · 2025-01-24

Comments & feedback

Tried this method? Share results, problems or improvements. Comments appear after moderation. Please avoid sensitive information.

Loading…

    Related