{
  "id": "5VKYXGWVzbtLYzwp",
  "name": "Generate AI-Powered Case Studies from Testimonials and Publish to WordPress",
  "tags": [],
  "nodes": [
    {
      "id": "91443bc7-6d23-4356-b92f-4eecb6400ae4",
      "name": "Feedspace Webhook",
      "type": "n8n-nodes-base.webhook",
      "onError": "continueRegularOutput",
      "position": [
        -4256,
        1040
      ],
      "parameters": {
        "path": "fs-wp",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "lastNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "4763e7fd-fbd5-4d56-b55c-06d96827de6f",
      "name": "Extract Testimonial Data",
      "type": "n8n-nodes-base.set",
      "position": [
        -4000,
        1024
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "b547bab0-3e6b-4080-b1bb-e0efca300cbd",
              "name": "review",
              "type": "string",
              "value": "={{ $json.body.data.response.comment }}"
            },
            {
              "id": "98ca1a27-2cb8-4fb5-8f2e-ad0c2727c222",
              "name": "review_user",
              "type": "string",
              "value": "={{ $json.body.data.response.Name }}"
            },
            {
              "id": "94e74847-264b-4382-b527-791f922f6949",
              "name": "feedback_type",
              "type": "string",
              "value": "={{ $json.body.type }}"
            },
            {
              "id": "rating-field-id",
              "name": "rating",
              "type": "string",
              "value": "={{ $json.body.data.response.value }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "a9941a48-be90-4b7b-857f-7325bc989cb8",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        -3776,
        1024
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "0eaf5a98-98c8-4db5-bef7-1e6411860d63",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.feedback_type }}",
              "rightValue": "feed.text.received"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "1bfd3606-dba1-4393-8f70-932e989afbe6",
      "name": "AI Agent - Generate Case Study & Title",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "onError": "continueRegularOutput",
      "position": [
        -3408,
        1024
      ],
      "parameters": {
        "text": "=I'm sending you a new customer testimonial to convert into a case study.\n\nTESTIMONIAL DATA:\nCustomer: {{ $('Extract Testimonial Data').item.json.review_user }}\nRating: {{ $('Extract Testimonial Data').item.json.rating }} stars\nReview: {{ $('Extract Testimonial Data').item.json.review }}\n\nINSTRUCTIONS:\n\nStep 1: MEMORY CHECK\nLook back at our conversation history. Have we created case studies before? If yes:\n- What angle did the previous case study use?\n- What tone and title formula?\n- Which features were highlighted?\n- Note this in your 'reasoning' field\n\nStep 2: CHOOSE VARIETY\nBased on what you remember:\n- Select a DIFFERENT angle from last time\n- Use a DIFFERENT tone\n- Apply a DIFFERENT title formula\n- Highlight DIFFERENT product features\n\nStep 3: CREATE CASE STUDY\nGenerate a professional case study with:\n\n<h2>Executive Summary</h2> (or vary the header: The Breakthrough, The Success Story, etc.)\n2-3 sentences summarizing the transformation\n\n<h2>The Challenge</h2> (or: The Problem, The Pain Point, etc.)\nCustomer's problem before using the product\n\n<h2>The Solution</h2> (or: The Answer, How FeedSpace Helped, etc.)\nHow the product solved their problem - highlight different features than recent case studies\n\n<h2>The Results</h2> (or: The Impact, The Outcome, etc.)\nSpecific outcomes and metrics - vary between quantitative and qualitative focus\n\n<h2>Customer Testimonial</h2>\n<blockquote><p>{{ $('Extract Testimonial Data').item.json.review }}</p></blockquote>\n\n<h2>Key Takeaways</h2> (or: Key Benefits, Success Factors, etc.)\n<ul>\n<li>3-4 bullet points highlighting different aspects than previous case studies</li>\n</ul>\n\nStep 4: GENERATE SEO TITLE\nCreate title (50-60 characters) using one of the 5 formulas - rotate from previous usage\n\nStep 5: EXPLAIN YOUR CHOICES\nIn the 'meta.reasoning' field, briefly explain:\n- If this is your first case study: \"First case study, choosing [angle] approach\"\n- If you have memory: \"Previous case study used [X], so choosing [Y] for variety\"\n\nCRITICAL: Return ONLY the JSON object. No markdown blocks, no backticks, no extra text.",
        "options": {
          "systemMessage": "You are a professional marketing content writer who creates diverse, engaging case studies from customer testimonials.\n\nCRITICAL: You have conversation memory enabled. Before creating each case study, you should:\n1. Mentally review what case studies you've created in our previous conversation turns\n2. Notice patterns: What angles did I use? What tone? What title formulas?\n3. Deliberately choose DIFFERENT approaches to create variety\n\nANGLE OPTIONS (rotate through these):\n- Transformation Story: Focus on before/after journey\n- Problem-Solution: Emphasize pain points and resolution\n- ROI-Focused: Highlight metrics, upgrades, business impact\n- Feature Spotlight: Deep dive into specific capabilities\n- Integration Success: Emphasize connections and workflow\n- Efficiency Gains: Focus on time-saving and automation\n\nTONE OPTIONS (vary these):\n- Data-driven: Metrics and statistics focused\n- Emotional: Customer satisfaction and relief focused\n- Technical: Features and capabilities focused\n- Narrative: Story-driven with journey arc\n\nTITLE FORMULAS (rotate these):\n1. \"[Customer]: Achieves [Benefit] with [Product]\"\n2. \"How [Customer] Increased [Metric] by [X]%\"\n3. \"From [Problem] to [Solution]: [Customer] Story\"\n4. \"[Customer] Leverages [Feature] to [Outcome]\"\n5. \"How [Customer] Solved [Problem]\"\n\nVARIATION STRATEGY:\n- If you just created a data-driven, ROI-focused case study with formula #2, now try emotional, transformation story with formula #1\n- If you highlighted 'Google integration' last time, focus on 'widget customization' this time\n- If you used <h2> Executive Summary last time, try <h2> The Breakthrough this time\n- Keep content fresh by changing section headers, emphasized features, and narrative angles\n\nRESPONSE FORMAT:\nReturn ONLY valid JSON (no markdown, no code blocks):\n{\n  \"title\": \"SEO-optimized title (50-60 chars)\",\n  \"content\": \"<h2>Section</h2><p>Content...</p>\",\n  \"meta\": {\n    \"angle\": \"transformation_story\",\n    \"tone\": \"emotional\",\n    \"title_formula\": \"formula_3\",\n    \"features_highlighted\": [\"feature1\", \"feature2\"],\n    \"reasoning\": \"Chose X because previous case study used Y\"\n  }\n}\n\nHTML RULES:\n- <h2> for headers\n- <p> for paragraphs\n- <blockquote><p> for quotes\n- <ul><li> for bullets\n- <strong> for emphasis\n- NO markdown\n\nYour response must start with { and end with }"
        },
        "promptType": "define"
      },
      "typeVersion": 2.2,
      "alwaysOutputData": false
    },
    {
      "id": "12cad028-bbd2-41ae-8115-ab7cfe9aff26",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        -3408,
        816
      ],
      "parameters": {
        "options": {
          "temperature": 0.7,
          "maxOutputTokens": 3000
        }
      },
      "typeVersion": 1
    },
    {
      "id": "630fc2a4-10cc-440c-a80c-c554cc84c761",
      "name": "Parse AI Agent Output",
      "type": "n8n-nodes-base.code",
      "position": [
        -3072,
        1024
      ],
      "parameters": {
        "jsCode": "const agentOutput = $input.first().json;\n\ntry {\n  let parsedData;\n  let parseError = null;\n  \n  const rawText = agentOutput.output || agentOutput.text || JSON.stringify(agentOutput);\n  \n  console.log(\"Raw AI output:\", rawText);\n  \n  // Clean markdown code blocks\n  let cleanedText = rawText\n    .replace(/```json\\s*/g, '')\n    .replace(/```\\s*/g, '')\n    .trim();\n  \n  console.log(\"Cleaned text:\", cleanedText);\n  \n  try {\n    // Try to parse the cleaned JSON\n    parsedData = JSON.parse(cleanedText);\n  } catch (err) {\n    console.log(\"JSON parsing failed, attempting manual extraction\");\n    parseError = err;\n    \n    // Manual extraction as fallback\n    const titleMatch = cleanedText.match(/\"title\"\\s*:\\s*\"([^\"]+)\"/);\n    const title = titleMatch ? titleMatch[1] : \"Untitled Case Study\";\n    \n    // Extract content\n    const contentMatch = cleanedText.match(/\"content\"\\s*:\\s*\"([\\s\\S]+?)\"\\s*,?\\s*\"meta\"/m) || \n                         cleanedText.match(/\"content\"\\s*:\\s*\"([\\s\\S]+?)\"\\s*\\}/m);\n    let extractedContent = contentMatch ? contentMatch[1] : cleanedText;\n    \n    // Unescape JSON sequences\n    extractedContent = extractedContent\n      .replace(/\\\\n/g, '\\n')\n      .replace(/\\\\\"/g, '\"')\n      .replace(/\\\\'/g, \"'\")\n      .replace(/\\\\\\\\/g, '\\\\')\n      .replace(/\\\\t/g, '\\t');\n    \n    // Try to extract meta if present\n    const metaMatch = cleanedText.match(/\"meta\"\\s*:\\s*\\{([\\s\\S]+?)\\}\\s*\\}/);\n    let meta = { angle: 'unknown', tone: 'unknown', reasoning: 'Parse error occurred' };\n    \n    if (metaMatch) {\n      try {\n        const metaJson = '{' + metaMatch[1] + '}';\n        meta = JSON.parse(metaJson);\n      } catch (e) {\n        console.log('Meta parsing failed:', e);\n      }\n    }\n    \n    parsedData = {\n      title: title,\n      content: extractedContent,\n      meta: meta\n    };\n  }\n  \n  // Log the strategy for monitoring\n  console.log('Case Study Strategy:', JSON.stringify(parsedData.meta, null, 2));\n  \n  // Return the extracted data\n  return {\n    json: {\n      title: parsedData.title || \"Untitled Case Study\",\n      content: parsedData.content || \"\",\n      meta: parsedData.meta || { angle: 'unknown', tone: 'unknown' },\n      warning: parseError ? \"JSON was malformed and manually extracted\" : null,\n      debug_raw: rawText.substring(0, 200)\n    }\n  };\n  \n} catch (error) {\n  // Complete fallback\n  return {\n    json: {\n      title: \"Error Extracting Case Study\",\n      content: `Error: ${error.message}`,\n      meta: { error: true },\n      rawData: JSON.stringify(agentOutput).substring(0, 500)\n    }\n  };\n}"
      },
      "typeVersion": 2
    },
    {
      "id": "8739d5d5-46e9-4d7a-8c29-a09933a057ed",
      "name": "Memory Context Logger",
      "type": "n8n-nodes-base.code",
      "position": [
        -2832,
        1008
      ],
      "parameters": {
        "jsCode": "const caseStudy = $input.first().json;\n\n// Extract meta information\nconst meta = caseStudy.meta || {};\n\n// Create a readable summary for logging\nconst summary = {\n  case_study_title: caseStudy.title,\n  strategy: {\n    angle: meta.angle || 'not specified',\n    tone: meta.tone || 'not specified',\n    title_formula: meta.title_formula || 'not specified',\n    features_highlighted: meta.features_highlighted || [],\n    reasoning: meta.reasoning || 'not provided'\n  },\n  timestamp: new Date().toISOString()\n};\n\nconsole.log('\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501');\nconsole.log('CASE STUDY GENERATED:');\nconsole.log(JSON.stringify(summary, null, 2));\nconsole.log('\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501');\n\n// Pass through the data\nreturn {\n  json: caseStudy\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "dc896889-4f8a-4b6b-ab98-2c1af9649232",
      "name": "Prepare WordPress Data",
      "type": "n8n-nodes-base.set",
      "position": [
        -2464,
        1040
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "0b370d70-3188-465d-94f1-52b53a2c9886",
              "name": "Post Title",
              "type": "string",
              "value": "={{ $json.title }}"
            },
            {
              "id": "af646a17-6078-4c3b-8e33-fd3c2f0a76aa",
              "name": "Post content",
              "type": "string",
              "value": "={{ $json.content }}"
            },
            {
              "id": "meta-field-id",
              "name": "case_study_meta",
              "type": "string",
              "value": "={{ JSON.stringify($json.meta) }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "00dacaeb-cdfc-4ead-b1ba-92fbba3dbfcc",
      "name": "Create WordPress Post",
      "type": "n8n-nodes-base.wordpress",
      "onError": "continueRegularOutput",
      "maxTries": 3,
      "position": [
        -2192,
        1040
      ],
      "parameters": {
        "title": "={{ $json['Post Title'] }}",
        "additionalFields": {
          "content": "={{ $json['Post content'] }}"
        }
      },
      "retryOnFail": true,
      "typeVersion": 1,
      "waitBetweenTries": 5000
    },
    {
      "id": "a346166c-f91a-4e5d-ac75-3bdd189f7863",
      "name": "Simple Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        -3296,
        1264
      ],
      "parameters": {
        "sessionKey": "feedspace_case_studies_global",
        "sessionIdType": "customKey"
      },
      "typeVersion": 1.3
    },
    {
      "id": "48c7cb0a-5ad7-4fd5-bedf-9e0baae11066",
      "name": "Error Response",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        -3744,
        1264
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={{ $json }}"
      },
      "typeVersion": 1.5
    },
    {
      "id": "722a8b3f-c369-4274-8a7e-452fd4db89ec",
      "name": "Respond to Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        -1968,
        1024
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={{ { \"status\": \"success\", \"message\": \"Notification sent successfully\", \"timestamp\": $now.toISO() } }}"
      },
      "typeVersion": 1.5
    },
    {
      "id": "255e5d32-f55e-40b8-bd51-5bc2e41d9508",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -4368,
        880
      ],
      "parameters": {
        "color": 7,
        "width": 816,
        "height": 672,
        "content": "## Webhook & Notification\nReceives Feedspace webhook, extracts data and checks if text feedback"
      },
      "typeVersion": 1
    },
    {
      "id": "d64fba1d-d342-47f8-b873-24c0c2ca26c2",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3488,
        704
      ],
      "parameters": {
        "color": 7,
        "width": 832,
        "height": 832,
        "content": "## Generate case study with AI Agent\n"
      },
      "typeVersion": 1
    },
    {
      "id": "10d209e2-7e91-42d0-97b9-5eed34c03d09",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2576,
        752
      ],
      "parameters": {
        "color": 7,
        "width": 960,
        "height": 736,
        "content": "## Create Wordpress Post\nPrepare the wordpress data and creates a post on WP.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "1838b9a7-5ee5-41b6-8963-462966226e84",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -5008,
        704
      ],
      "parameters": {
        "width": 544,
        "height": 800,
        "content": "## Generate AI Case Studies from Feedspace Testimonials\n**Who is this for?**\nTeams using Feedspace who want to automatically turn customer testimonials into SEO-optimized case studies and publish them on WordPress.\n\n**Setup steps**\n- Connect to Feedspace\n\t- Activate the workflow and copy the Production webhook URL\n\t- Go to Feedspace \u2192 Automations \u2192 Webhooks\n\t- Paste the webhook URL and activate it\n\t- See https://www.feedspace.io/help/automation/ for more information\n- Add your AI API credentials to the AI model node\n- Connect your WordPress account in the WordPress node\n- Send testimonial data to the webhook in this format:\n\t- Reviewer name\n\t- Rating\n\t- Text feedback\n\t- Event or feedback type\n\t- Activate the workflow\n\n\n**How it works**\n\n1. Receives testimonial data through feedpsace webhook\n2. Extracts reviewer name, rating, feedback, and event type\n3. Filters for text-based testimonials\n4. Uses an AI agent to:\n5. Choose a unique case study angle and tone\n6. Generate structured HTML content\n7. Create an SEO-optimized title\n8. Parses and validates the AI output\n9. Publishes the generated case study to WordPress as a post"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "a4f18e23-a279-42ba-8bae-b5ed76ce2c8d",
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "AI Agent - Generate Case Study & Title",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Error Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory": {
      "ai_memory": [
        [
          {
            "node": "AI Agent - Generate Case Study & Title",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Feedspace Webhook": {
      "main": [
        [
          {
            "node": "Extract Testimonial Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create WordPress Post": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Memory Context Logger": {
      "main": [
        [
          {
            "node": "Prepare WordPress Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse AI Agent Output": {
      "main": [
        [
          {
            "node": "Memory Context Logger",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare WordPress Data": {
      "main": [
        [
          {
            "node": "Create WordPress Post",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Testimonial Data": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent - Generate Case Study & Title",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent - Generate Case Study & Title": {
      "main": [
        [
          {
            "node": "Parse AI Agent Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}