AutomationFlowsAI & RAG › Fluidx the Eye — Create & Invite via SMS for Live Camera Session

Fluidx the Eye — Create & Invite via SMS for Live Camera Session

ByOlaf Titel @superoel on n8n.io

Goal: This workflow demonstrates the full fluidX THE EYE integration — starting a live session, inviting both the customer (via SMS) and the service agent (via email), and then accessing the media (photos and videos) created during the session. Captured images are automatically…

Event trigger★★★★★ complexityAI-powered47 nodesForm TriggerGoogle DriveEmail SendItem ListsHTTP RequestOpenAI
AI & RAG Trigger: Event Nodes: 47 Complexity: ★★★★★ AI nodes: yes Added:

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

This workflow follows the Emailsend → Form Trigger 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": "r8Qe7WuBooLIDbHv",
  "meta": {
    "templateTitle": "fluidX \u2014 Create Session & Notify (API Integration Example)",
    "templateDescription": "Creates a production-ready fluidX THE EYE session, delivers SMS/email invites, deduplicates media polling, adds AI-based labels, and syncs photos plus rolling summaries to Google Drive.",
    "templateInstructions": "# \ud83d\udcdd Setup \u2014 fluidX THE EYE Session Automation\n\n## 1. Accounts & Docs\n- Create a developer login at https://live.fluidx.digital (TEST plan is free)\n- Review the API reference: https://live.fluidx.digital/api/swagger.html\n\n## 2. Required Credentials in n8n\n1. `fluidx API key` (HTTP Header Auth \u2192 header `x-api-key`)\n2. SMTP account for outbound email notifications\n3. Google Drive OAuth2 credential (for uploads)\n4. Optional: OpenAI credential if you want AI photo captions\n\n## 3. Configure the \"Set Config\" node\n- `BASE_URL`: keep `https://live.fluidx.digital`\n- `company` / `project` / `billingcode` / `sku`: set to your production identifiers\n- `language`: controls the OpenAI caption language (default `DE`)\n- `message`: SMS intro text; the customer link is appended automatically\n- Phone/email fields come from the built-in form each run, so no personal data is stored in the workflow\n\n## 4. Run Flow\nForm Trigger \u2192 Create Session \u2192 Set Session Vars \u2192 Google Drive folder \u2192 Send SMS \u2192 Send Email \u2192 Wait for live feed \u2192 Poll `/api/revxr/ext/session` for `photoRefs` \u2192 Skip already processed photos via workflow static data \u2192 Download \u2192 Analyze (optional OpenAI) \u2192 Upload media + captions to Drive \u2192 Fetch `/api/fx/ext/media/summary`, convert to text, and keep the latest summary file per session.\n\n## 5. Operational Notes\n- All HTTP request nodes reference the `fluidx API key` credential so you can rotate keys centrally.\n- Workflow static data is cleared after each run to avoid leaking media IDs between sessions.\n- Replace the Google Drive folder ID with your own shared workspace before publishing.\n- Use environment variables or n8n Credentials for any other secrets you add.\n\nHappy streaming! \ud83d\ude80\n",
    "templateCredsSetupCompleted": true
  },
  "name": "n8n_fluidx_create_session",
  "tags": [],
  "nodes": [
    {
      "id": "0d2978ac-0459-47fd-9b99-9851852cad04",
      "name": "\ud83d\udcdd Setup & Instructions",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        0
      ],
      "parameters": {
        "width": 688,
        "height": 540,
        "content": "### Setup \u2014 Create a fluidX revXR THE EYE session\n\n**Goal:** Invite the customer via SMS and the service agent via email so both join the fluidX THE EYE session and share their cameras live.\n\n1. Sign in at https://live.fluidx.digital (activate the TEST ABO plan, \u20ac0) and create your API key.\n2. Review the API docs: https://live.fluidx.digital/api/swagger.html.\n3. In n8n add credentials:\n   - fluidX API key (HTTP Header Auth \u2192 header x-api-key)\n   - SMTP account for outbound email.\n   - OpenAI key\n   - Google Drive API\n4. Open the \"Set Config\" node \u2014 the defaults are ready to test; adjust other values if needed (the form collects the phone and email each run).\n5. Run the flow: Submit the form (\"On form submission\") \u2192 Create Session \u2192 Set Session Vars \u2192 Create Drive folder \u2192 Send SMS \u2192 Send Email.\n6. Create a THEEYE folder in your Google Drive root.\n\nTips:\n- Keep secrets inside n8n credentials or environment variables.\n- Use demo data while testing; swap to production values when ready.\n- Log out of live.fluidx.digital in the agent's browser before testing to ensure the invite flow opens a clean session.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "f3421d4b-5e6a-4dd8-890e-c9023d262599",
      "name": "On form submission",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        288,
        960
      ],
      "parameters": {
        "options": {},
        "formTitle": "fluidX digital The Eye Session Invitation",
        "formFields": {
          "values": [
            {
              "fieldLabel": "User Phone Number",
              "placeholder": "+1234567890",
              "requiredField": true
            },
            {
              "fieldLabel": "Agent Email Address",
              "placeholder": "user@example.com",
              "requiredField": true
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "cdd96102-c2b5-471a-aeaf-a6da0bee2f40",
      "name": "Set Config",
      "type": "n8n-nodes-base.set",
      "position": [
        512,
        960
      ],
      "parameters": {
        "values": {
          "string": [
            {
              "name": "BASE_URL",
              "value": "https://live.fluidx.digital"
            },
            {
              "name": "phoneNumberUser",
              "value": "={{ $json['User Phone Number'] }}"
            },
            {
              "name": "message",
              "value": "fluidX.digital TheEye. Your Link: "
            },
            {
              "name": "emailAgent",
              "value": "={{ $json['Agent Email Address'] }}"
            },
            {
              "name": "language",
              "value": "DE"
            },
            {
              "name": "company",
              "value": "service berlin"
            },
            {
              "name": "project",
              "value": "fluidX demo"
            },
            {
              "name": "billingcode",
              "value": "demo-budget"
            },
            {
              "name": "correlationId",
              "value": "{{$now}}"
            },
            {
              "name": "sku",
              "value": "THEEYE"
            }
          ]
        },
        "options": {},
        "keepOnlySet": true
      },
      "typeVersion": 2
    },
    {
      "id": "bece2d3b-3465-4cab-8483-f49136e1778c",
      "name": "Set Session Vars",
      "type": "n8n-nodes-base.set",
      "position": [
        960,
        960
      ],
      "parameters": {
        "values": {
          "string": [
            {
              "name": "sessionId",
              "value": "={{ $json.revXRSession.id }}"
            },
            {
              "name": "viewTheEyeUrl",
              "value": "={{ $json.sessionInfo.viewTheEyeUrl }}"
            },
            {
              "name": "theEyeUserUrl",
              "value": "={{ $json.sessionInfo.theEyeUserUrl }}"
            },
            {
              "name": "folderName",
              "value": "={{ 'THEEYE_' + $now.toFormat('yyyyLLdd_HHmmss') + '_' + $json.revXRSession.id }}"
            }
          ]
        },
        "options": {},
        "keepOnlySet": true
      },
      "typeVersion": 2
    },
    {
      "id": "e77f231d-a7ba-4be8-87a7-b6f97e9aa3cc",
      "name": "Create Session Folder",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        1184,
        960
      ],
      "parameters": {
        "name": "={{ $node[\"Set Session Vars\"].json.folderName }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "10d6dEoF6GVYGMUW0M1eZiSlDc7JLtaxY",
          "cachedResultUrl": "https://drive.google.com/drive/folders/10d6dEoF6GVYGMUW0M1eZiSlDc7JLtaxY",
          "cachedResultName": "THEEYE"
        },
        "resource": "folder"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "f9d45461-ef0b-4724-a771-96abd835c6b7",
      "name": "Send email to Agent",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        1632,
        960
      ],
      "parameters": {
        "text": "=fluidx.digital View TheEye: Your Link: \n{{ $node[\"Set Session Vars\"].json.viewTheEyeUrl }}",
        "options": {},
        "subject": "fluidX.digital View TheEye Link",
        "toEmail": "={{ $node[\"Set Config\"].json.emailAgent }}",
        "fromEmail": "user@example.com",
        "emailFormat": "text"
      },
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "78c8ce11-4a68-4f4a-af66-deb61212bffc",
      "name": "\u2139\ufe0f Viewer Tips",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2495,
        400
      ],
      "parameters": {
        "color": 7,
        "width": 835,
        "height": 364,
        "content": "### If the Session is closed: Get the media summary\nfluidX API GET /api/fx/ext/media/summary\nUpload the final Summary to the Google Drive\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "18bfe57d-a072-4886-b99e-2f9e3fbc9773",
      "name": "Split photoRefs (Item Lists)",
      "type": "n8n-nodes-base.itemLists",
      "position": [
        2976,
        912
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "=photoRefs"
      },
      "typeVersion": 3,
      "alwaysOutputData": false
    },
    {
      "id": "5f6ee9ef-966a-411e-beee-c2d5f0406c44",
      "name": "fluidX API - Media Info HTTP Request GET",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "position": [
        3424,
        944
      ],
      "parameters": {
        "url": "={{ $item(0).$node[\"Set Config\"].json.BASE_URL }}/api/revxr/ext/media/info",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "type",
              "value": "image"
            },
            {
              "name": "id",
              "value": "={{ $json.id }}"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2,
      "alwaysOutputData": true
    },
    {
      "id": "18f9e934-a057-4327-b806-67f33c710dab",
      "name": "Upload file",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        6112,
        528
      ],
      "parameters": {
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Create Session Folder').item.json.id }}"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "68726804-080e-4eaa-868a-6f18012165d0",
      "name": "Wait",
      "type": "n8n-nodes-base.wait",
      "position": [
        6560,
        1184
      ],
      "parameters": {
        "amount": 15
      },
      "typeVersion": 1.1
    },
    {
      "id": "3a119e17-c12c-4a95-978a-1dcfdef0acc1",
      "name": "Wait1",
      "type": "n8n-nodes-base.wait",
      "position": [
        1856,
        960
      ],
      "parameters": {
        "amount": 30
      },
      "typeVersion": 1.1
    },
    {
      "id": "4f4c0803-fd98-450a-adcc-185f904f4346",
      "name": "Analyze image",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "onError": "continueRegularOutput",
      "position": [
        4768,
        704
      ],
      "parameters": {
        "text": "=What's in this image? Output language is {{ $('Set Config').item.json.language }}",
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "chatgpt-4o-latest",
          "cachedResultName": "CHATGPT-4O-LATEST"
        },
        "options": {},
        "resource": "image",
        "inputType": "base64",
        "operation": "analyze"
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "354b4dca-18e9-42ce-b489-95d2b8cab6c6",
      "name": "Merge Analyze + URL",
      "type": "n8n-nodes-base.merge",
      "position": [
        4992,
        768
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "6656b843-0c83-4301-a834-c1a0da326b92",
      "name": "Build MediaInfo",
      "type": "n8n-nodes-base.set",
      "position": [
        5216,
        768
      ],
      "parameters": {
        "values": {
          "string": [
            {
              "name": "type",
              "value": "image"
            },
            {
              "name": "id",
              "value": "={{ $json._srcId }}"
            },
            {
              "name": "title",
              "value": "={{\n  (() => {\n    // Kandidaten vom Analyze-Node \u2013 nimm was bef\u00fcllt ist\n    const raw =($json['0'].content[0].text).trim();\n\n    // Fallback: sinnvoller Titel, falls nichts da\n    const fallback = `Image ${$json.id || ''}`.trim();\n\n    if (!raw) return fallback;\n\n    // erste Satzh\u00e4lfte nehmen\n    let first = (raw.split(/[.!?\\n]/).find(s => s && s.trim().length) || raw).trim();\n\n    // leading Phrasen weg\n    first = first\n      .replace(/^\\s*(the|this)\\s+image\\s+(shows|depicts|displays)\\s*/i, '')\n      .replace(/^\\s*(an?\\s+|the\\s+)?(photo|image)\\s+of\\s+/i, '')\n      .trim();\n\n first = first\n      .replace(/^\\s*(Auf dem|Das)\\s+Bild\\s+(sieht man|zeigt)\\s*/i, '')\n      .replace(/^\\s*(einen?\\s+|ein\\s+)?(Bild)\\s+of\\s+/i, '')\n      .trim();\n\n    // auf 10 W\u00f6rter k\u00fcrzen\n    const words = first.split(/\\s+/);\n    let title = words.slice(0, 10).join(' ');\n\n    // Erstes Zeichen gro\u00df\n    title = title.charAt(0).toUpperCase() + title.slice(1);\n\n    return title || fallback;\n  })()\n}}"
            },
            {
              "name": "description",
              "value": "={{ $json['0'].content[0].text }}"
            }
          ]
        },
        "options": {},
        "keepOnlySet": true
      },
      "typeVersion": 2
    },
    {
      "id": "aa94f2dd-756a-46f2-9210-91be6ee3b883",
      "name": "fluidX API - Create Session",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        736,
        960
      ],
      "parameters": {
        "url": "={{ $node[\"Set Config\"].json.BASE_URL }}/api/fx/ext/session/create",
        "method": "POST",
        "options": {
          "timeout": 30000
        },
        "jsonBody": "={\n  \"sessionDetails\": {\n    \"company\": {{ $json.company.toJsonString() }},\n    \"project\": {{ $json.project.toJsonString() }},\n    \"billingcode\": {{ $json.billingcode.toJsonString() }},\n    \"correlationId\": \"2025-1234\",\n    \"sku\": {{ $json.sku.toJsonString() }}\n  }\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "58f80aca-625f-44bb-9f3b-0c726d9e3a20",
      "name": "fluidX API - Send SMS User",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1408,
        960
      ],
      "parameters": {
        "url": "={{ $node[\"Set Config\"].json.BASE_URL }}/api/fx/ext/sms/send",
        "method": "POST",
        "options": {
          "timeout": 30000
        },
        "jsonBody": "={\n  \"phoneNumber\": \"{{ $node[\"Set Config\"].json.phoneNumberUser }}\",\n  \"message\": {{ ($node[\"Set Config\"].json.message + $node[\"Set Session Vars\"].json.theEyeUserUrl).toJsonString() }},\n  \"sessionId\": {{ $node[\"Set Session Vars\"].json.sessionId.toJsonString() }}\n}\n",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "d54991a8-c71f-49d2-b3d0-a8b4a42ebaa8",
      "name": "fluidX API - Get Session Info",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "position": [
        2080,
        960
      ],
      "parameters": {
        "url": "={{ $item(0).$node[\"Set Config\"].json.BASE_URL }}/api/revxr/ext/session",
        "options": {
          "timeout": 30000
        },
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "sessionId",
              "value": "={{  $item(0).$node[\"Set Session Vars\"].json.sessionId }}"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3,
      "alwaysOutputData": true
    },
    {
      "id": "09d29311-35df-4666-b3ed-69d350ee23ef",
      "name": "fluidX API - Download Photo THEEYE Session",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        4320,
        768
      ],
      "parameters": {
        "url": "={{ $json.url }}",
        "options": {
          "timeout": 60000
        },
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "3dce58d2-3599-4cfe-8270-86eaed04f5bd",
      "name": "fluidX API - Media Info HTTP Request POST",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        5440,
        768
      ],
      "parameters": {
        "url": "={{ $item(0).$node[\"Set Config\"].json.BASE_URL }}/api/revxr/ext/media/info",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ $json }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "9a9c03a1-4c76-4cc9-b99c-1402870c57d4",
      "name": "If new Image",
      "type": "n8n-nodes-base.if",
      "position": [
        3872,
        848
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "33e243e6-7c66-4e3d-bb2e-b91a1c0f1d2e",
              "operator": {
                "type": "string",
                "operation": "notExists",
                "singleValue": true
              },
              "leftValue": "={{ $json.mediaInfo.description }}",
              "rightValue": ""
            },
            {
              "id": "c495e43a-4333-479e-9dc9-c0e29f8259c4",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "",
              "rightValue": ""
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "d5961c10-19fe-4cf3-8c29-e7bd0394238f",
      "name": "If Media Id",
      "type": "n8n-nodes-base.if",
      "position": [
        3200,
        1040
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "4f59097c-8851-43c7-9b9a-78a4d6181d8a",
              "operator": {
                "type": "number",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.id }}",
              "rightValue": ""
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "78d49f55-9671-4868-b617-f5f9b29be27c",
      "name": "If Session Active",
      "type": "n8n-nodes-base.if",
      "position": [
        2304,
        896
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cond-session-active",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.revXRSession.status }}",
              "rightValue": "ACTIVE"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "2de45ed6-e553-4e9b-b0e7-c270f22b4df5",
      "name": "The End",
      "type": "n8n-nodes-base.noOp",
      "position": [
        3648,
        600
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "55247c08-471c-46b4-97be-ef17c50a3445",
      "name": "Generate Photo Summary",
      "type": "n8n-nodes-base.code",
      "position": [
        5664,
        768
      ],
      "parameters": {
        "jsCode": "// Iterate through all incoming items and create one summary per mediaInfo\nconst items = $input.all();\nconst results = [];\n\nfor (const item of items) {\n  const info = item.json.mediaInfo || {};\n\n  const description = info.description?.trim() || 'No description';\n  const filename = `photo-${info.imageId || info.id || Date.now()}.txt`;\n\n  results.push({\n    json: {\n      filename,\n      text: `Title: ${info.title || 'Untitled'}\\nDescription: ${description}\\n---\\n`\n    }\n  });\n}\n\nreturn results;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "33faddeb-94fe-42e9-9293-2b576f810159",
      "name": "Upload Photo Summary",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        6112,
        768
      ],
      "parameters": {
        "name": "={{ $json.filename }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Create Session Folder').first().json.id.trim() }}"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "ead00873-f003-4565-a0d5-2ce82697d2fa",
      "name": "Convert Text to Binary",
      "type": "n8n-nodes-base.code",
      "position": [
        5888,
        768
      ],
      "parameters": {
        "jsCode": "// Convert all text summaries to binary files for Google Drive upload\nconst items = $input.all();\nconst results = [];\n\nfor (const item of items) {\n  const { text, filename } = item.json;\n  const buffer = Buffer.from(text, 'utf8');\n\n  results.push({\n    json: { filename },\n    binary: {\n      data: {\n        data: buffer.toString('base64'),\n        mimeType: 'text/plain',\n        fileName: filename\n      }\n    }\n  });\n}\n\nreturn results;\n\n"
      },
      "typeVersion": 2
    },
    {
      "id": "eb3e2f03-92e5-4bf4-8cbe-06d505ddc038",
      "name": "fluidX API - Media Summary",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2528,
        600
      ],
      "parameters": {
        "url": "={{ $item(0).$node[\"Set Config\"].json.BASE_URL }}/api/fx/ext/media/summary",
        "options": {
          "timeout": 30000
        },
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "sessionId",
              "value": "={{ $item(0).$node[\"Set Session Vars\"].json.sessionId }}"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "b10c3d6a-bb00-4d4a-b3f3-4b2814525b2d",
      "name": "Carry URL and Id",
      "type": "n8n-nodes-base.set",
      "position": [
        4544,
        768
      ],
      "parameters": {
        "values": {
          "number": [
            {
              "name": "_srcId",
              "value": "={{ $json.id }}"
            }
          ],
          "string": [
            {
              "name": "_srcUrl",
              "value": "={{ $json.url }}"
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 2
    },
    {
      "id": "cf9f62ec-6c67-4e0d-b62f-cfe3ca5b566f",
      "name": "If photos",
      "type": "n8n-nodes-base.if",
      "position": [
        2752,
        992
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "7988fb13-6236-4794-b051-9d992e47ab05",
              "operator": {
                "type": "array",
                "operation": "empty",
                "singleValue": true
              },
              "leftValue": "={{ $json.photoRefs }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "703663ab-56b1-4837-bfbe-fa6bc4d86a5f",
      "name": "Extract Media Refs photos",
      "type": "n8n-nodes-base.set",
      "position": [
        2528,
        992
      ],
      "parameters": {
        "values": {
          "string": [
            {
              "name": "photoRefs",
              "value": "={{$json.mediaInfo?.photoRefs || $json.photoRefs || []}}"
            }
          ]
        },
        "options": {},
        "keepOnlySet": true
      },
      "typeVersion": 2
    },
    {
      "id": "2ea8fec6-05db-4c6f-9790-b4f72c3ed42a",
      "name": "Check Already Uploaded",
      "type": "n8n-nodes-base.code",
      "position": [
        4096,
        768
      ],
      "parameters": {
        "jsCode": "// \ud83d\udd01 1\ufe0f\u20e3 Global store initialisieren\nconst store = $getWorkflowStaticData('global');\nif (!store.uploadedPhotoIds) store.uploadedPhotoIds = [];\n\n// \ud83d\udd01 2\ufe0f\u20e3 Alle eingehenden Items holen\nconst items = $input.all();\nconst newItems = [];\n\n// \ud83d\udd01 3\ufe0f\u20e3 Schleife: nur neue Bilder behalten\nfor (const item of items) {\n  const id = item.json.id;\n  if (!id) continue;\n\n  if (!store.uploadedPhotoIds.includes(id)) {\n    store.uploadedPhotoIds.push(id);\n    console.log(`\u2705 Neues Foto erkannt: ${id}`);\n    newItems.push(item);\n  } else {\n    console.log(`\u26a0\ufe0f Foto ${id} wurde bereits verarbeitet, \u00fcberspringe`);\n  }\n}\n\n// \ud83d\udd01 4\ufe0f\u20e3 Alles Neue als Batch zur\u00fcckgeben\nreturn newItems;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "42b490c0-d66d-41bb-8ec4-16ba19ea10e5",
      "name": "Merge photoRefs",
      "type": "n8n-nodes-base.merge",
      "position": [
        3648,
        848
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "5aa40281-8a45-434f-beae-b131f8decb96",
      "name": "Clear Uploaded Photo Store",
      "type": "n8n-nodes-base.code",
      "position": [
        3424,
        600
      ],
      "parameters": {
        "jsCode": "// \ud83e\uddf9 Clear stored photo IDs after the session ends\nconst store = $getWorkflowStaticData('global');\n\nif (store.uploadedPhotoIds && store.uploadedPhotoIds.length > 0) {\n  console.log(`\ud83e\uddf9 Removing ${store.uploadedPhotoIds.length} stored photo IDs from the upload cache`);\n  store.uploadedPhotoIds = [];\n} else {\n  console.log('\u2705 No stored photo ID cache \u2013 nothing to clean up');\n}\n\nreturn $input.all();\n"
      },
      "typeVersion": 2
    },
    {
      "id": "a71d0b5a-6076-41c2-8d71-0b738ed14485",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        6336,
        752
      ],
      "parameters": {
        "mode": "chooseBranch"
      },
      "typeVersion": 3.2
    },
    {
      "id": "adf7b7e5-2f9a-4c4d-8f00-1fec2c7315c3",
      "name": "Convert Summary Text to Binary",
      "type": "n8n-nodes-base.code",
      "position": [
        2752,
        600
      ],
      "parameters": {
        "jsCode": "// \ud83e\udde0 Safe conversion of session summary text to binary for Google Drive upload\nconst store = $getWorkflowStaticData('global');\nif (!store.sessionSummaryFiles || typeof store.sessionSummaryFiles !== 'object') {\n  store.sessionSummaryFiles = {};\n}\n\n// \ud83d\udd39 Get session info\nconst sessionItems = $items('Set Session Vars', 0, 0);\nconst sessionId = sessionItems[0]?.json?.sessionId || 'unknown-session';\n\n// \ud83d\udd39 Skip if we already uploaded a summary for this session\nif (store.sessionSummaryFiles[sessionId]) {\n  console.log(`\u2705 Session ${sessionId} summary already uploaded (file ${store.sessionSummaryFiles[sessionId]}). Skipping re-upload.`);\n  return [];\n}\n\n// \ud83d\udd39 Extract summary text from API response (robustly handle all cases)\nlet raw = $json.data ?? $json.body ?? $json.text ?? $json.mediaSummary ?? '';\nif (typeof raw !== 'string') {\n  try {\n    raw = JSON.stringify(raw, null, 2);\n  } catch (e) {\n    raw = String(raw);\n  }\n}\n\nconst summaryText = raw.trim() || '\u26a0\ufe0f Empty summary received from API';\nconst filename = `session-summary-${sessionId}.txt`;\n\nlet buffer;\ntry {\n  buffer = Buffer.from(summaryText, 'utf8');\n} catch (e) {\n  buffer = Buffer.from('\u26a0\ufe0f Error creating buffer from summary text', 'utf8');\n}\n\nreturn [{\n  json: { filename, sessionId },\n  binary: {\n    data: {\n      data: buffer.toString('base64'),\n      mimeType: 'text/plain',\n      fileName: filename,\n      fileExtension: 'txt'\n    }\n  }\n}];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "c0c73a6c-ea0e-44b5-9cd4-133d45e3fa80",
      "name": "Upload Session Summary",
      "type": "n8n-nodes-base.googleDrive",
      "onError": "continueRegularOutput",
      "position": [
        2976,
        600
      ],
      "parameters": {
        "name": "={{ $json.filename }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Create Session Folder').first().json.id.trim() }}"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": false,
      "typeVersion": 3,
      "alwaysOutputData": true
    },
    {
      "id": "727998b9-3c8e-4764-9cf1-3d683ab91670",
      "name": "\u2139\ufe0f Viewer Tips1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1924,
        784
      ],
      "parameters": {
        "color": 7,
        "width": 740,
        "height": 400,
        "content": "### Get session information\nfluidX API GET /api/revxr/ext/session\n"
      },
      "typeVersion": 1
    },
    {
      "id": "3fe62bc4-ae18-4632-8d41-41f29442b8cc",
      "name": "## Create THE EYE Session",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        80,
        784
      ],
      "parameters": {
        "color": 7,
        "width": 1840,
        "height": 400,
        "content": "### Create THE EYE session\nInvite the user via SMS and the agent via email.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "964e64a8-7b21-4cb4-837d-c1aab865590b",
      "name": "\u2139\ufe0f Viewer Tips2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3252,
        784
      ],
      "parameters": {
        "color": 7,
        "width": 590,
        "height": 400,
        "content": "### Retrieve the media information\nfluidX API GET /api/revxr/ext/media/info\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "a7c957dd-8d95-484b-b104-61f44550c669",
      "name": "\u2139\ufe0f Viewer Tips3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4000,
        600
      ],
      "parameters": {
        "color": 7,
        "width": 600,
        "height": 343,
        "content": "### Download the image via photoRefs\nUse the photoRefs download URL. If there is no MediaInfo, it is a new image captured on the customer's device.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "ffafc7ec-4972-41fe-9c20-51e5982be325",
      "name": "\u2139\ufe0f Viewer Tips4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4600,
        600
      ],
      "parameters": {
        "color": 7,
        "width": 580,
        "height": 343,
        "content": "### Analyze the image\nUse the `Analyze Image` node (or your preferred vision model) to extract insights.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "536dd4c3-2c3c-49ec-a509-ce9759fb22f6",
      "name": "\u2139\ufe0f Viewer Tips5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        5200,
        300
      ],
      "parameters": {
        "color": 7,
        "width": 660,
        "height": 636,
        "content": "### Create Media Info\nfluidX API POST /api/revxr/ext/media/info\nDocument the AI findings back into the session payload.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "bb49376f-7d0f-4528-b255-54f49f577a25",
      "name": "\u2139\ufe0f Viewer Tips6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        5875,
        300
      ],
      "parameters": {
        "color": 7,
        "width": 660,
        "height": 636,
        "content": "### Upload image and MediaInfo\nStore both assets in your Google Drive THEEYE folder.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "db283dae-d28f-4c4d-af92-557df597d384",
      "name": "\u2139\ufe0f Viewer Tips7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2680,
        784
      ],
      "parameters": {
        "color": 7,
        "width": 564,
        "height": 400,
        "content": "### Prepare image information\nExtract the image references: download URL and ID.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "8cf50456-15d7-410f-9e63-f0f167e18171",
      "name": "\u2139\ufe0f Viewer Tips9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3334,
        400
      ],
      "parameters": {
        "color": 7,
        "width": 510,
        "height": 364,
        "content": "### The end\nClean up remaining assets and wrap up the session.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "remember-summary-file-12345678",
      "name": "Remember Session Summary File",
      "type": "n8n-nodes-base.code",
      "position": [
        3200,
        600
      ],
      "parameters": {
        "jsCode": "// Track uploaded summary file IDs per session so we only upload once.\nconst store = $getWorkflowStaticData('global');\nif (!store.sessionSummaryFiles || typeof store.sessionSummaryFiles !== 'object') {\n  store.sessionSummaryFiles = {};\n}\n\nconst sessionItems = $items('Set Session Vars', 0, 0);\nconst sessionId = sessionItems[0]?.json?.sessionId || 'unknown-session';\nconst uploadedId = $json?.id;\n\nif (uploadedId) {\n  store.sessionSummaryFiles[sessionId] = uploadedId;\n  console.log(`\ud83d\udcc4 Stored session summary file ${uploadedId} for ${sessionId}`);\n} else {\n  console.log('\u26a0\ufe0f No uploaded summary file ID found \u2013 nothing stored.');\n}\n\nreturn $input.all();\n"
      },
      "typeVersion": 2
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "c45e820e-c6f4-4d56-b7df-5b26abb1add6",
  "connections": {
    "Wait": {
      "main": [
        [
          {
            "node": "fluidX API - Get Session Info",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait1": {
      "main": [
        [
          {
            "node": "fluidX API - Get Session Info",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "The End": {
      "main": []
    },
    "If photos": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Split photoRefs (Item Lists)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Config": {
      "main": [
        [
          {
            "node": "fluidX API - Create Session",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Media Id": {
      "main": [
        [
          {
            "node": "fluidX API - Media Info HTTP Request GET",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload file": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If new Image": {
      "main": [
        [
          {
            "node": "Check Already Uploaded",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Analyze image": {
      "main": [
        [
          {
            "node": "Merge Analyze + URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build MediaInfo": {
      "main": [
        [
          {
            "node": "fluidX API - Media Info HTTP Request POST",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge photoRefs": {
      "main": [
        [
          {
            "node": "If new Image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Carry URL and Id": {
      "main": [
        [
          {
            "node": "Analyze image",
            "type": "main",
            "index": 0
          },
          {
            "node": "Upload file",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge Analyze + URL",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Set Session Vars": {
      "main": [
        [
          {
            "node": "Create Session Folder",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Session Active": {
      "main": [
        [
          {
            "node": "Extract Media Refs photos",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "fluidX API - Media Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "On form submission": {
      "main": [
        [
          {
            "node": "Set Config",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Analyze + URL": {
      "main": [
        [
          {
            "node": "Build MediaInfo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send email to Agent": {
      "main": [
        [
          {
            "node": "Wait1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload Photo Summary": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Create Session Folder": {
      "main": [
        [
          {
            "node": "fluidX API - Send SMS User",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Already Uploaded": {
      "main": [
        [
          {
            "node": "fluidX API - Download Photo THEEYE Session",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert Text to Binary": {
      "main": [
        [
          {
            "node": "Upload Photo Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Photo Summary": {
      "main": [
        [
          {
            "node": "Convert Text to Binary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload Session Summary": {
      "main": [
        [
          {
            "node": "Remember Session Summary File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Media Refs photos": {
      "main": [
        [
          {
            "node": "If photos",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Clear Uploaded Photo Store": {
      "main": [
        [
          {
            "node": "The End",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "fluidX API - Media Summary": {
      "main": [
        [
          {
            "node": "Convert Summary Text to Binary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "fluidX API - Send SMS User": {
      "main": [
        [
          {
            "node": "Send email to Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "fluidX API - Create Session": {
      "main": [
        [
          {
            "node": "Set Session Vars",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split photoRefs (Item Lists)": {
      "main": [
        [
          {
            "node": "If Media Id",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge photoRefs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Remember Session Summary File": {
      "main": [
        [
          {
            "node": "Clear Uploaded Photo Store",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "fluidX API - Get Session Info": {
      "main": [
        [
          {
            "node": "If Session Active",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert Summary Text to Binary": {
      "main": [
        [
          {
            "node": "Upload Session Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "fluidX API - Media Info HTTP Request GET": {
      "main": [
        [
          {
            "node": "Merge photoRefs",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "fluidX API - Media Info HTTP Request POST": {
      "main": [
        [
          {
            "node": "Generate Photo Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "fluidX API - Download Photo THEEYE Session": {
      "main": [
        [
          {
            "node": "Carry URL and Id",
            "type": "main",
            "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

Goal: This workflow demonstrates the full fluidX THE EYE integration — starting a live session, inviting both the customer (via SMS) and the service agent (via email), and then accessing the media (photos and videos) created during the session. Captured images are automatically…

Source: https://n8n.io/workflows/10724/ — 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 ideal for content creators, training providers, agencies, and businesses that need to quickly turn raw videos into polished, captioned, or narrated content — without hiring editors or

Ssh, Form Trigger, Ftp +3
AI & RAG

What it is An automated LinkedIn content system that takes a simple form (idea + optional file), generates LinkedIn posts with OpenAI, stores them in Notion, builds Google Slides carousels, and auto-p

Form Trigger, OpenAI, Notion +6
AI & RAG

Automate the entire process of converting any website or domain into clean, structured, AI-ready knowledge bases for Large Language Models (LLMs), semantic search, and chatbot development. URL Input v

HTTP Request, Form Trigger, Google Drive +1
AI & RAG

In this tutorial, I’ll show how to create UGC (User Generated Content) videos automatically using n8n and Sora 2.

Form Trigger, Google Drive, HTTP Request +2
AI & RAG

This workflow turns a single reference image into up to 100 high-performing ad variations using Fal.AI's Nano Banana model and GPT-5.1. Simply upload your inspiration to a form, and watch as unique, c

OpenAI, HTTP Request, Google Drive +1