{
  "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
          }
        ]
      ]
    }
  }
}