AutomationFlowsAI & RAG › Log Workouts and Get AI Fitness Analysis with a Form, Google Gemini, Sheets,…

Log Workouts and Get AI Fitness Analysis with a Form, Google Gemini, Sheets,…

Original n8n title: Log Workouts and Get AI Fitness Analysis with a Form, Google Gemini, Sheets, Slack, and Gmail

ByOka Hironobu @okp29 on n8n.io

Gym-goers, runners, home workout enthusiasts, and personal trainers who want to track workouts without fiddling with complicated fitness apps. Just type what you did and let AI handle the rest.

Event trigger★★★★☆ complexityAI-powered12 nodesForm TriggerChain LlmGoogle Gemini ChatGoogle SheetsSlackGmail
AI & RAG Trigger: Event Nodes: 12 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #13574 — we link there as the canonical source.

This workflow follows the Chainllm → Form Trigger recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "nodes": [
    {
      "id": "bb25e4a1-cf34-4693-ae7c-0108c653ee59",
      "name": "Workout Log Form",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        -160,
        64
      ],
      "parameters": {
        "path": "9caa6885-c1c2-44b1-b749-ca28333a9cdf",
        "options": {},
        "formTitle": "Workout Logger",
        "formFields": {
          "values": [
            {
              "fieldType": "textarea",
              "fieldLabel": "What did you do today?",
              "placeholder": "e.g. Bench press 60kg x 10 x 3, Running 5km 28min, Squats bodyweight 20 reps x 4",
              "requiredField": true
            },
            {
              "fieldType": "dropdown",
              "fieldLabel": "How do you feel? (1-10)",
              "fieldOptions": {
                "values": [
                  {
                    "option": "1 - Exhausted"
                  },
                  {
                    "option": "2"
                  },
                  {
                    "option": "3"
                  },
                  {
                    "option": "4"
                  },
                  {
                    "option": "5 - Normal"
                  },
                  {
                    "option": "6"
                  },
                  {
                    "option": "7"
                  },
                  {
                    "option": "8"
                  },
                  {
                    "option": "9"
                  },
                  {
                    "option": "10 - Amazing"
                  }
                ]
              },
              "requiredField": true
            },
            {
              "fieldType": "number",
              "fieldLabel": "Duration (minutes)",
              "requiredField": true
            },
            {
              "fieldType": "textarea",
              "fieldLabel": "Notes",
              "placeholder": "Any injuries, PRs, or things to remember"
            }
          ]
        },
        "formDescription": "Log your workout and get AI-powered analysis on muscle groups, calories, and progress tips."
      },
      "typeVersion": 2
    },
    {
      "id": "984a6b52-88ac-45b3-8609-304ed0d4f1a8",
      "name": "Analyze Workout with AI",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        48,
        64
      ],
      "parameters": {
        "text": "You are a certified personal trainer and sports scientist. Analyze this workout log and return ONLY valid JSON (no markdown, no extra text):\n\nWorkout description: {{ $json['What did you do today?'] }}\nDuration: {{ $json['Duration (minutes)'] }} minutes\nFeeling: {{ $json['How do you feel? (1-10)'] }}\nNotes: {{ $json['Notes'] || 'None' }}\n\nReturn this exact JSON structure:\n{\n  \"exercises\": [\n    {\n      \"name\": \"Exercise name\",\n      \"type\": \"strength/cardio/flexibility/other\",\n      \"muscle_groups\": [\"primary muscles worked\"],\n      \"sets\": 0,\n      \"reps\": 0,\n      \"weight_kg\": 0,\n      \"duration_min\": 0,\n      \"estimated_calories\": 0\n    }\n  ],\n  \"summary\": {\n    \"total_exercises\": 0,\n    \"total_calories\": 0,\n    \"primary_type\": \"strength/cardio/mixed\",\n    \"muscle_groups_hit\": [\"list of all muscles worked\"],\n    \"intensity\": \"low/moderate/high/very high\"\n  },\n  \"tips\": [\n    \"One specific, actionable tip based on this workout\",\n    \"Another tip about recovery or next session\"\n  ],\n  \"next_workout_suggestion\": \"Brief suggestion for complementary workout\"\n}",
        "promptType": "define"
      },
      "typeVersion": 1.4
    },
    {
      "id": "3650268d-d219-45fc-8827-6792434af319",
      "name": "Google Gemini",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        48,
        240
      ],
      "parameters": {
        "options": {
          "temperature": 0.2
        },
        "modelName": "models/gemini-1.5-flash-latest"
      },
      "typeVersion": 1
    },
    {
      "id": "025dc1e0-f596-4ba8-be6f-142d8fec46bd",
      "name": "Parse AI Results",
      "type": "n8n-nodes-base.code",
      "position": [
        336,
        64
      ],
      "parameters": {
        "jsCode": "// Parse and validate AI workout analysis\nconst aiResponse = $json.response || $json.text || '';\n\n// Extract JSON from response\nlet jsonStr = aiResponse;\nconst jsonMatch = aiResponse.match(/```(?:json)?\\s*([\\s\\S]*?)```/);\nif (jsonMatch) {\n  jsonStr = jsonMatch[1].trim();\n}\n\nlet parsed;\ntry {\n  parsed = JSON.parse(jsonStr);\n} catch (e) {\n  parsed = {\n    exercises: [],\n    summary: {\n      total_exercises: 0,\n      total_calories: 0,\n      primary_type: 'unknown',\n      muscle_groups_hit: [],\n      intensity: 'moderate'\n    },\n    tips: ['Could not parse workout details. Try being more specific next time.'],\n    next_workout_suggestion: 'Rest day or light cardio'\n  };\n}\n\n// Get original form data\nconst form = $('Workout Log Form').first().json;\nconst feelingRaw = form['How do you feel? (1-10)'] || '5';\nconst feeling = parseInt(feelingRaw.match(/\\d+/)?.[0] || '5');\n\nreturn {\n  date: new Date().toISOString().split('T')[0],\n  workout_description: form['What did you do today?'],\n  duration_min: parseInt(form['Duration (minutes)']) || 0,\n  feeling: feeling,\n  notes: form['Notes'] || '',\n  exercises: parsed.exercises || [],\n  exercise_count: (parsed.exercises || []).length,\n  total_calories: parsed.summary?.total_calories || 0,\n  primary_type: parsed.summary?.primary_type || 'unknown',\n  muscle_groups: (parsed.summary?.muscle_groups_hit || []).join(', '),\n  intensity: parsed.summary?.intensity || 'moderate',\n  tips: (parsed.tips || []).join(' | '),\n  next_suggestion: parsed.next_workout_suggestion || '',\n  logged_at: new Date().toISOString()\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "270c9b77-67cc-454f-8d0e-2e09ac26d2e5",
      "name": "Save to Workout Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        528,
        64
      ],
      "parameters": {
        "columns": {
          "value": {
            "Date": "={{ $json.date }}",
            "Tips": "={{ $json.tips }}",
            "Type": "={{ $json.primary_type }}",
            "Notes": "={{ $json.notes }}",
            "Feeling": "={{ $json.feeling }}",
            "Muscles": "={{ $json.muscle_groups }}",
            "Workout": "={{ $json.workout_description }}",
            "Calories": "={{ $json.total_calories }}",
            "Duration": "={{ $json.duration_min }}",
            "Exercises": "={{ $json.exercise_count }}",
            "Intensity": "={{ $json.intensity }}",
            "Logged At": "={{ $json.logged_at }}",
            "Next Suggestion": "={{ $json.next_suggestion }}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {
          "cellFormat": "USER_ENTERED"
        },
        "operation": "appendOrUpdate",
        "sheetName": "Workouts",
        "documentId": "YOUR_GOOGLE_SHEET_ID"
      },
      "typeVersion": 4.4
    },
    {
      "id": "3f66044c-56ed-4f63-8a0f-c9e92db2ba81",
      "name": "Build Summary Message",
      "type": "n8n-nodes-base.code",
      "position": [
        736,
        64
      ],
      "parameters": {
        "jsCode": "// Build a nice summary for notifications\nconst w = $json;\n\n// Emoji for feeling\nconst feelEmoji = w.feeling >= 8 ? '\ud83d\udd25' : w.feeling >= 5 ? '\ud83d\udcaa' : '\ud83d\ude24';\n\n// Emoji for type\nconst typeEmoji = {\n  'strength': '\ud83c\udfcb\ufe0f',\n  'cardio': '\ud83c\udfc3',\n  'mixed': '\ud83c\udfcb\ufe0f\ud83c\udfc3',\n  'flexibility': '\ud83e\uddd8'\n};\nconst tEmoji = typeEmoji[w.primary_type] || '\ud83d\udcaa';\n\nconst intensityBar = {\n  'low': '\ud83d\udfe2',\n  'moderate': '\ud83d\udfe1',\n  'high': '\ud83d\udfe0',\n  'very high': '\ud83d\udd34'\n};\nconst iBar = intensityBar[w.intensity] || '\ud83d\udfe1';\n\nconst slackMsg = [\n  `${tEmoji} *Workout Logged* \u2014 ${w.date}`,\n  ``,\n  `*What:* ${w.workout_description}`,\n  `*Duration:* ${w.duration_min} min | *Feeling:* ${w.feeling}/10 ${feelEmoji}`,\n  `*Type:* ${w.primary_type} | *Intensity:* ${iBar} ${w.intensity}`,\n  `*Calories:* ~${w.total_calories} kcal`,\n  `*Muscles:* ${w.muscle_groups}`,\n  ``,\n  `\ud83d\udca1 *Tips:* ${w.tips}`,\n  `\ud83d\udccb *Next time:* ${w.next_suggestion}`,\n  w.notes ? `\ud83d\udccc ${w.notes}` : ''\n].filter(Boolean).join('\\n');\n\nconst emailHtml = `<h2>${tEmoji} Workout Summary \u2014 ${w.date}</h2>\n<p><strong>Workout:</strong> ${w.workout_description}<br>\n<strong>Duration:</strong> ${w.duration_min} min | <strong>Feeling:</strong> ${w.feeling}/10 ${feelEmoji}<br>\n<strong>Type:</strong> ${w.primary_type} | <strong>Intensity:</strong> ${w.intensity}<br>\n<strong>Estimated Calories:</strong> ~${w.total_calories} kcal<br>\n<strong>Muscle Groups:</strong> ${w.muscle_groups}</p>\n<h3>\ud83d\udca1 Tips</h3>\n<p>${w.tips.replace(/ \\| /g, '<br>')}</p>\n<h3>\ud83d\udccb Next Workout Suggestion</h3>\n<p>${w.next_suggestion}</p>\n${w.notes ? '<p><em>Notes: ' + w.notes + '</em></p>' : ''}\n<hr>\n<p><small>Logged automatically via n8n Workout Tracker</small></p>`;\n\nreturn {\n  ...w,\n  slack_message: slackMsg,\n  email_html: emailHtml\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "2c5f57f2-42cd-454b-a531-5d4128706d61",
      "name": "Notify on Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        1008,
        -16
      ],
      "parameters": {
        "text": "={{ $json.slack_message }}",
        "select": "channel",
        "channelId": "YOUR_SLACK_CHANNEL_ID",
        "otherOptions": {}
      },
      "typeVersion": 2.2
    },
    {
      "id": "39af1065-74b1-44e2-86ca-1aa0de152996",
      "name": "Email Summary",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1008,
        176
      ],
      "parameters": {
        "sendTo": "YOUR_EMAIL_ADDRESS",
        "message": "={{ $json.email_html }}",
        "options": {},
        "subject": "Workout logged: {{ $json.primary_type }} {{ $json.duration_min }}min \u2014 {{ $json.total_calories }} kcal ({{ $json.date }})"
      },
      "typeVersion": 2.1
    },
    {
      "id": "5594375b-55f7-43b5-b1ec-15856306f6ab",
      "name": "Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -624,
        -160
      ],
      "parameters": {
        "width": 400,
        "height": 660,
        "content": "## Workout tracker with AI analysis\nLog your workouts through a simple form and get instant AI-powered feedback on calories burned, muscles worked, and what to train next.\n\n### How it works\n1. Fill in the form with what you did \u2014 free text like \"Bench press 60kg x10 x3, 5km run\"\n2. Gemini AI parses each exercise, identifies muscle groups, and estimates calorie burn\n3. A code node validates everything and fills gaps\n4. Results are saved to Google Sheets as a structured training log\n5. You get a Slack ping and email with a visual summary and tips for your next session\n\n### Setup steps\n1. **Google Sheets** \u2014 create a spreadsheet with a \"Workouts\" tab. Headers: Date, Workout, Duration, Feeling, Type, Exercises, Calories, Muscles, Intensity, Tips, Next Suggestion, Notes, Logged At\n2. **Gemini API** \u2014 grab a free key from Google AI Studio\n3. **Slack** \u2014 pick the channel for workout notifications\n4. **Gmail** \u2014 connect for email summaries\n5. Bookmark the form URL or share it with your gym buddy\n\n**Tip:** Works great on your phone between sets \u2014 just type what you did and submit."
      },
      "typeVersion": 1
    },
    {
      "id": "38b42b53-004a-4ebb-9144-03881b6e7108",
      "name": "Input and AI Section",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -208,
        -160
      ],
      "parameters": {
        "color": 7,
        "width": 664,
        "height": 540,
        "content": "## Log & analyze\nThe form captures your workout in plain text. Gemini breaks it down into individual exercises with muscle groups, sets, reps, and calorie estimates."
      },
      "typeVersion": 1
    },
    {
      "id": "6bdc7dff-2cc5-445c-a00c-fcaf3e06cbce",
      "name": "Process and Save Section",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        480,
        -160
      ],
      "parameters": {
        "color": 7,
        "width": 428,
        "height": 540,
        "content": "## Validate & save\nThe code node cleans the AI output and builds a structured record. Everything gets appended to your Google Sheet as a training log."
      },
      "typeVersion": 1
    },
    {
      "id": "0259d68f-a980-4138-879e-7849e2a4dfe6",
      "name": "Notify Section",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        928,
        -160
      ],
      "parameters": {
        "color": 7,
        "width": 280,
        "height": 540,
        "content": "## Notifications\nSlack for quick confirmation, email with a full breakdown including tips and next workout suggestion."
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Google Gemini": {
      "ai_languageModel": [
        [
          {
            "node": "Analyze Workout with AI",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Parse AI Results": {
      "main": [
        [
          {
            "node": "Save to Workout Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Workout Log Form": {
      "main": [
        [
          {
            "node": "Analyze Workout with AI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Summary Message": {
      "main": [
        [
          {
            "node": "Notify on Slack",
            "type": "main",
            "index": 0
          },
          {
            "node": "Email Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save to Workout Sheet": {
      "main": [
        [
          {
            "node": "Build Summary Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Analyze Workout with AI": {
      "main": [
        [
          {
            "node": "Parse AI Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Gym-goers, runners, home workout enthusiasts, and personal trainers who want to track workouts without fiddling with complicated fitness apps. Just type what you did and let AI handle the rest.

Source: https://n8n.io/workflows/13574/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Automate your lead intake, scoring, and outreach pipeline. This workflow collects leads from forms, enriches and scores them using Relevance AI, routes them by quality, and triggers the right follow-u

Form Trigger, HTTP Request, Chain Llm +6
AI & RAG

Transform your sales pipeline with this comprehensive AI-powered platform that automates lead capture, scoring, revenue prediction, and sales team coordination. Perfect for B2B teams processing 50+ le

Form Trigger, HTTP Request, Chain Llm +4
AI & RAG

This workflow automates invoice processing and cash flow prediction by combining Google Gemini AI with form-based invoice capture, fraud detection, and financial reporting.

Form Trigger, Chain Llm, Google Gemini Chat +3
AI & RAG

Content creators, YouTubers, marketing agencies, and social media managers who want to optimize their YouTube videos for better discoverability and engagement. Perfect for teams managing multiple chan

Form Trigger, HTTP Request, Chain Llm +4
AI & RAG

Sales teams and B2B marketers who spend hours researching leads manually. If you've looked at Clay but didn't want the $149/month price tag, this workflow does the same job as a one-time n8n template.

Form Trigger, HTTP Request, Chain Llm +3