{
  "id": "",
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "name": "Personalized Feedback Summary Generator",
  "tags": [
    {
      "id": "feedback",
      "name": "Feedback"
    },
    {
      "id": "ai",
      "name": "AI"
    },
    {
      "id": "automation",
      "name": "Automation"
    },
    {
      "id": "pdf",
      "name": "PDF Generation"
    },
    {
      "id": "email",
      "name": "Email"
    }
  ],
  "nodes": [
    {
      "id": "1673a4f2-dac3-4a2f-89cf-8c95d02c0fc6",
      "name": "Sticky Note - Credentials Setup1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -7264,
        -880
      ],
      "parameters": {
        "color": 7,
        "width": 389,
        "height": 656,
        "content": "## \ud83d\udd10 CREDENTIALS SETUP REQUIRED\n\n**Before running this workflow, configure these credentials:**\n\n1. **OpenAI Account**\n   - Model: GPT-3.5-turbo (cost-effective) or GPT-4 (more accurate)\n\n2. **Gmail OAuth2**\n   - Connect via OAuth2 in n8n credentials\n\n3. **Google Sheets OAuth2**\n   - Create spreadsheet: \"Feedback Log\"\n   - Add columns: Submission ID, Timestamp, Name, Email, Rating, Sentiment, Comments, Suggestions, AI Summary, PDF URL, PDF Available Until, Email Sent\n\n4. **Slack OAuth2**\n   - Required scopes: chat:write, channels:read\n\n5. **HTML to PDF API**\n   - Sign up at hhttps://pdfmunk.com\n\n6. VerifiEmail API\n   - GET API at https://verifi.email"
      },
      "typeVersion": 1
    },
    {
      "id": "4959077e-1f6a-43f8-ad2c-30bd0baa7c8f",
      "name": "Sticky Note - Trigger1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -6160,
        -864
      ],
      "parameters": {
        "color": 7,
        "width": 392,
        "height": 657,
        "content": "## STEP 1: WEBHOOK TRIGGER\n\n**Expected Input Format:**\n```json\n{\n  \"name\": \"Customer Name\",\n  \"email\": \"email@example.com\",\n  \"rating\": 1-5,\n  \"comments\": \"Feedback text\",\n  \"suggestions\": \"Improvement ideas\"\n}\n```\n\n**Test URL:**\nGenerated when you execute this node in test mode.\n\n**Production URL:**\nActivate workflow to get permanent webhook endpoint.\n\n**Integration:**\nConnect Google Forms, Typeform, or any service that can send POST requests to this webhook."
      },
      "typeVersion": 1
    },
    {
      "id": "14577162-c367-452e-8fcc-0d444ea3ce14",
      "name": "Webhook - Receive Feedback1",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -6032,
        -368
      ],
      "parameters": {
        "path": "feedback-submission",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "4457ca3c-f600-407e-aa74-562cbb6ffe4d",
      "name": "Sticky Note - Clean Data1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -5744,
        -656
      ],
      "parameters": {
        "color": 7,
        "width": 392,
        "height": 449,
        "content": "## STEP 2: DATA CLEANING\n\n**Data Transformations:**\n- Empty name \u2192 \"Anonymous\"\n- Invalid email \u2192 empty string + flag false\n- Missing rating \u2192 0\n- Missing comments \u2192 \"No comments provided\"\n- Missing suggestions \u2192 \"No suggestions provided\"\n\n**Output:**\nClean, structured JSON ready for AI analysis with guaranteed data consistency."
      },
      "typeVersion": 1
    },
    {
      "id": "525aaa53-9a12-4379-8baa-47c91cabc443",
      "name": "Clean & Normalize Data1",
      "type": "n8n-nodes-base.code",
      "position": [
        -5664,
        -368
      ],
      "parameters": {
        "jsCode": "// Get input data\nconst items = $input.all();\nconst cleanedItems = [];\n\nfor (const item of items) {\n  const data = item.json;\n  \n  // Access the body object where the actual form data is\n  const formData = data.body || data;\n  \n  // Normalize and clean data\n  const cleaned = {\n    name: formData.name?.trim() || 'Anonymous',\n    email: formData.email?.trim().toLowerCase() || '',\n    rating: parseInt(formData.rating) || 0,\n    comments: formData.comments?.trim() || 'No comments provided',\n    suggestions: formData.suggestions?.trim() || 'No suggestions provided',\n    timestamp: new Date().toISOString(),\n    submissionId: `FB-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`\n  };\n  \n  // Validate email format\n  const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n  if (cleaned.email && !emailRegex.test(cleaned.email)) {\n    cleaned.email = '';\n    cleaned.hasValidEmail = false;\n  } else {\n    cleaned.hasValidEmail = true;\n  }\n  \n  cleanedItems.push({ json: cleaned });\n}\n\nreturn cleanedItems;"
      },
      "typeVersion": 2
    },
    {
      "id": "bee6365c-320f-426d-b90d-d421e15e2c4a",
      "name": "Sticky Note - AI Analysis1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -5328,
        -816
      ],
      "parameters": {
        "color": 7,
        "width": 408,
        "height": 609,
        "content": "## STEP 3: AI ANALYSIS\n\n**AI Instructions:**\nAnalyzes feedback and returns JSON with:\n1. **sentiment**: \"Positive\" | \"Neutral\" | \"Negative\"\n2. **highlights**: Array of 2-3 key points\n3. **suggestions**: Array of actionable recommendations\n4. **summary**: 2-3 sentence executive summary\n\n**Input Data:**\n- Customer name\n- Rating (1-5)\n- Comments\n- Suggestions\n\n**Output:**\nJSON response in `message.content` field containing structured analysis.\n\n**Tip:** Use GPT-4 for more nuanced analysis if budget allows."
      },
      "typeVersion": 1
    },
    {
      "id": "7359e419-7366-4629-b78d-9b3e6eb8e963",
      "name": "Generate AI Summary1",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        -5168,
        -368
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-3.5-turbo",
          "cachedResultName": "GPT-3.5-TURBO"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "=Analyze this feedback:\n\nName: {{ $json.name }}\nRating: {{ $json.rating }}/5\nComments: {{ $json.comments }}\nSuggestions: {{ $json.suggestions }}"
            },
            {
              "role": "system",
              "content": "=You are a feedback analysis assistant. You MUST respond with ONLY valid JSON, no other text.\n\nAnalyze the feedback and return this exact structure:\n{\n  \"sentiment\": \"Positive\" or \"Neutral\" or \"Negative\",\n  \"highlights\": [\"highlight 1\", \"highlight 2\", \"highlight 3\"],\n  \"suggestions\": [\"suggestion 1\", \"suggestion 2\"],\n  \"summary\": \"2-3 sentence summary\"\n}\n\nDo not include any text outside the JSON structure. Respond with valid JSON only."
            }
          ]
        }
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "176eab7c-6456-459b-b295-1b4952562509",
      "name": "Sticky Note - Parse Response1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -4896,
        -816
      ],
      "parameters": {
        "color": 7,
        "width": 360,
        "height": 593,
        "content": "## STEP 4: PARSE AI RESPONSE\n\n**Key Operations:**\n1. **Extracts** AI response from `message.content`\n2. **Cleans** markdown code blocks if present\n3. **Parses** JSON string to object\n4. **Validates** required fields (sentiment, highlights, suggestions, summary)\n5. **Maps** sentiment to color codes:\n   - Positive \u2192 Green (#10b981)\n   - Neutral \u2192 Orange (#f59e0b)\n   - Negative \u2192 Red (#ef4444)\n6. **Ensures** arrays are properly formatted\n7. **Merges** AI analysis with original feedback data\n\n\n**Output:**\nComplete feedback object with AI analysis ready for HTML generation."
      },
      "typeVersion": 1
    },
    {
      "id": "c4deea1d-d92a-4afa-9cb1-ff35adb28393",
      "name": "Parse AI Response1",
      "type": "n8n-nodes-base.code",
      "position": [
        -4736,
        -368
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\nconst outputItems = [];\n\nfor (let i = 0; i < items.length; i++) {\n  const feedbackData = $node[\"Clean & Normalize Data1\"].json;\n  const aiResponse = items[i].json.message.content;\n  \n  let aiAnalysis;\n  \n  try {\n    // Clean the response - remove any markdown code blocks if present\n    let cleanedResponse = aiResponse.trim();\n    \n    // Remove markdown code block markers if they exist\n    cleanedResponse = cleanedResponse.replace(/```json\\n?/g, '');\n    cleanedResponse = cleanedResponse.replace(/```\\n?/g, '');\n    cleanedResponse = cleanedResponse.trim();\n    \n    // Parse the JSON\n    aiAnalysis = JSON.parse(cleanedResponse);\n    \n    // Validate that we have all required fields\n    if (!aiAnalysis.sentiment || !aiAnalysis.highlights || !aiAnalysis.suggestions || !aiAnalysis.summary) {\n      throw new Error(\"Missing required fields in AI response\");\n    }\n    \n    console.log(\"Successfully parsed AI response as JSON\");\n    \n  } catch (e) {\n    console.log(\"Failed to parse as JSON, using fallback:\", e.message);\n    \n    // Fallback: Extract data intelligently from text\n    let sentiment = \"Neutral\";\n    const lowerResponse = aiResponse.toLowerCase();\n    \n    if (lowerResponse.includes(\"positive\") || \n        lowerResponse.includes(\"great\") || \n        lowerResponse.includes(\"excellent\")) {\n      sentiment = \"Positive\";\n    } else if (lowerResponse.includes(\"negative\") || \n               lowerResponse.includes(\"poor\") || \n               lowerResponse.includes(\"disappointed\")) {\n      sentiment = \"Negative\";\n    }\n    \n    // Create fallback structure\n    aiAnalysis = {\n      sentiment: sentiment,\n      highlights: [\n        feedbackData.comments || \"Customer provided feedback\",\n        `Rating: ${feedbackData.rating}/5 stars`\n      ],\n      suggestions: [feedbackData.suggestions || \"No specific suggestions\"],\n      summary: aiResponse.substring(0, 300)\n    };\n  }\n  \n  // Sentiment color mapping\n  const sentimentColors = {\n    'Positive': '#10b981',\n    'Neutral': '#f59e0b',\n    'Negative': '#ef4444'\n  };\n  \n  // Build output object\n  outputItems.push({\n    json: {\n      ...feedbackData,\n      aiSummary: aiAnalysis.summary,\n      sentiment: aiAnalysis.sentiment,\n      sentimentColor: sentimentColors[aiAnalysis.sentiment] || '#6b7280',\n      highlights: Array.isArray(aiAnalysis.highlights) ? aiAnalysis.highlights : [aiAnalysis.highlights],\n      aiSuggestions: Array.isArray(aiAnalysis.suggestions) ? aiAnalysis.suggestions : [aiAnalysis.suggestions]\n    }\n  });\n}\n\nreturn outputItems;"
      },
      "typeVersion": 2
    },
    {
      "id": "6c726077-7bca-4b66-864d-79074e097c2b",
      "name": "Sticky Note - HTML Generation1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -4512,
        -1008
      ],
      "parameters": {
        "color": 7,
        "width": 424,
        "height": 785,
        "content": "## STEP 5: BUILD HTML REPORT\n\n**HTML Components:**\n1. **Header Section**\n   - Gradient purple background\n   - \"\ud83d\udcca Feedback Report\" title\n   - Subtitle: \"AI-Powered Customer Feedback Analysis\"\n\n2. **User Information**\n   - Customer name (28px, bold)\n   - Email address\n   - Unique submission ID\n\n3. **Rating & Sentiment**\n   - Visual star rating (\u2605\u2605\u2605\u2605\u2606)\n   - Rating text (X out of 5 stars)\n   - Color-coded sentiment badge\n\n4. **AI Summary Section**\n   - Executive summary paragraph\n   - Easy-to-read format\n\n5. **Original Feedback**\n   - Comments box\n   - Suggestions box\n\n**Output:**\nComplete HTML string in `htmlContent` field ready for PDF conversion."
      },
      "typeVersion": 1
    },
    {
      "id": "35382397-13ee-46d0-9eaf-41aae3e4cce9",
      "name": "Build HTML Report1",
      "type": "n8n-nodes-base.code",
      "position": [
        -4320,
        -368
      ],
      "parameters": {
        "jsCode": "const data = $json;\n\n// Generate star rating HTML\nconst starRating = '\u2605'.repeat(data.rating) + '\u2606'.repeat(5 - data.rating);\n\n// Format highlights list\nconst highlightsList = data.highlights.map(h => `<li>${h}</li>`).join('');\n\n// Format AI suggestions list\nconst suggestionsList = data.aiSuggestions.length > 0 \n  ? data.aiSuggestions.map(s => `<li>${s}</li>`).join('')\n  : '<li>No additional suggestions</li>';\n\n// Generate complete HTML document\nconst html = `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <title>Feedback Report - ${data.name}</title>\n  <style>\n    * {\n      margin: 0;\n      padding: 0;\n      box-sizing: border-box;\n    }\n    \n    body {\n      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n      background: #f9fafb;\n      padding: 40px 20px;\n      line-height: 1.6;\n    }\n    \n    .container {\n      max-width: 800px;\n      margin: 0 auto;\n      background: white;\n      border-radius: 12px;\n      box-shadow: 0 4px 6px rgba(0, 0, 0, 0.07);\n      overflow: hidden;\n    }\n    \n    .header {\n      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n      color: white;\n      padding: 40px;\n      text-align: center;\n    }\n    \n    .header h1 {\n      font-size: 32px;\n      margin-bottom: 8px;\n      font-weight: 700;\n    }\n    \n    .header p {\n      opacity: 0.9;\n      font-size: 16px;\n    }\n    \n    .content {\n      padding: 40px;\n    }\n    \n    .user-info {\n      border-bottom: 2px solid #e5e7eb;\n      padding-bottom: 24px;\n      margin-bottom: 24px;\n    }\n    \n    .user-name {\n      font-size: 28px;\n      font-weight: 700;\n      color: #111827;\n      margin-bottom: 8px;\n    }\n    \n    .user-email {\n      color: #6b7280;\n      font-size: 15px;\n      margin-bottom: 8px;\n    }\n    \n    .submission-id {\n      color: #9ca3af;\n      font-size: 12px;\n      font-family: 'Courier New', monospace;\n    }\n    \n    .rating-section {\n      margin: 24px 0;\n      text-align: center;\n      padding: 24px;\n      background: #f9fafb;\n      border-radius: 8px;\n    }\n    \n    .stars {\n      font-size: 40px;\n      color: #fbbf24;\n      letter-spacing: 6px;\n      margin-bottom: 12px;\n    }\n    \n    .rating-text {\n      font-size: 18px;\n      color: #374151;\n      font-weight: 600;\n      margin-bottom: 12px;\n    }\n    \n    .sentiment-badge {\n      display: inline-block;\n      padding: 10px 20px;\n      border-radius: 24px;\n      font-weight: 600;\n      font-size: 15px;\n      color: white;\n      text-transform: uppercase;\n      letter-spacing: 0.5px;\n    }\n    \n    .section {\n      margin: 32px 0;\n    }\n    \n    .section-title {\n      font-size: 20px;\n      font-weight: 700;\n      color: #111827;\n      margin-bottom: 16px;\n      display: flex;\n      align-items: center;\n    }\n    \n    .section-title::before {\n      content: '';\n      width: 4px;\n      height: 28px;\n      background: #667eea;\n      margin-right: 12px;\n      border-radius: 2px;\n    }\n    \n    .section-content {\n      color: #374151;\n      line-height: 1.8;\n      font-size: 16px;\n    }\n    \n    .feedback-box {\n      background: #f9fafb;\n      padding: 24px;\n      border-radius: 8px;\n      border-left: 4px solid #667eea;\n      margin: 16px 0;\n    }\n    \n    .feedback-box strong {\n      color: #111827;\n      display: block;\n      margin-bottom: 8px;\n      font-size: 14px;\n      text-transform: uppercase;\n      letter-spacing: 0.5px;\n    }\n    \n    ul {\n      list-style: none;\n      padding-left: 0;\n    }\n    \n    ul li {\n      padding: 12px 0;\n      padding-left: 32px;\n      position: relative;\n      color: #374151;\n      line-height: 1.6;\n    }\n    \n    ul li::before {\n      content: '\u25cf';\n      color: #667eea;\n      font-weight: bold;\n      font-size: 24px;\n      position: absolute;\n      left: 0;\n      top: 8px;\n    }\n    \n    .footer {\n      background: #f9fafb;\n      padding: 32px 40px;\n      text-align: center;\n      color: #6b7280;\n      font-size: 14px;\n      border-top: 1px solid #e5e7eb;\n    }\n    \n    .footer p {\n      margin: 4px 0;\n    }\n    \n    .footer strong {\n      color: #111827;\n    }\n    \n    @media print {\n      body {\n        padding: 0;\n        background: white;\n      }\n      \n      .container {\n        box-shadow: none;\n      }\n    }\n  </style>\n</head>\n<body>\n  <div class=\"container\">\n    <div class=\"header\">\n      <h1>\ud83d\udcca Feedback Report</h1>\n      <p>AI-Powered Customer Feedback Analysis</p>\n    </div>\n    \n    <div class=\"content\">\n      <!-- User Information -->\n      <div class=\"user-info\">\n        <div class=\"user-name\">${data.name}</div>\n        <div class=\"user-email\">${data.email || 'No email provided'}</div>\n        <div class=\"submission-id\">Submission ID: ${data.submissionId}</div>\n      </div>\n      \n      <!-- Rating and Sentiment -->\n      <div class=\"rating-section\">\n        <div class=\"stars\">${starRating}</div>\n        <div class=\"rating-text\">${data.rating} out of 5 stars</div>\n        <div class=\"sentiment-badge\" style=\"background-color: ${data.sentimentColor};\">\n          ${data.sentiment} Feedback\n        </div>\n      </div>\n      \n      <!-- AI Summary -->\n      <div class=\"section\">\n        <div class=\"section-title\">AI Summary</div>\n        <div class=\"section-content\">${data.aiSummary}</div>\n      </div>\n      \n      <!-- Key Highlights -->\n      <div class=\"section\">\n        <div class=\"section-title\">Key Highlights</div>\n        <ul>${highlightsList}</ul>\n      </div>\n      \n      <!-- Original Feedback -->\n      <div class=\"section\">\n        <div class=\"section-title\">Original Feedback</div>\n        <div class=\"feedback-box\">\n          <strong>Comments</strong>\n          ${data.comments}\n        </div>\n        <div class=\"feedback-box\">\n          <strong>Suggestions</strong>\n          ${data.suggestions}\n        </div>\n      </div>\n      \n      <!-- AI Recommendations -->\n      ${data.aiSuggestions.length > 0 ? `\n      <div class=\"section\">\n        <div class=\"section-title\">Recommended Actions</div>\n        <ul>${suggestionsList}</ul>\n      </div>\n      ` : ''}\n    </div>\n    \n    <div class=\"footer\">\n      <p><strong>Report Generated:</strong> ${new Date(data.timestamp).toLocaleString('en-US', { \n        weekday: 'long', \n        year: 'numeric', \n        month: 'long', \n        day: 'numeric',\n        hour: '2-digit',\n        minute: '2-digit'\n      })}</p>\n      <p style=\"margin-top: 16px;\">Thank you for your valuable feedback! \ud83d\ude4f</p>\n    </div>\n  </div>\n</body>\n</html>\n`;\n\n// Return the HTML content along with all data\nreturn [{\n  json: {\n    ...data,\n    htmlContent: html\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "06215d6b-d83c-4ef6-9560-6bad2005f079",
      "name": "Sticky Note - PDF Generation1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -4064,
        -784
      ],
      "parameters": {
        "color": 7,
        "width": 376,
        "height": 561,
        "content": "## STEP 6: GENERATE PDF\n\n**API Response:**\n```json\n{\n  \"success\": true,\n  \"pdf_url\": \"https://generated-image.s3.ap-south-1.amazonaws.com/pdfs/[uuid].pdf\",\n  \"file_size_bytes\": 136164,\n  \"file_deletion_date\": \"2025-11-09\",\n  \"source_type\": \"html\"\n}\n```\n\n**Output:**\n- PDF URL (hosted on AWS S3)\n- File size in bytes\n- Expiration date (30 days from generation)\n- Success status"
      },
      "typeVersion": 1
    },
    {
      "id": "d10efd0f-df5c-43f1-b744-4287a0d32a02",
      "name": "Sticky Note - Process PDF1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3664,
        -688
      ],
      "parameters": {
        "color": 7,
        "width": 392,
        "height": 465,
        "content": "## STEP 7: MERGE PDF METADATA\n\n**Key Operations:**\n1. **Retrieves** previous feedback data from \"Build HTML Report\" node\n2. **Extracts** PDF metadata from current node:\n   - pdf_url: Direct link to generated PDF\n   - file_size_bytes: PDF file size\n   - file_deletion_date: When PDF expires (30 days)\n3. **Generates** descriptive filename: `Feedback-Report-[SubmissionID].pdf`\n4. **Adds** `pdfReady: true` flag for downstream nodes\n5. **Merges** all data into single JSON object\n"
      },
      "typeVersion": 1
    },
    {
      "id": "ede437b3-bbcc-4ac4-8848-d92d7a351cf8",
      "name": "Process PDF Response1",
      "type": "n8n-nodes-base.code",
      "position": [
        -3552,
        -368
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\nconst previousData = $node[\"Build HTML Report1\"].json;\nconst pdfInfo = items[0].json; // This is the output from HTML to PDF node\n\nreturn [{\n  json: {\n    ...previousData,\n    pdfUrl: pdfInfo.pdf_url,\n    pdfFileSize: pdfInfo.file_size_bytes,\n    pdfDeletionDate: pdfInfo.file_deletion_date,\n    pdfFileName: `Feedback-Report-${previousData.submissionId}.pdf`,\n    pdfReady: true\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "8f4b800d-8889-46c8-8fb0-234d4728f6b4",
      "name": "Sticky Note - Email Validation1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3232,
        -672
      ],
      "parameters": {
        "color": 7,
        "width": 392,
        "height": 434,
        "content": "## STEP 8: EMAIL VALIDATION CHECK\n\n**Condition:**\n- Checks: `hasValidEmail` boolean flag\n- Operation: Equals `true`\n\n**\ud83d\udfe2 TRUE Branch (Valid Email):**\n- Routes to \"Email User Report\" node\n- Sends personalized email with PDF link\n- User receives thank you message\n- Then proceeds to logging\n"
      },
      "typeVersion": 1
    },
    {
      "id": "171bdb6d-4c98-49d9-9928-0f7c11a0eb57",
      "name": "Check Valid Email1",
      "type": "n8n-nodes-base.if",
      "position": [
        -3136,
        -368
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "1668e9a2-47cc-4a7b-8dd2-29de8771f4c5",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.hasValidEmail }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "70c0fcc0-cb4b-4ffc-8a5a-bab1f0e71c3e",
      "name": "Email User Report1",
      "type": "n8n-nodes-base.gmail",
      "position": [
        -2688,
        -384
      ],
      "parameters": {
        "sendTo": "={{ $json.email }}",
        "message": "=<div style=\"font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px;\">\n  <div style=\"text-align: center; margin-bottom: 32px;\">\n    <h1 style=\"color: #667eea; margin: 0; font-size: 28px;\">Thank You for Your Feedback! \ud83c\udf89</h1>\n  </div>\n  \n  <p style=\"font-size: 16px; line-height: 1.6;\">Hi <strong>{{ $json.name }}</strong>,</p>\n  \n  <p style=\"font-size: 16px; line-height: 1.6;\">Thank you for taking the time to share your thoughts with us. Your feedback is invaluable in helping us improve our services.</p>\n  \n  <div style=\"background: linear-gradient(135deg, #667eea15 0%, #764ba215 100%); padding: 24px; border-radius: 12px; margin: 32px 0; border-left: 4px solid {{ $json.sentimentColor }};\">\n    <p style=\"margin: 0; font-size: 16px;\"><strong>\ud83d\udcca Your Rating:</strong>{{ $json.rating }}/5</p>\n    <p style=\"margin: 12px 0 0 0; font-size: 16px;\"><strong>\ud83d\udcad Sentiment:</strong> <span style=\"color: {{ $json.sentimentColor }}; font-weight: 700;\">{{ $json.sentiment }}</span></p>\n  </div>\n  \n  <div style=\"background: #f9fafb; padding: 20px; border-radius: 8px; margin: 24px 0;\">\n    <p style=\"margin: 0 0 12px 0; font-weight: 600; color: #111827;\">\ud83d\udcc4 Your Personalized Feedback Report</p>\n    <p style=\"margin: 0 0 16px 0; font-size: 14px; line-height: 1.6; color: #6b7280;\">We've prepared a detailed AI-powered analysis of your feedback including key highlights, sentiment analysis, and recommended actions.</p>\n    <a href=\"{{ $json.pdfUrl }}\" style=\"display: inline-block; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 14px 28px; border-radius: 8px; text-decoration: none; font-weight: 600; font-size: 16px;\">\ud83d\udce5 Download Your Report</a>\n    <p style=\"margin: 12px 0 0 0; font-size: 12px; color: #9ca3af;\">\u23f0 Report available until: {{ $json.pdfDeletionDate }}</p>\n  </div>\n  \n  <div style=\"background: white; border: 1px solid #e5e7eb; padding: 20px; border-radius: 8px; margin: 24px 0;\">\n    <p style=\"margin: 0 0 8px 0; font-weight: 600; color: #111827;\">\u2728 Your Report Includes:</p>\n    <ul style=\"margin: 0; padding-left: 20px; line-height: 1.8; color: #374151;\">\n      <li>AI-generated summary of your feedback</li>\n      <li>Key highlights and main points</li>\n      <li>Sentiment analysis with visual indicators</li>\n      <li>Actionable recommendations based on your input</li>\n      <li>Complete feedback history</li>\n    </ul>\n  </div>\n  \n  <p style=\"font-size: 16px; line-height: 1.6;\">If you have any questions or would like to discuss your feedback further, please don't hesitate to reach out. We're here to help!</p>\n  \n  <div style=\"margin-top: 40px; padding-top: 24px; border-top: 2px solid #e5e7eb;\">\n    <p style=\"margin: 0; font-size: 16px;\">Warm regards,</p>\n    <p style=\"margin: 4px 0 0 0; font-size: 18px; font-weight: 700; color: #667eea;\">The Team</p>\n  </div>\n  \n  <div style=\"margin-top: 32px; padding: 20px; background: #f9fafb; border-radius: 8px; text-align: center;\">\n    <p style=\"margin: 0; font-size: 12px; color: #6b7280;\">Submission ID: <code style=\"background: #e5e7eb; padding: 2px 8px; border-radius: 4px; font-family: monospace;\">{{ $json.submissionId }}</code></p>\n    <p style=\"margin: 8px 0 0 0; font-size: 12px; color: #9ca3af;\">Generated on {{ new Date($json.timestamp).toLocaleString() }}</p>\n  </div>\n</div>",
        "options": {},
        "subject": "Your Feedback Summary Report \u2013 Thank You for Sharing!"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "f9b4ca97-21e0-4a4f-9b42-43e1390a87c8",
      "name": "Sticky Note - Log Data1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2480,
        -768
      ],
      "parameters": {
        "color": 7,
        "width": 424,
        "height": 546,
        "content": "## STEP 10: LOG TO GOOGLE SHEETS\n\n\n**Columns Logged:**\n1. **Submission ID** - Unique identifier\n2. **Timestamp** - ISO 8601 date/time\n3. **Name** - Customer name\n4. **Email** - Customer email\n5. **Rating** - 1-5 star rating\n6. **Sentiment** - Positive/Neutral/Negative\n7. **Comments** - Original feedback text\n8. **Suggestions** - Customer suggestions\n9. **AI Summary** - Generated summary\n10. **PDF URL** - Link to report\n11. **PDF Available Until** - Expiration date\n12. **Email Sent** - Yes/No tracking"
      },
      "typeVersion": 1
    },
    {
      "id": "1d12b1e5-a8cb-436a-8a7f-4e093faaf42b",
      "name": "Log Feedback Data1",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -2336,
        -384
      ],
      "parameters": {
        "columns": {
          "value": {
            "Name": "={{ $('Check Valid Email1').item.json.name }}",
            "Email": "={{ $('Check Valid Email1').item.json.email }}",
            "Rating": "={{ $('Check Valid Email1').item.json.rating }}",
            "PDF URL": "={{ $('Check Valid Email1').item.json.pdfUrl }}",
            "Comments": "={{ $('Check Valid Email1').item.json.comments }}",
            "Sentiment": "={{ $('Check Valid Email1').item.json.sentiment }}",
            "Timestamp": "={{ $('Check Valid Email1').item.json.timestamp }}",
            "AI Summary": "={{ $('Check Valid Email1').item.json.aiSummary }}",
            "Email Sent": "={{ $('Check Valid Email1').item.json.hasValidEmail ? 'Yes' : 'No' }}",
            "Suggestions": "={{ $('Check Valid Email1').item.json.suggestions }}",
            "Submission ID": "={{ $('Check Valid Email1').item.json.submissionId }}",
            "PDF Available Until": "={{ $('Check Valid Email1').item.json.pdfDeletionDate }}"
          },
          "schema": [
            {
              "id": "Submission ID",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Submission ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Timestamp",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Rating",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Rating",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Sentiment",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Sentiment",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Comments",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Comments",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Suggestions",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Suggestions",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "AI Summary",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "AI Summary",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "PDF Available Until",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "PDF Available Until",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "PDF URL",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "PDF URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email Sent",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Email Sent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Submission ID"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_GOOGLE_SHEET_ID",
          "cachedResultUrl": "",
          "cachedResultName": "Feedback Log"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "c0c1f555-140d-448f-ba78-399971e374a6",
      "name": "Sticky Note - Team Alert1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2032,
        -800
      ],
      "parameters": {
        "color": 7,
        "width": 520,
        "height": 578,
        "content": "## STEP 11: SLACK TEAM NOTIFICATION\n\n**Message Contents:**\n1. **Header** - \"\ud83c\udd95 New Feedback Received!\"\n2. **Customer Info**\n   - Name\n   - Email address\n3. **Feedback Metrics**\n   - Star rating (X/5 \u2b50)\n   - Sentiment (Positive/Neutral/Negative)\n4. **AI Summary** - Quick overview\n5. **Key Highlights** - Top 2 points from AI analysis\n6. **Recommended Actions** - AI suggestions\n7. **PDF Link** - Direct link to full report\n8. **Footer** - Submission ID & confirmation of logging\n\n**Alternative:** Can use Teams, Discord, or email notifications instead."
      },
      "typeVersion": 1
    },
    {
      "id": "6deba6a0-a406-4865-8254-694ab11bd1e0",
      "name": "Notify Team1",
      "type": "n8n-nodes-base.slack",
      "position": [
        -1920,
        -384
      ],
      "parameters": {
        "text": "=\ud83c\udd95 *New Feedback Received!*\n\n*Customer:* {{ $json.Name }}\n*Email:* {{ $json.Email }}\n*Rating:* {{ $json.Rating }}/5 \u2b50\n*Sentiment:* {{ $json.Sentiment }}\n\n*AI Summary:*\n{{ $json['AI Summary'] }}\n\n*Key Highlights:*\n- {{ $('Check Valid Email1').item.json.highlights[0] }}\n- {{ $('Check Valid Email1').item.json.highlights[1] }}\n\n*Recommended Actions:*\n- {{ $('Check Valid Email1').item.json.aiSuggestions[0] }}\n- {{ $('Check Valid Email1').item.json.aiSuggestions[1] }}\n\n\ud83d\udcc4 *View Full Report:* {{ $json['PDF URL'] }}\n\n_Submission ID: {{ $json['Submission ID'] }}_\n_\u2705 Logged to tracking sheet_",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_SLACK_CHANNEL_ID",
          "cachedResultName": "feedback-notifications"
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "a569c084-e6ac-4ca0-8060-f952fa7e0589",
      "name": "Sticky Note - Final Response1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1472,
        -864
      ],
      "parameters": {
        "color": 7,
        "width": 568,
        "height": 642,
        "content": "## STEP 12: WEBHOOK RESPONSE\n\n**Response Structure:**\n```json\n{\n  \"success\": true,\n  \"message\": \"Thank you for your feedback! We've sent you a detailed report via email.\",\n  \"data\": {\n    \"submissionId\": \"FB-xxx\",\n    \"name\": \"Customer Name\",\n    \"email\": \"customer@email.com\",\n    \"rating\": 4,\n    \"sentiment\": \"Positive\",\n    \"emailSent\": true,\n    \"reportUrl\": \"https://...\",\n    \"reportAvailableUntil\": \"2025-11-09\"\n  }\n}\n```\n\n**Use Case:**\nIf integrating with custom forms, this response can trigger:\n- Success confirmation page\n- Download PDF button\n- Redirect to thank you page\n- Track submission in analytics\n"
      },
      "typeVersion": 1
    },
    {
      "id": "3b59493a-e441-49ac-9627-9dd157254c3f",
      "name": "Send Success Response1",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        -1184,
        -384
      ],
      "parameters": {
        "options": {
          "responseCode": 200
        },
        "respondWith": "json",
        "responseBody": "={\n  \"success\": true,\n  \"message\": \"Thank you for your feedback! We've sent you a detailed report via email.\",\n  \"data\": {\n    \"submissionId\": \"={{ $('Log Feedback Data1').item.json['Submission ID'] }}\",\n    \"name\": \"={{ $('Log Feedback Data1').item.json.Name }}\",\n    \"email\": \"={{ $('Log Feedback Data1').item.json.Email }}\",\n    \"rating\": \"={{ $('Log Feedback Data1').item.json.Rating }}\",\n    \"sentiment\": \"={{ $('Log Feedback Data1').item.json.Sentiment }}\",\n    \"emailSent\": \"={{ $('Check Valid Email1').item.json.hasValidEmail }}\",\n    \"reportUrl\": \"={{ $('Check Valid Email1').item.json.pdfUrl }}\",\n    \"reportAvailableUntil\": \"={{ $('Check Valid Email1').item.json.pdfDeletionDate }}\"\n  } \n}\n"
      },
      "typeVersion": 1.1
    },
    {
      "id": "0fc941d8-3ae3-4334-aaad-456b75177c35",
      "name": "Sticky Note - Testing Guide1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -6768,
        -880
      ],
      "parameters": {
        "color": 7,
        "width": 549,
        "height": 600,
        "content": "## \ud83d\ude80 TESTING YOUR WORKFLOW\n\n**Step-by-Step Testing Guide:**\n\n**1. Initial Setup**\n- \u2705 Verify all credentials are configured\n- \u2705 Check Google Sheet has correct columns\n- \u2705 Confirm Slack bot is in channel\n- \u2705 Test webhook URL is active\n\n**2. Test Data**\nUse this JSON in Postman/curl:\n```json\n{\n  \"name\": \"Sarah Johnson\",\n  \"email\": \"your-email@example.com\",\n  \"rating\": 4,\n  \"comments\": \"Great product! Delivery was slow but customer service was helpful.\",\n  \"suggestions\": \"Improve shipping speed and tracking updates.\"\n}\n```\n\n**3. Execution Steps**\n- Execute \"Webhook\" node to get test URL\n- Send POST request with test data\n- Watch nodes execute sequentially\n- Check for green checkmarks on all nodes\n"
      },
      "typeVersion": 1
    },
    {
      "id": "749a54d2-50ac-40ab-b3a0-792e9fdc4387",
      "name": "HTML to PDF1",
      "type": "n8n-nodes-htmlcsstopdf.htmlcsstopdf",
      "position": [
        -3936,
        -368
      ],
      "parameters": {
        "html_content": "={{ $json.htmlContent }}"
      },
      "credentials": {
        "htmlcsstopdfApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "f210d49f-ebe2-4e23-823e-e29412a330e8",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2800,
        -528
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 304,
        "content": "## STEP 9:EMAIL USER REPORT\n\nSends an email user report to the email id of the user"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "",
  "connections": {
    "HTML to PDF1": {
      "main": [
        [
          {
            "node": "Process PDF Response1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Notify Team1": {
      "main": [
        [
          {
            "node": "Send Success Response1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build HTML Report1": {
      "main": [
        [
          {
            "node": "HTML to PDF1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Valid Email1": {
      "main": [
        [
          {
            "node": "Email User Report1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Email User Report1": {
      "main": [
        [
          {
            "node": "Log Feedback Data1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Feedback Data1": {
      "main": [
        [
          {
            "node": "Notify Team1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse AI Response1": {
      "main": [
        [
          {
            "node": "Build HTML Report1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate AI Summary1": {
      "main": [
        [
          {
            "node": "Parse AI Response1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process PDF Response1": {
      "main": [
        [
          {
            "node": "Check Valid Email1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Clean & Normalize Data1": {
      "main": [
        [
          {
            "node": "Generate AI Summary1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook - Receive Feedback1": {
      "main": [
        [
          {
            "node": "Clean & Normalize Data1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}