AutomationFlowsAI & RAG › Generate Conference Synthetic Personas with Slack, Gemini and Salesforce

Generate Conference Synthetic Personas with Slack, Gemini and Salesforce

ByMilo Bravo @milobravo1 on n8n.io

Who is this for? Event strategists, conference organizers, and marketing teams planning content/networking who want to interview realistic audience personas based on their participantants behavioural data before spending budget. What problem is this workflow solving? Event…

Webhook trigger★★★★☆ complexityAI-powered27 nodesHTTP RequestGoogle SheetsChain LlmGoogle Gemini ChatSlack
AI & RAG Trigger: Webhook Nodes: 27 Complexity: ★★★★☆ AI nodes: yes Added:

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

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

The workflow JSON

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

Download .json
{
  "id": "OS0DM1wf2h0qBhUA",
  "name": "Conference Synthetic Personas Generator TEMPLATE",
  "tags": [],
  "nodes": [
    {
      "id": "a21ef05a-1d8c-44ea-b16d-809809c0c8a7",
      "name": "Receive Slash Command",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -1216,
        448
      ],
      "parameters": {
        "path": "doppelganger",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "cd617b17-9a95-48e2-84e8-fe2762408762",
      "name": "Acknowledge Slack Command",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        -1008,
        368
      ],
      "parameters": {
        "options": {
          "responseCode": 200,
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "application/json"
              }
            ]
          }
        },
        "respondWith": "text",
        "responseBody": "=\ud83e\uddec Generating Digital Doppelg\u00e4ngers for *{{ $json.body.text }}*... This may take a minute."
      },
      "typeVersion": 1.1
    },
    {
      "id": "2d203524-3225-42af-b74c-e181b7358542",
      "name": "Parse Command Args",
      "type": "n8n-nodes-base.code",
      "position": [
        -1008,
        528
      ],
      "parameters": {
        "jsCode": "// Parse slash command: /doppelganger <event_name> <count> <source>\n// Example: /doppelganger \"TechConf 2026\" 5 hubspot\nconst text = $input.first().json.body?.text || '';\nconst channelId = $input.first().json.body?.channel_id || '';\nconst userId = $input.first().json.body?.user_id || '';\n\n// Parse arguments \u2014 supports quoted event names\nconst quotedMatch = text.match(/^\"([^\"]+)\"\\s+(\\d+)?\\s*(\\w+)?$/);\nconst simpleMatch = text.match(/^(\\S+)\\s+(\\d+)?\\s*(\\w+)?$/);\n\nlet eventName, personaCount, crmSource;\n\nif (quotedMatch) {\n  eventName = quotedMatch[1];\n  personaCount = parseInt(quotedMatch[2] || '5', 10);\n  crmSource = (quotedMatch[3] || 'sheets').toLowerCase();\n} else if (simpleMatch) {\n  eventName = simpleMatch[1];\n  personaCount = parseInt(simpleMatch[2] || '5', 10);\n  crmSource = (simpleMatch[3] || 'sheets').toLowerCase();\n} else {\n  eventName = text.trim() || 'Unnamed Event';\n  personaCount = 5;\n  crmSource = 'sheets';\n}\n\n// Clamp persona count to 3-10 range\npersonaCount = Math.max(3, Math.min(10, personaCount));\n\n// Validate CRM source\nconst validSources = ['hubspot', 'salesforce', 'sheets'];\nif (!validSources.includes(crmSource)) {\n  crmSource = 'sheets';\n}\n\nreturn [{\n  json: {\n    eventName,\n    personaCount,\n    crmSource,\n    channelId,\n    userId,\n    requestedAt: new Date().toISOString()\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "cc5b24c7-ca6e-407d-82e4-ecdb32896bbb",
      "name": "Route by CRM Source",
      "type": "n8n-nodes-base.switch",
      "position": [
        -720,
        512
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "HubSpot",
              "conditions": {
                "options": {
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.crmSource }}",
                    "rightValue": "hubspot"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Salesforce",
              "conditions": {
                "options": {
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.crmSource }}",
                    "rightValue": "salesforce"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Google Sheets",
              "conditions": {
                "options": {
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.crmSource }}",
                    "rightValue": "sheets"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {
          "allMatchingOutputs": false
        }
      },
      "typeVersion": 3.2
    },
    {
      "id": "99f98c74-56a2-48ed-9e2e-625d456d237a",
      "name": "Fetch HubSpot Contacts",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -480,
        320
      ],
      "parameters": {
        "url": "https://api.hubapi.com/crm/v3/objects/contacts/search",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"filterGroups\": [{\n    \"filters\": [{\n      \"propertyName\": \"event_tag\",\n      \"operator\": \"EQ\",\n      \"value\": \"{{ $('Parse Command Args').item.json.eventName }}\"\n    }]\n  }],\n  \"properties\": [\"firstname\", \"lastname\", \"jobtitle\", \"company\", \"industry\", \"city\", \"country\", \"notes_last_contacted\"],\n  \"limit\": 100\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.2
    },
    {
      "id": "9b9bb280-37aa-4f22-a894-15269df30c7b",
      "name": "Fetch Salesforce Contacts",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -480,
        512
      ],
      "parameters": {
        "url": "={{ $('Parse Command Args').item.json.sfInstanceUrl || 'https://yourinstance.salesforce.com' }}/services/data/v59.0/query",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "oAuth2Api",
        "queryParameters": {
          "parameters": [
            {
              "name": "q",
              "value": "=SELECT FirstName, LastName, Title, Account.Name, Account.Industry, MailingCity, MailingCountry FROM CampaignMember WHERE Campaign.Name = '{{ $('Parse Command Args').item.json.eventName }}'"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "82281f12-bcbd-468c-aa1e-c8219b648f8d",
      "name": "Fetch Google Sheets Contacts",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -480,
        720
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "PLACEHOLDER_AUDIENCE_SHEET_ID"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "07e135ad-53f1-41bf-8612-084ac75511d3",
      "name": "Normalize Audience Data",
      "type": "n8n-nodes-base.code",
      "position": [
        -240,
        512
      ],
      "parameters": {
        "jsCode": "// Normalize audience data from any CRM source into a common format\nconst source = $('Parse Command Args').first().json.crmSource;\nconst items = $input.all();\n\nlet attendees = [];\n\nif (source === 'hubspot') {\n  const results = items[0]?.json?.results || items.map(i => i.json);\n  attendees = results.map(r => ({\n    name: [r.properties?.firstname, r.properties?.lastname].filter(Boolean).join(' ') || 'Unknown',\n    title: r.properties?.jobtitle || '',\n    company: r.properties?.company || '',\n    industry: r.properties?.industry || '',\n    location: [r.properties?.city, r.properties?.country].filter(Boolean).join(', ')\n  }));\n} else if (source === 'salesforce') {\n  const records = items[0]?.json?.records || items.map(i => i.json);\n  attendees = records.map(r => ({\n    name: [r.FirstName, r.LastName].filter(Boolean).join(' ') || 'Unknown',\n    title: r.Title || '',\n    company: r.Account?.Name || '',\n    industry: r.Account?.Industry || '',\n    location: [r.MailingCity, r.MailingCountry].filter(Boolean).join(', ')\n  }));\n} else {\n  // Google Sheets \u2014 expects columns: Name, Title, Company, Industry, Location\n  attendees = items.map(i => ({\n    name: i.json.Name || i.json.name || 'Unknown',\n    title: i.json.Title || i.json.title || i.json['Job Title'] || '',\n    company: i.json.Company || i.json.company || i.json.Organization || '',\n    industry: i.json.Industry || i.json.industry || '',\n    location: i.json.Location || i.json.location || i.json.City || ''\n  }));\n}\n\n// Build audience summary for AI\nconst totalCount = attendees.length;\nconst titles = attendees.map(a => a.title).filter(Boolean);\nconst companies = attendees.map(a => a.company).filter(Boolean);\nconst industries = attendees.map(a => a.industry).filter(Boolean);\n\nconst titleCounts = {};\ntitles.forEach(t => { titleCounts[t] = (titleCounts[t] || 0) + 1; });\nconst industryCounts = {};\nindustries.forEach(i => { industryCounts[i] = (industryCounts[i] || 0) + 1; });\n\nreturn [{\n  json: {\n    totalAttendees: totalCount,\n    topTitles: Object.entries(titleCounts).sort((a,b) => b[1]-a[1]).slice(0, 15).map(([k,v]) => `${k} (${v})`).join(', '),\n    topIndustries: Object.entries(industryCounts).sort((a,b) => b[1]-a[1]).slice(0, 10).map(([k,v]) => `${k} (${v})`).join(', '),\n    uniqueCompanies: [...new Set(companies)].length,\n    sampleAttendees: JSON.stringify(attendees.slice(0, 20), null, 2),\n    eventName: $('Parse Command Args').first().json.eventName,\n    personaCount: $('Parse Command Args').first().json.personaCount,\n    crmSource: $('Parse Command Args').first().json.crmSource\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "8a873198-d62d-4482-8f9b-5645bb92ad3a",
      "name": "Generate Persona Archetypes",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        0,
        400
      ],
      "parameters": {},
      "typeVersion": 1.4
    },
    {
      "id": "3836dbe0-8c48-4a9a-8960-e1612f1a5c7e",
      "name": "Google Gemini for Personas",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        0,
        624
      ],
      "parameters": {
        "options": {
          "temperature": 0.8
        },
        "modelName": "models/gemini-2.5-flash-lite"
      },
      "typeVersion": 1
    },
    {
      "id": "20a6ccbc-2ed3-4750-ac1f-c0a3dd5f0ccb",
      "name": "Parse Persona JSON",
      "type": "n8n-nodes-base.code",
      "position": [
        240,
        400
      ],
      "parameters": {
        "jsCode": "// Parse the AI-generated persona JSON from the LLM response\nconst response = $input.first().json.text || $input.first().json.response || '';\n\n// Extract JSON array from response (handle markdown code blocks)\nlet jsonStr = response;\nconst jsonMatch = response.match(/\\[\\s*\\{[\\s\\S]*\\}\\s*\\]/);\nif (jsonMatch) {\n  jsonStr = jsonMatch[0];\n}\n\nlet personas;\ntry {\n  personas = JSON.parse(jsonStr);\n} catch (e) {\n  // Try to fix common JSON issues\n  jsonStr = jsonStr.replace(/,\\s*\\]/g, ']').replace(/,\\s*\\}/g, '}');\n  personas = JSON.parse(jsonStr);\n}\n\nconst eventName = $('Parse Command Args').first().json.eventName;\nconst channelId = $('Parse Command Args').first().json.channelId;\nconst crmSource = $('Parse Command Args').first().json.crmSource;\n\n// Return each persona as a separate item for the loop\nreturn personas.map((persona, index) => ({\n  json: {\n    ...persona,\n    persona_index: index + 1,\n    persona_total: personas.length,\n    event_name: eventName,\n    channel_id: channelId,\n    crm_source: crmSource,\n    persona_json: JSON.stringify(persona),\n    created_at: new Date().toISOString()\n  }\n}));"
      },
      "typeVersion": 2
    },
    {
      "id": "0e986611-c7ad-4b75-aebe-b39eb64e7055",
      "name": "Store Persona in Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        480,
        400
      ],
      "parameters": {
        "columns": {
          "value": {
            "industry": "={{ $json.industry }}",
            "created_at": "={{ $json.created_at }}",
            "event_name": "={{ $json.event_name }}",
            "source_crm": "={{ $json.crm_source }}",
            "persona_org": "={{ $json.persona_org }}",
            "persona_json": "={{ $json.persona_json }}",
            "persona_name": "={{ $json.persona_name }}",
            "persona_title": "={{ $json.persona_title }}",
            "slack_channel": "={{ $json.channel_id }}",
            "interview_count": 0,
            "slack_thread_ts": ""
          },
          "mappingMode": "defineBelow"
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Personas"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "PLACEHOLDER_DOPPELGANGER_SHEET_ID"
        }
      },
      "typeVersion": 4.5,
      "continueOnFail": true
    },
    {
      "id": "6a6413c9-3eed-4bc3-b35c-56482facd117",
      "name": "Format Persona Card",
      "type": "n8n-nodes-base.code",
      "position": [
        480,
        592
      ],
      "parameters": {
        "jsCode": "// Build Slack Block Kit message for this persona\nconst p = $input.first().json;\n\nconst card = `${p.emoji || '\ud83e\uddec'} *Digital Doppelg\u00e4nger #${p.persona_index}/${p.persona_total}*\n\n*${p.persona_name}* \u2014 ${p.persona_title}\n_${p.persona_org}_ (${p.org_size}) | ${p.industry}\n\n\ud83c\udfaf *Motivation:* ${p.primary_motivation}\n\n\ud83d\ude24 *Pain Points:*\n${(p.pain_points || []).map(pp => '  \u2022 ' + pp).join('\\n')}\n\n\ud83e\udde0 *Decision Style:* ${p.decision_style} | \ud83d\udcb0 *Budget Authority:* ${p.budget_authority}\n\n\ud83e\udd1d *Networking:* ${p.networking_preference}\n\ud83d\udcda *Prefers:* ${(p.content_preferences || []).join(', ')}\n\n\u26a0\ufe0f *Likely Objections:*\n${(p.likely_objections || []).map(o => '  \u2022 ' + o).join('\\n')}\n\n\ud83d\udcca *Predicted Behavior:* ${p.engagement_prediction}\n\n---\n_\ud83d\udcac Reply in this thread to interview ${p.persona_name} \u2014 ask about their preferences, concerns, or what would make this event valuable to them._\n_\ud83e\uddec Synthetic persona generated from aggregate ${p.crm_source} data for \"${p.event_name}\"_`;\n\nreturn [{\n  json: {\n    ...p,\n    slackMessage: card\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "f126a2c8-666c-43a7-96fd-8f4dbde6d930",
      "name": "Post Persona to Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        720,
        592
      ],
      "parameters": {
        "text": "={{ $json.slackMessage }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.channel_id }}"
        },
        "otherOptions": {
          "unfurl_links": false,
          "unfurl_media": false
        },
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "0a78c4fa-99e4-4c27-8206-a84fa37b4a61",
      "name": "Capture Thread Timestamp",
      "type": "n8n-nodes-base.code",
      "position": [
        960,
        592
      ],
      "parameters": {
        "jsCode": "// Capture the Slack message timestamp for interview thread routing\nconst slackResponse = $input.first().json;\nconst threadTs = slackResponse.ts || slackResponse.message?.ts || '';\nconst personaData = $('Format Persona Card').first().json;\n\n// We'll update the Data Table record with the thread_ts\n// For now, store it for the summary\nreturn [{\n  json: {\n    persona_name: personaData.persona_name,\n    thread_ts: threadTs,\n    channel_id: personaData.channel_id,\n    persona_index: personaData.persona_index,\n    persona_total: personaData.persona_total\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "f5ed46c9-5d92-4783-9717-4c90f510a117",
      "name": "Run Structured Interview",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        1200,
        400
      ],
      "parameters": {},
      "typeVersion": 1.4
    },
    {
      "id": "0e942576-00d3-47f5-a5ea-b0ea6f8cc21a",
      "name": "Google Gemini for Auto-Interview",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        1200,
        624
      ],
      "parameters": {
        "options": {
          "temperature": 0.7
        },
        "modelName": "models/gemini-2.5-flash-lite"
      },
      "typeVersion": 1
    },
    {
      "id": "6668db23-49e1-45e0-8b72-835121499589",
      "name": "Format Interview Report",
      "type": "n8n-nodes-base.code",
      "position": [
        1504,
        400
      ],
      "parameters": {
        "jsCode": "// Format the auto-interview response for this persona\nconst interviewResponse = $input.first().json.text || $input.first().json.response || '';\nconst personaData = $('Parse Persona JSON').first().json;\n\nconst report = `\ud83e\uddec *AUTO-INTERVIEW REPORT: ${personaData.persona_name}*\n_${personaData.persona_title} at ${personaData.persona_org}_ (${personaData.org_size}) | ${personaData.industry}\n\n${interviewResponse}\n\n---\n_${personaData.emoji || '\ud83e\uddec'} Digital Doppelg\u00e4nger #${personaData.persona_index}/${personaData.persona_total} | Auto-interview for \"${personaData.event_name}\"_`;\n\nreturn [{\n  json: {\n    report,\n    persona_name: personaData.persona_name,\n    persona_index: personaData.persona_index,\n    persona_total: personaData.persona_total,\n    channel_id: personaData.channel_id,\n    event_name: personaData.event_name\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "6766b486-713a-489b-b4c3-0aad6ee5a081",
      "name": "Post Interview Report to Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        1680,
        400
      ],
      "parameters": {
        "text": "={{ $json.report }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.channel_id }}"
        },
        "otherOptions": {
          "unfurl_links": false,
          "unfurl_media": false
        },
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "d1d6087b-6a0b-4288-bdf0-8f474e38517d",
      "name": "Post Generation Summary",
      "type": "n8n-nodes-base.slack",
      "position": [
        1872,
        400
      ],
      "parameters": {
        "text": "=\u2705 *Digital Doppelg\u00e4nger Report Complete!*\n\n\ud83e\uddec Generated and auto-interviewed *{{ $('Parse Command Args').item.json.personaCount }}* synthetic personas for *{{ $('Parse Command Args').item.json.eventName }}*\n\ud83d\udcca Data source: {{ $('Parse Command Args').item.json.crmSource }}\n\n\ud83d\udccb *14 structured questions per persona covering:*\n  \u2022 Content & Format (3 questions)\n  \u2022 Logistics & Experience (3 questions)\n  \u2022 Networking & Meetings (3 questions)\n  \u2022 ROI & Decision-Making (3 questions)\n  \u2022 Wildcard Insights (2 questions)\n\n\ud83d\udcac *Want to dig deeper?* Reply in any persona card's thread with follow-up questions.\n\n_Powered by Braia Labs | Digital Doppelg\u00e4nger Engine_",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Parse Command Args').item.json.channelId }}"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "sticky-intro-gen",
      "name": "Intro \u2014 Persona Generator",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1904,
        112
      ],
      "parameters": {
        "width": 600,
        "height": 820,
        "content": "## Digital Doppelg\u00e4nger \u2014 Persona Generator\n\n### **What it does:**\nGenerates AI-powered synthetic personas (Digital Doppelg\u00e4ngers) from your CRM attendee data that event teams can interview before the event \u2014 shifting from post-event measurement to pre-event prediction.\n\n### **Why it matters:**\nVOK DAMS' Digital Doppelg\u00e4nger concept lets you test event concepts, content strategies, and networking formats against realistic audience archetypes BEFORE committing resources. Predict what works instead of measuring what didn't.\n\n### **How it works:**\n1. Team runs `/doppelganger \"Event Name\" 5 hubspot` in Slack\n2. Workflow fetches attendee data from CRM (HubSpot, Salesforce, or Google Sheets)\n3. Gemini AI analyzes audience segments and generates synthetic personas\n4. Each persona is posted as a rich card to Slack\n5. Each persona is auto-interviewed with 14 structured questions across 5 categories\n6. Full interview reports are posted to Slack\n7. Team can still reply in persona threads for deeper follow-up questions\n\n### **Setup steps:**\n1. Connect **Slack** OAuth2 credential\n2. Connect **Google Gemini** API credential\n3. Configure CRM credentials (HubSpot API key, Salesforce OAuth, or Google Sheets)\n4. Create a Google Sheet with tabs: `Personas` and `Conversations` \u2014 update the Sheet ID placeholder\n5. Update the audience Google Sheets ID placeholder if using Sheets as CRM data source\n6. Register the `/doppelganger` slash command in your Slack app settings\n7. Set the slash command URL to this webhook's production URL"
      },
      "typeVersion": 1
    },
    {
      "id": "sticky-slash-setup",
      "name": "Section \u2014 Slash Command",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1280,
        112
      ],
      "parameters": {
        "color": 6,
        "width": 484,
        "height": 592,
        "content": "## 1. Slack Slash Command\n\nReceives `/doppelganger` command with args:\n- **Event name** (quoted if spaces)\n- **Persona count** (3-10, default 5)\n- **CRM source** (`hubspot`, `salesforce`, `sheets`)\n\nAcknowledges immediately (Slack 3s timeout) then processes async."
      },
      "typeVersion": 1
    },
    {
      "id": "sticky-crm",
      "name": "Section \u2014 CRM Integration",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -768,
        112
      ],
      "parameters": {
        "color": 5,
        "width": 672,
        "height": 796,
        "content": "## 2. CRM Data Fetch\n\nRoutes to the correct CRM API based on source parameter:\n- **HubSpot** \u2014 Contact search by event tag\n- **Salesforce** \u2014 SOQL query on CampaignMember\n- **Google Sheets** \u2014 Direct read (CSV import fallback)\n\nAll sources are normalized to a common format for AI analysis."
      },
      "typeVersion": 1
    },
    {
      "id": "sticky-ai-gen",
      "name": "Section \u2014 AI Persona Engine",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -64,
        112
      ],
      "parameters": {
        "color": 3,
        "width": 460,
        "height": 680,
        "content": "## 3. AI Persona Engine\n\nGoogle Gemini Flash Lite clusters attendee data into distinct archetypes and generates detailed synthetic personas with:\n- Motivations, pain points, decision style\n- Budget authority, networking preferences\n- Content format preferences\n- Likely objections and engagement predictions\n\n**GDPR Safe:** All personas are synthetic \u2014 no real PII is reproduced."
      },
      "typeVersion": 1
    },
    {
      "id": "sticky-delivery",
      "name": "Section \u2014 Store & Deliver",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        432,
        112
      ],
      "parameters": {
        "color": 4,
        "width": 680,
        "height": 680,
        "content": "## 4. Store & Deliver\n\nEach persona is:\n1. Stored in the `Digital Doppelg\u00e4ngers` Google Sheet (Personas tab)\n2. Formatted as a rich Slack Block Kit card\n3. Posted to the requesting channel\n\nInterview conversations are also logged to the Conversations tab."
      },
      "typeVersion": 1
    },
    {
      "id": "sticky-auto-interview",
      "name": "Section \u2014 Auto-Interview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1152,
        112
      ],
      "parameters": {
        "color": 5,
        "width": 944,
        "height": 680,
        "content": "## 5. Structured Auto-Interview\n\nEach persona is automatically interviewed with **14 questions** across 5 categories:\n\n| Category | Questions | Covers |\n|---|---|---|\n| **Content & Format** | Q1-Q3 | Session types, topics, depth |\n| **Logistics & Experience** | Q4-Q6 | Schedule, venue, hybrid |\n| **Networking & Meetings** | Q7-Q9 | Who to meet, formats, value |\n| **ROI & Decision-Making** | Q10-Q12 | Justification, success, objections |\n| **Wildcard** | Q13-Q14 | Pain points, ideal experience |\n\nFull reports are posted to Slack automatically \u2014 no manual questioning needed."
      },
      "typeVersion": 1
    },
    {
      "id": "sticky-contact-gen",
      "name": "Contact \u2014 Braia Labs",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2128,
        112
      ],
      "parameters": {
        "width": 560,
        "height": 1176,
        "content": "## Was this helpful? Get in touch!\n\n[![clic](https://vptkuqoipqbebipqjnqw.supabase.co/storage/v1/object/public/Milo%20Bravo/seeAxWUupcOOXY5tntexZ_video.gif)](https://tally.so/r/EkKGgB)\n\nI really hope this automation helped you. Your feedback is incredibly valuable and helps me create better resources for business and the n8n community.\n\n### **Have Feedback, a Question, or a Project Idea?**\n\nI've streamlined the way we connect. It all starts with one simple form that takes less than 10 seconds. After that, you'll chat with my AI assistant who will gather the key details and pass them directly on to me.\n\n####  **[Start the conversation here](https://tally.so/r/EkKGgB)**\n\n*   **Give Feedback:** Share your thoughts on this template\u2014whether you found a typo, encountered an unexpected error, have a suggestion, or just want to say thanks!\n\n*   **n8n Consulting:** Have a complex business challenge or need a custom workflow built from scratch? Let's partner on a powerful automation solution tailored to your specific needs.\n\n*   **Join your team:** We can work together to get you launched with confidence.\n\n---\n\nHappy Automating!\n[Milo Bravo](https://linkedin.com/in/MiloBravo/) | BRaiA Labs | Automation & BI Systems + AI Integration"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "callerPolicy": "workflowsFromSameOwner",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "cf9b6e46-6ebc-46c2-87eb-6523efd1eca4",
  "connections": {
    "Parse Command Args": {
      "main": [
        [
          {
            "node": "Route by CRM Source",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Persona JSON": {
      "main": [
        [
          {
            "node": "Store Persona in Google Sheets",
            "type": "main",
            "index": 0
          },
          {
            "node": "Format Persona Card",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Persona Card": {
      "main": [
        [
          {
            "node": "Post Persona to Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route by CRM Source": {
      "main": [
        [
          {
            "node": "Fetch HubSpot Contacts",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Fetch Salesforce Contacts",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Fetch Google Sheets Contacts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post Persona to Slack": {
      "main": [
        [
          {
            "node": "Capture Thread Timestamp",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Receive Slash Command": {
      "main": [
        [
          {
            "node": "Acknowledge Slack Command",
            "type": "main",
            "index": 0
          },
          {
            "node": "Parse Command Args",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch HubSpot Contacts": {
      "main": [
        [
          {
            "node": "Normalize Audience Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Interview Report": {
      "main": [
        [
          {
            "node": "Post Interview Report to Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Audience Data": {
      "main": [
        [
          {
            "node": "Generate Persona Archetypes",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Capture Thread Timestamp": {
      "main": [
        [
          {
            "node": "Run Structured Interview",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run Structured Interview": {
      "main": [
        [
          {
            "node": "Format Interview Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Salesforce Contacts": {
      "main": [
        [
          {
            "node": "Normalize Audience Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini for Personas": {
      "ai_languageModel": [
        [
          {
            "node": "Generate Persona Archetypes",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Generate Persona Archetypes": {
      "main": [
        [
          {
            "node": "Parse Persona JSON",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Google Sheets Contacts": {
      "main": [
        [
          {
            "node": "Normalize Audience Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post Interview Report to Slack": {
      "main": [
        [
          {
            "node": "Post Generation Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini for Auto-Interview": {
      "ai_languageModel": [
        [
          {
            "node": "Run Structured Interview",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

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

About this workflow

Who is this for? Event strategists, conference organizers, and marketing teams planning content/networking who want to interview realistic audience personas based on their participantants behavioural data before spending budget. What problem is this workflow solving? Event…

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

More AI & RAG workflows → · Browse all categories →

Related workflows

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

AI & RAG

This workflow is designed for sales professionals, account managers, and small business owners in Japan who frequently exchange business cards. Instead of manually entering contact details, you can in

HTTP Request, Google Sheets, Slack +3
AI & RAG

Development teams and tech leads who want to maintain consistent code quality without manual review bottlenecks. Perfect for teams handling multiple PRs daily and wanting AI-powered insights on securi

HTTP Request, Chain Llm, Google Gemini Chat +2
AI & RAG

ANIS_HUB 1. Uses gmail, googleDrive, googleSheets, httpRequest. Webhook trigger; 89 nodes.

Gmail, Google Drive, Google Sheets +3
AI & RAG

This n8n workflow orchestrates a powerful suite of AI Agents and automations to manage and optimize various aspects of an e-commerce operation, particularly for platforms like Shopify. It leverages La

Google Sheets, HTTP Request, Slack +10
AI & RAG

Resume Screening & Behavioral Interviews with Gemini, Elevenlabs, & Notion ATS copy. Uses outputParserStructured, chainLlm, googleDrive, stickyNote. Webhook trigger; 67 nodes.

Output Parser Structured, Chain Llm, Google Drive +9