AutomationFlowsAI & RAG › Handle Linkedin Inbox RAG Replies with Unipile, Claude, Pinecone, and Airtable

Handle Linkedin Inbox RAG Replies with Unipile, Claude, Pinecone, and Airtable

BySalman Mehboob @salmanmehboob on n8n.io

Automatically ingest your knowledge base, monitor your LinkedIn company page inbox, and reply to leads and customers with AI-drafted, source-grounded answers. Classifies every message, checks for spam, drafts replies using Claude and Pinecone RAG, and lets you auto-send or…

Event trigger★★★★★ complexityAI-powered51 nodesGoogle Drive TriggerGoogle DrivePinecone Vector StoreDocument Default Data LoaderText Splitter Token SplitterAirtableGoogle Gemini EmbeddingsHTTP Request
AI & RAG Trigger: Event Nodes: 51 Complexity: ★★★★★ AI nodes: yes Added:

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

This workflow follows the Agent → Airtable 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": "zX9gIZbFjzVLWYoP",
  "name": "All In One Unipile Linkedin Auto Reply",
  "tags": [],
  "nodes": [
    {
      "id": "f39626a2-1393-4907-a8be-0926f9ef2965",
      "name": "Watch KB Folder",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "position": [
        80,
        496
      ],
      "parameters": {
        "event": "fileCreated",
        "options": {
          "fileType": "all"
        },
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "mode": "list",
          "value": "1NJtz6JJbL2hLDQdpufKpGdT5ayXIepXb",
          "cachedResultUrl": "https://drive.google.com/drive/folders/1NJtz6JJbL2hLDQdpufKpGdT5ayXIepXb",
          "cachedResultName": "Linked Auto Reply Test Folder"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "50d9b89a-16d5-4669-97a1-409610f17035",
      "name": "Download File",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        400,
        496
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {
          "binaryPropertyName": "data"
        },
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "fe47d174-f923-4d0b-89d3-d730aa7204c1",
      "name": "Pinecone Insert",
      "type": "@n8n/n8n-nodes-langchain.vectorStorePinecone",
      "position": [
        704,
        496
      ],
      "parameters": {
        "mode": "insert",
        "options": {
          "pineconeNamespace": "company-kb"
        },
        "pineconeIndex": {
          "__rl": true,
          "mode": "list",
          "value": "company-knowledge-base"
        }
      },
      "credentials": {
        "pineconeApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "61b9088b-d5c4-4345-825a-09206eb66556",
      "name": "Default Data Loader",
      "type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
      "position": [
        880,
        736
      ],
      "parameters": {
        "options": {
          "metadata": {
            "metadataValues": [
              {
                "name": "filename",
                "value": "={{ $('Watch KB Folder').item.json.name }}"
              },
              {
                "name": "file_id",
                "value": "={{ $('Watch KB Folder').item.json.id }}"
              },
              {
                "name": "ingested_at",
                "value": "={{ $now.toISO() }}"
              }
            ]
          }
        },
        "dataType": "binary",
        "textSplittingMode": "custom"
      },
      "typeVersion": 1.1
    },
    {
      "id": "2e8a0742-08cb-4453-ab21-8fe4192e0ce4",
      "name": "Token Splitter",
      "type": "@n8n/n8n-nodes-langchain.textSplitterTokenSplitter",
      "position": [
        896,
        864
      ],
      "parameters": {
        "chunkSize": 500,
        "chunkOverlap": 50
      },
      "typeVersion": 1
    },
    {
      "id": "bbdb26ba-6cd6-492e-94da-89e938d5f219",
      "name": "Log to KB Log",
      "type": "n8n-nodes-base.airtable",
      "position": [
        1088,
        496
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "id",
          "value": "appQvM6vBl23Vw171",
          "cachedResultName": "LinkedIn RAG Bot"
        },
        "table": {
          "__rl": true,
          "mode": "id",
          "value": "tblhbTmLDXnkxVN0q",
          "cachedResultName": "KB Log"
        },
        "columns": {
          "value": {
            "status": "success",
            "file_id": "={{ $('Watch KB Folder').item.json.id }}",
            "filename": "={{ $('Watch KB Folder').item.json.name }}",
            "timestamp": "={{ $now.toISO() }}",
            "chunks_upserted": "={{ $input.all().length }}"
          },
          "schema": [
            {
              "id": "filename",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "filename",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "file_id",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "file_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "chunks_upserted",
              "type": "number",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "chunks_upserted",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "options",
              "display": true,
              "options": [
                {
                  "name": "success",
                  "value": "success"
                },
                {
                  "name": "failed",
                  "value": "failed"
                },
                {
                  "name": "processing",
                  "value": "processing"
                }
              ],
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "timestamp",
              "type": "dateTime",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "create"
      },
      "credentials": {
        "airtableTokenApi": {
          "name": "<your credential>"
        }
      },
      "executeOnce": true,
      "typeVersion": 2.2
    },
    {
      "id": "96156692-b865-4d5d-b222-245935358536",
      "name": "Embeddings Google Gemini",
      "type": "@n8n/n8n-nodes-langchain.embeddingsGoogleGemini",
      "position": [
        656,
        688
      ],
      "parameters": {
        "modelName": "models/gemini-embedding-2"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "8a13ee60-4808-41f5-b7bd-42e5da49a23f",
      "name": "Overview - LinkedIn RAG Bot (Full System)",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -784,
        1200
      ],
      "parameters": {
        "width": 582,
        "height": 920,
        "content": "## LinkedIn Company Page RAG Bot \u2014 Full System (3 Workflows)\n\n### How it works\n1. Workflow 1 watches a Google Drive folder and automatically chunks, embeds, and indexes new documents into a Pinecone knowledge base.\n2. Workflow 2 receives incoming LinkedIn messages via a Unipile webhook, classifies each message's intent, and drafts a reply grounded in the Pinecone knowledge base.\n3. Every drafted reply is saved to Airtable, and either sent automatically or held for human approval depending on the autoSend toggle.\n4. Workflow 3 triggers when a human approves a pending draft in Airtable, sending the approved reply via Unipile and updating its status.\n5. All three workflows log errors to a shared Airtable Errors table for troubleshooting.\n\n### Setup steps\n- [ ] Reconnect the Google Drive credential (Workflow 1)\n- [ ] Reconnect the Unipile credential (all HTTP nodes currently return 401)\n- [ ] Replace the placeholder DSN (api1.unipile.com:13111) with your real Unipile DSN in Workflow 2 and Workflow 3's HTTP Request nodes\n- [ ] Create the Unipile webhook (source: messaging) pointing at Workflow 2's production URL once activated\n- [ ] Set up the Airtable \"Run a script\" automation on the Drafts table (trigger: status = approved) to call Workflow 3's webhook\n- [ ] Add your company name and description to Generate RAG Reply's system prompt (Workflow 2)\n- [ ] Confirm the Pinecone index dimensions match your Gemini embedding model output\n- [ ] Activate all three workflows once the above is complete\n\n### Customization\nFlip the autoSend field on Workflow 2's Config node to true once you trust the AI's replies, to skip human review and send automatically."
      },
      "typeVersion": 1
    },
    {
      "id": "ed27da41-5fe7-4f04-9b23-67b0963bda33",
      "name": "Group - Watch and download source file",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        16,
        320
      ],
      "parameters": {
        "color": 7,
        "width": 560,
        "height": 372,
        "content": "## Watch and download source file\n\nWatches the Google Drive folder for new or updated documents and downloads each one as binary data."
      },
      "typeVersion": 1
    },
    {
      "id": "b1c2cdaf-57cf-482b-9fec-1b114732900f",
      "name": "Group - Chunk, embed, and log to knowledge base",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        608,
        320
      ],
      "parameters": {
        "color": 7,
        "width": 644,
        "height": 680,
        "content": "## Chunk, embed, and log to knowledge base\n\nSplits the document into 500-token chunks (50 overlap), embeds them with Gemini, upserts into the Pinecone company-knowledge-base index (namespace: company-kb), then logs the result to Airtable KB Log."
      },
      "typeVersion": 1
    },
    {
      "id": "b9b218ee-35ea-46a4-86ef-da76d1d94f68",
      "name": "Airtable Approved Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        80,
        2560
      ],
      "parameters": {
        "path": "airtable-approved-send",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2.1
    },
    {
      "id": "a1764609-5a81-4645-a054-7e10b0a8f425",
      "name": "Extract Payload",
      "type": "n8n-nodes-base.set",
      "position": [
        320,
        2560
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "record_id",
              "name": "record_id",
              "type": "string",
              "value": "={{ $json.body?.record_id ?? $json.record_id }}"
            },
            {
              "id": "chat_id",
              "name": "chat_id",
              "type": "string",
              "value": "={{ $json.body?.chat_id ?? $json.chat_id }}"
            },
            {
              "id": "ai_draft",
              "name": "ai_draft",
              "type": "string",
              "value": "={{ $json.body?.ai_draft ?? $json.ai_draft }}"
            },
            {
              "id": "status",
              "name": "status",
              "type": "string",
              "value": "={{ $json.body?.status ?? $json.status }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "07492d02-eb2d-4647-9ca9-f7ff9805ab73",
      "name": "Valid Approved Payload?",
      "type": "n8n-nodes-base.if",
      "position": [
        544,
        2560
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "4dd291ed-c5b9-4cb4-9398-f23999706c96",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.record_id }}",
              "rightValue": ""
            },
            {
              "id": "0dc80ae1-a1e5-4aca-93b7-cbe0f5261890",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.chat_id }}",
              "rightValue": ""
            },
            {
              "id": "496d785a-2bf8-4ff0-905d-98bf3199fe3f",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.ai_draft }}",
              "rightValue": ""
            },
            {
              "id": "3bebce87-fd1e-46e8-8c5c-4148f2a9f1cd",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "approved"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "e6d25117-74bc-42f5-8d7d-120e890cc354",
      "name": "Send Approved Reply via Unipile",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueErrorOutput",
      "position": [
        880,
        2544
      ],
      "parameters": {
        "url": "=https://api1.unipile.com:13111/api/v1/chats/{{ $json.chat_id }}/messages",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "multipart-form-data",
        "authentication": "predefinedCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "text",
              "value": "={{ $json.ai_draft }}"
            }
          ]
        },
        "nodeCredentialType": "unipileApi"
      },
      "credentials": {
        "unipileApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "f0454927-90f5-4b39-9426-a26a94222035",
      "name": "Update Draft Status Sent",
      "type": "n8n-nodes-base.airtable",
      "position": [
        1248,
        2432
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "id",
          "value": "appQvM6vBl23Vw171",
          "cachedResultName": "LinkedIn RAG Bot"
        },
        "table": {
          "__rl": true,
          "mode": "id",
          "value": "tblPkjkyXfsHq5aa5",
          "cachedResultName": "Drafts"
        },
        "columns": {
          "value": {
            "id": "={{ $('Extract Payload').item.json.record_id }}",
            "status": "sent",
            "sent_at": "={{ $now.toISO() }}"
          },
          "schema": [
            {
              "id": "id",
              "type": "string",
              "display": true,
              "readOnly": true,
              "required": false,
              "displayName": "id",
              "defaultMatch": true
            },
            {
              "id": "sender_name",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "sender_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "sender_id",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "sender_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "chat_id",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "chat_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "category",
              "type": "options",
              "display": true,
              "options": [
                {
                  "name": "LEAD",
                  "value": "LEAD"
                },
                {
                  "name": "SUPPORT",
                  "value": "SUPPORT"
                },
                {
                  "name": "PARTNERSHIP",
                  "value": "PARTNERSHIP"
                },
                {
                  "name": "RECRUITMENT",
                  "value": "RECRUITMENT"
                },
                {
                  "name": "OTHER",
                  "value": "OTHER"
                }
              ],
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "category",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "confidence",
              "type": "number",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "confidence",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "their_message",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "their_message",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ai_draft",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "ai_draft",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "options",
              "display": true,
              "options": [
                {
                  "name": "pending",
                  "value": "pending"
                },
                {
                  "name": "approved",
                  "value": "approved"
                },
                {
                  "name": "sent",
                  "value": "sent"
                },
                {
                  "name": "rejected",
                  "value": "rejected"
                },
                {
                  "name": "send_failed",
                  "value": "send_failed"
                }
              ],
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "timestamp",
              "type": "dateTime",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "sent_at",
              "type": "dateTime",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "sent_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update"
      },
      "credentials": {
        "airtableTokenApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "692e93cd-4f11-41e9-b989-3bbfa8e13073",
      "name": "Mark Send Failed",
      "type": "n8n-nodes-base.airtable",
      "position": [
        1152,
        2704
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "id",
          "value": "appQvM6vBl23Vw171",
          "cachedResultName": "LinkedIn RAG Bot"
        },
        "table": {
          "__rl": true,
          "mode": "id",
          "value": "tblPkjkyXfsHq5aa5",
          "cachedResultName": "Drafts"
        },
        "columns": {
          "value": {
            "id": "={{ $('Extract Payload').item.json.record_id }}",
            "status": "send_failed"
          },
          "schema": [
            {
              "id": "id",
              "type": "string",
              "display": true,
              "readOnly": true,
              "required": false,
              "displayName": "id",
              "defaultMatch": true
            },
            {
              "id": "sender_name",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "sender_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "sender_id",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "sender_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "chat_id",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "chat_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "category",
              "type": "options",
              "display": true,
              "options": [
                {
                  "name": "LEAD",
                  "value": "LEAD"
                },
                {
                  "name": "SUPPORT",
                  "value": "SUPPORT"
                },
                {
                  "name": "PARTNERSHIP",
                  "value": "PARTNERSHIP"
                },
                {
                  "name": "RECRUITMENT",
                  "value": "RECRUITMENT"
                },
                {
                  "name": "OTHER",
                  "value": "OTHER"
                }
              ],
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "category",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "confidence",
              "type": "number",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "confidence",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "their_message",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "their_message",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ai_draft",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "ai_draft",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "options",
              "display": true,
              "options": [
                {
                  "name": "pending",
                  "value": "pending"
                },
                {
                  "name": "approved",
                  "value": "approved"
                },
                {
                  "name": "sent",
                  "value": "sent"
                },
                {
                  "name": "rejected",
                  "value": "rejected"
                },
                {
                  "name": "send_failed",
                  "value": "send_failed"
                }
              ],
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "timestamp",
              "type": "dateTime",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "sent_at",
              "type": "dateTime",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "sent_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update"
      },
      "credentials": {
        "airtableTokenApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "d817e686-8529-4e22-80ee-67a286dc8338",
      "name": "Log Send Error",
      "type": "n8n-nodes-base.airtable",
      "position": [
        1328,
        2704
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "id",
          "value": "appQvM6vBl23Vw171",
          "cachedResultName": "LinkedIn RAG Bot"
        },
        "table": {
          "__rl": true,
          "mode": "id",
          "value": "tblNqamVByZhR3TBb",
          "cachedResultName": "Errors"
        },
        "columns": {
          "value": {
            "stage": "Workflow 3 - Send Approved Reply",
            "chat_id": "={{ $('Extract Payload').item.json.chat_id }}",
            "timestamp": "={{ $now.toISO() }}",
            "error_message": "={{ $json.error?.message ?? JSON.stringify($json.error) }}"
          },
          "schema": [
            {
              "id": "stage",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "stage",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "chat_id",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "chat_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "error_message",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "error_message",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "timestamp",
              "type": "dateTime",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "create"
      },
      "credentials": {
        "airtableTokenApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "4d94fa75-0b22-46f3-a05e-bf7874f3f40d",
      "name": "Log Invalid Payload",
      "type": "n8n-nodes-base.airtable",
      "position": [
        880,
        2784
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "id",
          "value": "appQvM6vBl23Vw171",
          "cachedResultName": "LinkedIn RAG Bot"
        },
        "table": {
          "__rl": true,
          "mode": "id",
          "value": "tblNqamVByZhR3TBb",
          "cachedResultName": "Errors"
        },
        "columns": {
          "value": {
            "stage": "Workflow 3 - Validate Payload",
            "chat_id": "={{ $json.chat_id || \"unknown\" }}",
            "timestamp": "={{ $now.toISO() }}",
            "error_message": "={{ \"Invalid or incomplete payload received from Airtable automation: \" + JSON.stringify($json) }}"
          },
          "schema": [
            {
              "id": "stage",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "stage",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "chat_id",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "chat_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "error_message",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "error_message",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "timestamp",
              "type": "dateTime",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "create"
      },
      "credentials": {
        "airtableTokenApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "c4bbec36-9715-4d3d-92d7-14ad46af7b79",
      "name": "Group - Receive and validate approval payload",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        32,
        2368
      ],
      "parameters": {
        "color": 7,
        "width": 740,
        "height": 360,
        "content": "## Receive and validate approval payload\n\nReceives the webhook fired by Airtable's automation script when a draft is approved, extracts the payload fields, and validates that all required fields are present with status = approved. Invalid payloads are logged to Airtable (Log Invalid Payload sits just below this cluster)."
      },
      "typeVersion": 1
    },
    {
      "id": "ef64cebd-d643-4a05-bbb8-304d33ca3b20",
      "name": "Group - Send the approved reply via Unipile",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        784,
        2320
      ],
      "parameters": {
        "color": 7,
        "width": 266,
        "height": 408,
        "content": "## Send the approved reply via Unipile\n\nPosts the approved draft text to the LinkedIn conversation via Unipile's send-message endpoint."
      },
      "typeVersion": 1
    },
    {
      "id": "18ad1d4a-ab6d-4c2f-ad5e-37291965b82a",
      "name": "Group - Update or flag draft status",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1072,
        2240
      ],
      "parameters": {
        "color": 7,
        "width": 460,
        "height": 656,
        "content": "## Update or flag draft status\n\nMarks the Airtable draft as sent on success, or as send_failed with an accompanying error log entry on failure."
      },
      "typeVersion": 1
    },
    {
      "id": "21a89f87-9e23-464c-a848-4739df214fb6",
      "name": "Unipile Inbox Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        64,
        1536
      ],
      "parameters": {
        "path": "unipile-inbox",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2.1
    },
    {
      "id": "a3a72865-883b-4a48-86c8-80e23d475aa0",
      "name": "Config",
      "type": "n8n-nodes-base.set",
      "position": [
        288,
        1536
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "auto-send",
              "name": "autoSend",
              "type": "boolean",
              "value": false
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "d16c4497-5d12-46f3-9959-99855b9ee211",
      "name": "Extract & Normalize Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        512,
        1536
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "event",
              "name": "event",
              "type": "string",
              "value": "={{ $json.body?.event ?? $json.event }}"
            },
            {
              "id": "feature",
              "name": "feature",
              "type": "string",
              "value": "={{ $json.body?.account_info?.feature ?? $json.account_info?.feature }}"
            },
            {
              "id": "user_id",
              "name": "user_id",
              "type": "string",
              "value": "={{ $json.body?.account_info?.user_id ?? $json.account_info?.user_id }}"
            },
            {
              "id": "chat_id",
              "name": "chat_id",
              "type": "string",
              "value": "={{ $json.body?.chat_id ?? $json.chat_id }}"
            },
            {
              "id": "message_text",
              "name": "message_text",
              "type": "string",
              "value": "={{ $json.body?.message ?? $json.message }}"
            },
            {
              "id": "sender_id",
              "name": "sender_id",
              "type": "string",
              "value": "={{ $json.body?.sender?.attendee_provider_id ?? $json.sender?.attendee_provider_id }}"
            },
            {
              "id": "sender_name",
              "name": "sender_name",
              "type": "string",
              "value": "={{ $json.body?.sender?.attendee_name ?? $json.sender?.attendee_name }}"
            },
            {
              "id": "timestamp",
              "name": "timestamp",
              "type": "string",
              "value": "={{ $json.body?.timestamp ?? $json.timestamp }}"
            },
            {
              "id": "account_id",
              "name": "account_id",
              "type": "string",
              "value": "={{ $json.body?.account_id ?? $json.account_id }}"
            },
            {
              "id": "session_id",
              "name": "session_id",
              "type": "string",
              "value": "={{ $json.body?.sender?.attendee_provider_id ?? $json.sender?.attendee_provider_id }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "2d9c1890-3453-4868-9c28-6f5e9a8d2d54",
      "name": "Valid Inbound Message?",
      "type": "n8n-nodes-base.if",
      "position": [
        800,
        1536
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "ade8393e-f5ee-44a9-b83e-77a0a08603b8",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.event }}",
              "rightValue": "message_received"
            },
            {
              "id": "53602d50-e6d4-4f76-8adb-38b8edddaa60",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.feature }}",
              "rightValue": "organization"
            },
            {
              "id": "55142b00-4cf2-479d-8f7c-c7ff198e3f00",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.sender_id }}",
              "rightValue": "={{ $json.user_id }}"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "b73fac2b-4258-4cf3-8726-048aa805f8ab",
      "name": "Fetch Thread History",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueErrorOutput",
      "position": [
        1024,
        1536
      ],
      "parameters": {
        "url": "=https://api1.unipile.com:13111/api/v1/chats/{{ $json.chat_id }}/messages",
        "options": {},
        "sendQuery": true,
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "limit",
              "value": "6"
            }
          ]
        },
        "nodeCredentialType": "unipileApi"
      },
      "credentials": {
        "unipileApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "96b6a02a-99ca-45c9-990e-f84aaa396dfc",
      "name": "Format Thread Context",
      "type": "n8n-nodes-base.code",
      "position": [
        1248,
        1440
      ],
      "parameters": {
        "jsCode": "const raw = $input.first().json.items || $input.first().json || [];\nconst newestFirst = Array.isArray(raw) ? raw : [];\n// Unipile returns messages newest-first; reverse to chronological order (oldest -> newest)\nconst chronological = [...newestFirst].reverse();\n// Drop the newest message from the transcript since it's already surfaced separately\n// as \"message_text\" (the latest inbound message) - avoids duplicating it in the prompt\nconst priorMessages = chronological.slice(0, -1);\nconst lines = priorMessages.map((m) => {\n  const who = m.is_sender ? 'Page' : 'Them';\n  return who + ': ' + (m.text || '');\n});\nconst context = lines.length > 0 ? lines.join('\\n') : '(No prior messages - this is the start of the conversation.)';\nconst extract = $('Extract & Normalize Fields').first().json;\nreturn [{\n  json: {\n    context: context,\n    message_text: extract.message_text,\n    sender_name: extract.sender_name,\n    chat_id: extract.chat_id\n  },\n  pairedItem: { item: 0 }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "0ccbd569-dfba-4abd-9e87-8b30dac3d2c8",
      "name": "Claude via OpenRouter",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        1472,
        1664
      ],
      "parameters": {
        "model": "openrouter/free",
        "options": {}
      },
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "edef26aa-09d2-4553-920c-954586aa5701",
      "name": "Conversation Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        1600,
        1664
      ],
      "parameters": {
        "sessionKey": "={{ $('Extract & Normalize Fields').first().json.session_id }}",
        "sessionIdType": "customKey",
        "contextWindowLength": 4
      },
      "typeVersion": 1.4
    },
    {
      "id": "7a901bb5-62bd-4603-b084-a71ca598aa13",
      "name": "Classification Schema",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1728,
        1664
      ],
      "parameters": {
        "jsonSchemaExample": "{ \"category\": \"LEAD\", \"confidence\": 0.95, \"reason\": \"Asked about pricing\" }"
      },
      "typeVersion": 1.3
    },
    {
      "id": "e129990c-ba17-4448-aa9b-fcf197869fca",
      "name": "Is Spam?",
      "type": "n8n-nodes-base.if",
      "position": [
        1872,
        1440
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "e43bc4b2-c9b9-4cbd-a557-4405e2b2f238",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.output.category }}",
              "rightValue": "SPAM"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "cd32dbc0-6d58-418e-9c9a-647ee9153feb",
      "name": "Log Spam",
      "type": "n8n-nodes-base.airtable",
      "position": [
        2240,
        1232
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "id",
          "value": "appQvM6vBl23Vw171",
          "cachedResultName": "LinkedIn RAG Bot"
        },
        "table": {
          "__rl": true,
          "mode": "id",
          "value": "tblv2pj2nzHVDgGBP",
          "cachedResultName": "Spam"
        },
        "columns": {
          "value": {
            "reason": "={{ $json.output.reason }}",
            "sender_id": "={{ $('Extract & Normalize Fields').first().json.sender_id }}",
            "timestamp": "={{ $now.toISO() }}",
            "sender_name": "={{ $('Format Thread Context').first().json.sender_name }}",
            "their_message": "={{ $('Format Thread Context').first().json.message_text }}"
          },
          "schema": [
            {
              "id": "sender_name",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "sender_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "sender_id",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "sender_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "their_message",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "their_message",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "reason",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "reason",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "timestamp",
              "type": "dateTime",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "create"
      },
      "credentials": {
        "airtableTokenApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "0a65edaf-6401-4ef5-aa94-3e7959dc1e61",
      "name": "Generate RAG Reply",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        2176,
        1632
      ],
      "parameters": {
        "text": "=Conversation so far:\n{{ $('Format Thread Context').item.json.context }}\n\nLatest message from {{ $('Format Thread Context').item.json.sender_name }}: {{ $('Format Thread Context').item.json.message_text }}",
        "options": {
          "systemMessage": "=You are the LinkedIn page assistant for our company. Search the knowledge base tool before every reply. Never invent pricing, features, or facts. If unsure, say a human will follow up shortly. Reply in the language the sender used. Keep replies to 3-5 sentences, LinkedIn inbox style. Message category: {{ $('Classify Message').item.json.output.category }} ({{ $('Classify Message').item.json.output.reason }})"
        },
        "promptType": "define"
      },
      "typeVersion": 3.1
    },
    {
      "id": "d8e4f5a6-c279-4fa3-9f15-bab0d15ae4c1",
      "name": "Knowledge Base",
      "type": "@n8n/n8n-nodes-langchain.vectorStorePinecone",
      "position": [
        2208,
        1808
      ],
      "parameters": {
        "mode": "retrieve-as-tool",
        "options": {
          "pineconeNamespace": "company-kb"
        },
        "pineconeIndex": {
          "__rl": true,
          "mode": "list",
          "value": "company-knowledge-base",
          "cachedResultName": "company-knowledge-base"
        },
        "toolDescription": "Search the company knowledge base for facts about products, pricing, features, and policies before answering a customer question.",
        "includeDocumentMetadata": false
      },
      "credentials": {
        "pineconeApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "bb7b963c-f62e-41c3-8193-2aa37a2dd6be",
      "name": "Query Embeddings (Gemini)",
      "type": "@n8n/n8n-nodes-langchain.embeddingsGoogleGemini",
      "position": [
        2288,
        1936
      ],
      "parameters": {
        "modelName": "models/gemini-embedding-2"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "10060da7-9cbb-4f16-aded-22d1f6c0d046",
      "name": "Save Draft to Airtable",
      "type": "n8n-nodes-base.airtable",
      "position": [
        2608,
        1632
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "id",
          "value": "appQvM6vBl23Vw171",
          "cachedResultName": "LinkedIn RAG Bot"
        },
        "table": {
          "__rl": true,
          "mode": "id",
          "value": "tblPkjkyXfsHq5aa5",
          "cachedResultName": "Drafts"
        },
        "columns": {
          "value": {
            "status": "pending",
            "chat_id": "={{ $('Extract & Normalize Fields').first().json.chat_id }}",
            "ai_draft": "={{ $json.output }}",
            "category": "={{ $('Classify Message').first().json.output.category }}",
            "sender_id": "={{ $('Extract & Normalize Fields').first().json.sender_id }}",
            "timestamp": "={{ $now.toISO() }}",
            "confidence": "={{ $('Classify Message').first().json.output.confidence }}",
            "sender_name": "={{ $('Format Thread Context').first().json.sender_name }}",
            "their_message": "={{ $('Format Thread Context').first().json.message_text }}"
          },
          "schema": [
            {
              "id": "id",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "id",
              "defaultMatch": true
            },
            {
              "id": "sender_name",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "sender_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "sender_id",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "sender_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "chat_id",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "chat_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "category",
              "type": "options",
              "display": true,
              "options": [
                {
                  "name": "LEAD",
                  "value": "LEAD"
                },
                {
                  "name": "SUPPORT",
                  "value": "SUPPORT"
                },
                {
                  "name": "PARTNERSHIP",
                  "value": "PARTNERSHIP"
                },
                {
                  "name": "RECRUITMENT",
                  "value": "RECRUITMENT"
                },
                {
                  "name": "OTHER",
                  "value": "OTHER"
                }
              ],
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "category",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "confidence",
              "type": "number",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "confidence",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "their_message",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "their_message",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ai_draft",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "ai_draft",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "options",
              "display": true,
              "options": [
                {
                  "name": "pending",
                  "value": "pending"
                },
                {
                  "name": "approved",
                  "value": "approved"
                },
                {
                  "name": "sent",
                  "value": "sent"
                },
                {
                  "name": "rejected",
                  "value": "rejected"
                },
                {
                  "name": "send_failed",
                  "value": "send_failed"
                }
              ],
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "timestamp",
              "type": "dateTime",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "sent_at",
              "type": "dateTime",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "sent_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "chat_id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "upsert"
      },
      "credentials": {
        "airtableTokenApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "06ecb5c2-a85f-4bf8-8819-7d21cc1b20dc",
      "name": "Auto-Send Enabled?",
      "type": "n8n-nodes-base.if",
      "position": [
        2848,
        1632
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "operator": {
                "type": "boolean",
                "operation": "true"
              },
              "leftValue": "={{ $('Config').item.json.autoSend }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "c574e35a-5dd8-46bd-b55c-f77b92a9db2d",
      "name": "Send Reply via Unipile",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueErrorOutput",
      "position": [
        3152,
        1648
      ],
      "parameters": {
        "url": "=https://api1.unipile.com:13111/api/v1/chats/{{ $('Extract & Normalize Fields').item.json.chat_id }}/messages",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "multipart-form-data",
        "authentication": "predefinedCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "text",
              "value": "={{ $('Generate RAG Reply').item.json.output }}"
            }
          ]
        },
        "nodeCredentialType": "unipileApi"
      },
      "credentials": {
        "unipileApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "38f7b1c3-2b18-41ec-ae22-1f67363f6637",
      "name": "Log Fetch Error",
      "type": "n8n-nodes-base.airtable",
      "position": [
        1248,
        1632
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "id",
          "value": "appQvM6vBl23Vw171",
          "cachedResultName": "LinkedIn RAG Bot"
        },
        "table": {
          "__rl": true,
          "mode": "id",
          "value": "tblNqamVByZhR3TBb",
          "cachedResultName": "Errors"
        },
        "columns": {
          "value": {
            "stage": "Fetch Thread History",
            "chat_id": "={{ $('Extract & Normalize Fields').item.json.chat_id }}",
            "timestamp": "={{ $now.toISO() }}",
            "error_message": "={{ $json.error?.message ?? JSON.stringify($json.error) }}"
          },
          "schema": [
            {
              "id": "stage",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "stage",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "chat_id",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "chat_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "error_message",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "error_message",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "timestamp",
              "type": "dateTime",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "create"
      },
      "credentials": {
        "airtableTokenApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "9e94f1be-d685-482d-90a9-8a716b829853",
      "name": "Classify Message",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1536,
        1440
      ],
      "parameters": {
        "text": "=Conversation so far:\n{{ $json.context }}\n\nLatest message from {{ $json.sender_name }}: {{ $json.message_text }}",
        "options": {
          "systemMessage": "Classify the latest LinkedIn message into exactly one category: LEAD (product, service, pricing, or demo interest), SUPPORT (existing customer needing help), PARTNERSHIP (business collaboration proposal), RECRUITMENT (job inquiry or recruiter outreach), SPAM (irrelevant, mass outreach, or bot), OTHER (anything else). Return the category, a confidence score between 0 and 1, and a short reason. Respond with JSON only."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3.1
    },
    {
      "id": "0a0f3093-5f2c-42b8-8f22-8c2a4fd24615",
      "name": "Group - Receive webhook and normalize payload",
      "type": "n8n-

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

Automatically ingest your knowledge base, monitor your LinkedIn company page inbox, and reply to leads and customers with AI-drafted, source-grounded answers. Classifies every message, checks for spam, drafts replies using Claude and Pinecone RAG, and lets you auto-send or…

Source: https://n8n.io/workflows/16963/ — 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

Alfred (funcional). Uses gmailTool, googleCalendarTool, gmail, embeddingsOpenAi. Event-driven trigger; 83 nodes.

Gmail Tool, Google Calendar Tool, Gmail +24
AI & RAG

This comprehensive workflow bundle is designed as a powerful starter kit, enabling you to build a multi-functional AI assistant on Telegram. It seamlessly integrates AI-powered voice interactions, an

Telegram Trigger, Telegram, OpenAI +19
AI & RAG

Agent IA Projet Client. Uses executeWorkflowTrigger, lmChatOpenAi, toolWorkflow, vectorStoreQdrant. Event-driven trigger; 79 nodes.

Execute Workflow Trigger, OpenAI Chat, Tool Workflow +16
AI & RAG

This advanced n8n workflow automates the full lead enrichment, qualification, and personalized outreach process tailored specifically for the B2B real estate sector. Integrating top platforms like Api

N8N Nodes Fillout, OpenAI Chat, Pinecone Vector Store +11
AI & RAG

This n8n template automatically classifies incoming emails (Sales, Support, Internal, Finance, Promotions) and routes them to a dedicated OpenAI LLM Agent for processing. Depending on the category, th

OpenAI, Gmail, Text Classifier +16