{
  "id": "hKZ3mbvF2xHQR91M",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Webinar Feedback Workflow",
  "tags": [],
  "nodes": [
    {
      "id": "eb02fbc6-420a-4c0d-8f40-0d1fe5942ee8",
      "name": "Feedback Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -208,
        192
      ],
      "parameters": {
        "path": "webinar-feedback",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "streaming"
      },
      "typeVersion": 2.1
    },
    {
      "id": "eaf2baae-5dce-4343-a1f7-1f176232b406",
      "name": "Normalize Feedback",
      "type": "n8n-nodes-base.code",
      "position": [
        240,
        192
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const body = $json.body ?? $json ?? {};\n\nreturn {\n  email: body.Email || \"\",\n  name: body.Name || \"Attendee\",\n  rating: Number(body.Rating) || 0,\n  feedback: body.Feedback || body.comment || \"\",\n  attended: body.Attended !== false,\n  webinarTitle: body['Webinar Title'] || \"AI Automation Mastery Webinar\",\n  submittedAt: new Date().toISOString()\n};\n"
      },
      "typeVersion": 2
    },
    {
      "id": "db8c422a-4b4a-4eba-a308-2a369fe4d7f2",
      "name": "Store Feedback",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2192,
        192
      ],
      "parameters": {
        "columns": {
          "value": {
            "Sent At": "={{ $now.toISO().slice(0, 10) }}\n",
            "Our Reply": "={{ $('Merge').item.json.aiThankYouMessage }}",
            "Email Sent": "={{ $json.labelIds[0] }}",
            "row_number": 0,
            "feedback_id": "={{ $('Store Partial').item.json.feedback_id }}"
          },
          "schema": [
            {
              "id": "feedback_id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "feedback_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Name",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Webinar Title",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Webinar Title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Rating",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Rating",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Original Feedback",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Original Feedback",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Our Reply",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Our Reply",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email Sent",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Email Sent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Sent At",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Sent At",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "number",
              "display": true,
              "removed": false,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "feedback_id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "value": "YOUR_SHEET_NAME"
        },
        "documentId": {
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "ffcc9e52-e985-4e7e-bc01-3a5a0a0a211c",
      "name": "Parse AI Response",
      "type": "n8n-nodes-base.code",
      "position": [
        1200,
        48
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// ===============================\n// Parse AI Agent Response (FINAL)\n// ===============================\n\n// 1\ufe0f\u20e3 Extract AI text safely\nconst rawText =\n  $json.output?.[0]?.content?.[0]?.text ||\n  '{}';\n\n// 2\ufe0f\u20e3 Clean + parse JSON\nlet aiData = {};\ntry {\n  const cleaned = rawText.replace(/```json|```/g, '').trim();\n  aiData = JSON.parse(cleaned);\n} catch (e) {\n  aiData = {\n    segment: \"warm\",\n    thankYouMessage: \"Thank you for attending the webinar.\",\n    nextSteps: []\n  };\n}\n\n// 3\ufe0f\u20e3 Promote parsed fields (DO NOT add resources here)\nreturn {\n  ...$json,\n  aiSegment: aiData.segment || \"warm\",\n  aiThankYouMessage: aiData.thankYouMessage || \"Thank you for your feedback.\",\n  aiNextSteps: Array.isArray(aiData.nextSteps) ? aiData.nextSteps : []\n};\n"
      },
      "typeVersion": 2
    },
    {
      "id": "b7d5b399-12fc-4941-8c4a-d23527cc969d",
      "name": "Build Email HTML",
      "type": "n8n-nodes-base.code",
      "position": [
        1744,
        192
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// ===============================\n// Build Professional Feedback Reply Email\n// Mode: Run Once for Each Item\n// ===============================\n\n// Core data (DO NOT rename)\nconst name = $json.Name || 'there';\nconst email = $json.Email || '';\nconst webinarTitle = $json['Webinar Title'] || 'our webinar';\n\n// -------------------------------\n// Parse AI JSON SAFELY\n// -------------------------------\nlet aiData = {};\ntry {\n  aiData = JSON.parse($json.output[0].content[0].text);\n} catch (e) {\n  aiData = {};\n}\n\nconst thankYouMessage =\n  aiData.thankYouMessage || 'Thank you for sharing your feedback.';\n\nconst nextSteps = Array.isArray(aiData.nextSteps) ? aiData.nextSteps : [];\n\n// -------------------------------\n// Common Resources (already merged)\n// -------------------------------\nconst resources = Array.isArray($json.resources) ? $json.resources : [];\n\n// -------------------------------\n// Optional sections\n// -------------------------------\nconst nextStepsBlock = nextSteps.length\n  ? `\n    <div class=\"section\">\n      <h3>Suggested next steps</h3>\n      <ul>\n        ${nextSteps.map(step => `<li>${step}</li>`).join('')}\n      </ul>\n    </div>`\n  : '';\n\nconst resourcesBlock = resources.length\n  ? `\n    <div class=\"section\">\n      <h3>Helpful resources</h3>\n      <ul>\n        ${resources\n          .map(r => `<li><a href=\"${r.url}\" target=\"_blank\">${r.label}</a></li>`)\n          .join('')}\n      </ul>\n    </div>`\n  : '';\n\n// -------------------------------\n// Final HTML\n// -------------------------------\nconst htmlContent = `\n<!DOCTYPE html>\n<html>\n<head>\n  <style>\n    body {\n      font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Arial, sans-serif;\n      background-color: #f4f6f8;\n      padding: 24px;\n      color: #111827;\n    }\n    .container {\n      max-width: 640px;\n      margin: auto;\n      background: #ffffff;\n      border-radius: 8px;\n      box-shadow: 0 6px 20px rgba(0,0,0,0.08);\n    }\n    .header {\n      padding: 28px;\n      border-bottom: 1px solid #e5e7eb;\n    }\n    .content {\n      padding: 28px;\n      font-size: 15px;\n      line-height: 1.6;\n    }\n    h1 {\n      font-size: 20px;\n      margin: 0 0 12px 0;\n    }\n    h3 {\n      font-size: 16px;\n      margin-bottom: 8px;\n    }\n    .section {\n      margin-top: 24px;\n      padding-top: 16px;\n      border-top: 1px solid #e5e7eb;\n    }\n    ul {\n      padding-left: 18px;\n      margin: 8px 0;\n    }\n    li {\n      margin: 6px 0;\n    }\n    .footer {\n      padding: 20px;\n      font-size: 13px;\n      color: #6b7280;\n      border-top: 1px solid #e5e7eb;\n    }\n    a {\n      color: #2563eb;\n      text-decoration: none;\n    }\n  </style>\n</head>\n<body>\n  <div class=\"container\">\n    <div class=\"header\">\n      <h1>Thank you, ${name}</h1>\n      <p>Regarding ${webinarTitle}</p>\n    </div>\n\n    <div class=\"content\">\n      <p>${thankYouMessage}</p>\n\n      ${resourcesBlock}\n      ${nextStepsBlock}\n\n      <p style=\"margin-top:24px;\">\n        If you have any questions or would like to discuss this further, feel free to reply to this email.\n      </p>\n\n      <p>\n        Best regards,<br/>\n        <strong>The Webinar Team</strong>\n      </p>\n    </div>\n\n    <div class=\"footer\">\n      This email was sent in response to feedback you shared after attending our webinar.\n    </div>\n  </div>\n</body>\n</html>\n`;\n\nreturn {\n  email,\n  subject: `Thank you for your feedback \u2013 ${webinarTitle}`,\n  htmlContent\n};\n"
      },
      "typeVersion": 2
    },
    {
      "id": "35d022c8-fbb9-4ad6-a156-2776274cd140",
      "name": "Send AI Thank You Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1968,
        192
      ],
      "parameters": {
        "sendTo": "={{ $json.email }}",
        "message": "={{ $json.htmlContent }}",
        "options": {
          "appendAttribution": false
        },
        "subject": "={{ $json.subject }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "8260de8d-d657-4856-bd3e-aadce922b260",
      "name": "Message a model",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        896,
        48
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini",
          "cachedResultName": "GPT-4.1-MINI"
        },
        "options": {},
        "responses": {
          "values": [
            {
              "content": "You are a professional webinar organizer responding personally to attendee feedback.\n\nYour task is to:\n1. Read the attendee\u2019s feedback carefully\n2. Write a thoughtful, human reply that acknowledges what they said\n3. Decide an engagement segment internally (HOT / WARM / COLD)\n4. Suggest appropriate next steps and resources subtly and professionally\n\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nSEGMENTATION LOGIC (INTERNAL USE ONLY)\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nDetermine the segment using these rules:\n\nHOT\n- Rating is 4 or 5\n- Attended = true\n- Feedback is clearly positive, detailed, or shows intent to apply learnings\n\nWARM\n- Rating is exactly 3\n- Attended = true\n- Feedback is neutral or brief\n\nCOLD\n- Rating is 1 or 2\n- OR Attended = false\n- OR feedback is missing or very weak\n\nIf unsure, choose the LOWER segment.\n\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nWRITING GUIDELINES (VERY IMPORTANT)\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n- Write like a real person replying to feedback\n- Acknowledge specific points mentioned in the feedback\n- Be professional, calm, and appreciative\n- Do NOT mention ratings or scores\n- Do NOT use emojis\n- Do NOT sound promotional or salesy\n- 2\u20134 short paragraphs maximum\n\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nOUTPUT REQUIREMENTS\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nRespond in VALID JSON ONLY.\nNo markdown, no explanations, no extra text.\n\nJSON format:\n{\n  \"segment\": \"hot | warm | cold\",\n  \"thankYouMessage\": \"A natural, professional reply that directly responds to the attendee\u2019s feedback\",\n  \"nextSteps\": [\n    \"1\u20132 optional, low-pressure next steps\"\n  ],\n\"resources\": [\nThe following resources are available. Do NOT invent new ones.\n{{ $('Store Partial').item.json['Webinar Title'] }} \n]\n}\n\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nATTENDEE FEEDBACK\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nFeedback: {{ $('Store Partial').item.json['Original Feedback'] }}\nRating: {{ $('Store Partial').item.json.Rating }}\nWebinar: {{ $('Store Partial').item.json['Webinar Title'] }}\n"
            }
          ]
        },
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "f19b7631-d608-44e8-8836-6dc8935a48d6",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        1504,
        176
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition",
        "numberInputs": 3
      },
      "typeVersion": 3.2
    },
    {
      "id": "2a86cbb2-f173-4740-b715-5f05c87eede8",
      "name": "Common Resources",
      "type": "n8n-nodes-base.code",
      "position": [
        688,
        224
      ],
      "parameters": {
        "jsCode": "return [\n  {\n    json: {\n      resources: [\n        {\n          label: \"Webinar Recording\",\n          url: \"https://yourdomain.com/webinar-recording\"\n        },\n        {\n          label: \"Presentation Slides\",\n          url: \"https://yourdomain.com/slides\"\n        },\n        {\n          label: \"Automation Use-Case Library\",\n          url: \"https://yourdomain.com/use-cases\"\n        }\n      ]\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "b2b57686-ac2f-4883-9e6c-130cced071a5",
      "name": "Store Partial",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        464,
        192
      ],
      "parameters": {
        "columns": {
          "value": {
            "Name": "={{ $json.name }}",
            "Email": "={{ $json.email }}",
            "Rating": "={{ $json.rating }}",
            "feedback_id": "={{ $('ID Generation').item.json.feedback_id }}",
            "Webinar Title": "={{ $json.webinarTitle }}",
            "Original Feedback": "={{ $json.feedback }}"
          },
          "schema": [
            {
              "id": "feedback_id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "feedback_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Webinar Title",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Webinar Title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Rating",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Rating",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Original Feedback",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Original Feedback",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Our Reply",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Our Reply",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email Sent",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Email Sent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Sent At",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Sent At",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "value": "YOUR_SHEET_NAME"
        },
        "documentId": {
          "__rl": true,
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "a9827ad6-7a2d-453e-8469-9c386c800f1e",
      "name": "ID Generation",
      "type": "n8n-nodes-base.code",
      "position": [
        16,
        192
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// ===============================\n// Generate Human-Readable feedback_id\n// ===============================\n\nconst name = ( $json.body.Name|| 'Guest')\n  .replace(/\\s+/g, '')\n  .trim();\n\nconst submittedAt = new Date(\n  $json.submittedAt || Date.now()\n);\n\n// Format date parts\nconst date = submittedAt.toISOString().slice(0, 10); // YYYY-MM-DD\nconst time = submittedAt.toISOString().slice(11, 16); // HH:MM\n\nconst feedback_id = `${name}_${date}_${time}`;\n\nreturn {\n  ...$json,\n  feedback_id\n};\n"
      },
      "typeVersion": 2
    },
    {
      "id": "b50f686c-e89d-4752-9797-6fd13e4c7d93",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -816,
        -80
      ],
      "parameters": {
        "width": 528,
        "height": 624,
        "content": "## Webinar Feedback Workflow\nThis workflow automatically captures webinar feedback, understands attendee intent using AI, and sends a personalized follow-up email without manual review. This workflow is ideal for webinars, workshops, and live events where follow-up quality matters.\n\n### How it works\n\n\t\u2022\tA webhook receives feedback from your webinar form\n\t\u2022\tFeedback data is normalized and stored in Google Sheets\n\t\u2022\tAn AI model analyzes sentiment and intent\n\t\u2022\tA natural, professional response is generated\n\t\u2022\tA polished HTML email is sent automatically via Gmail\n\t\u2022\tThe reply and delivery status are logged back to Sheets\n\n### Setup steps\n\n\t1.\tConnect Webhook to your feedback form\n\t2.\tAdd Google Sheets, OpenAI, and Gmail credentials\n\t3.\tUpdate resource links (recording, slides, use-cases)\n\t4.\tTest once with sample feedback and activate\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "6050229b-7992-4dff-b2bf-cbf60e7dc128",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -256,
        -80
      ],
      "parameters": {
        "color": 7,
        "width": 624,
        "height": 624,
        "content": "## Step 1: Feedback Intake\nReceives attendee responses, generates a readable feedback ID, and normalizes incoming form data for downstream processing.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "1c214c8c-27bf-43cb-8dea-fc79298606ce",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        400,
        -80
      ],
      "parameters": {
        "color": 7,
        "width": 400,
        "height": 624,
        "content": "## Step 2: Data Persistence\nStores raw feedback in Google Sheets and enriches it with shared webinar resources for consistent AI responses.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "6101a62d-3a76-4a8c-b064-591e014d99db",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        832,
        -80
      ],
      "parameters": {
        "color": 7,
        "width": 544,
        "height": 624,
        "content": "## Step 3: AI Understanding\nAnalyzes sentiment, intent, and engagement level, then produces a structured human-like response plan.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "1aa4342b-3618-448b-bf94-dbc6f92f8290",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1424,
        -80
      ],
      "parameters": {
        "color": 7,
        "width": 704,
        "height": 624,
        "content": "## Step 4: Personalized Follow-Up\nBuilds a clean HTML email and sends a thoughtful, non-salesy response tailored to each attendee.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "df0a330e-8e5c-4015-b465-43d3350cd0f5",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2144,
        -80
      ],
      "parameters": {
        "color": 7,
        "height": 624,
        "content": "##  Step 5: Feedback Log\nWrites the sent email, timestamp, and status back to Google Sheets for visibility and reporting.\n"
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "b9270fd9-de43-43b8-b6b8-889d08f5cf37",
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "Build Email HTML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ID Generation": {
      "main": [
        [
          {
            "node": "Normalize Feedback",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Store Partial": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          },
          {
            "node": "Message a model",
            "type": "main",
            "index": 0
          },
          {
            "node": "Common Resources",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Store Feedback": {
      "main": [
        []
      ]
    },
    "Message a model": {
      "main": [
        [
          {
            "node": "Parse AI Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Email HTML": {
      "main": [
        [
          {
            "node": "Send AI Thank You Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Common Resources": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Feedback Webhook": {
      "main": [
        [
          {
            "node": "ID Generation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse AI Response": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Feedback": {
      "main": [
        [
          {
            "node": "Store Partial",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send AI Thank You Email": {
      "main": [
        [
          {
            "node": "Store Feedback",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}