{
  "id": "jSeYyfezn59gcONp",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "AI Meeting Intelligence System: Zoom Transcription, RAG Memory & Decision Tracking",
  "tags": [],
  "nodes": [
    {
      "id": "c22e9626-df7c-4ff2-a673-acb5e0e56b9b",
      "name": "Zoom Meeting Trigger (Recording Webhook)",
      "type": "n8n-nodes-base.webhook",
      "position": [
        304,
        928
      ],
      "parameters": {
        "path": "zoom-recording",
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "cb29b553-2a57-4ed5-b5ed-5dd27f8eac11",
      "name": "Meeting Payload Parser",
      "type": "n8n-nodes-base.set",
      "position": [
        528,
        928
      ],
      "parameters": {
        "values": {
          "string": [
            {
              "name": "recording_url",
              "value": "={{$json.body.recording_url}}"
            },
            {
              "name": "meeting_title",
              "value": "={{$json.body.meeting_title}}"
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 2
    },
    {
      "id": "05a88815-94e7-402d-85ba-d5e888de8f85",
      "name": "Audio File Downloader (Zoom Cloud Fetch)",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        752,
        928
      ],
      "parameters": {
        "url": "={{$json.recording_url}}",
        "options": {}
      },
      "typeVersion": 4
    },
    {
      "id": "b097d312-0065-4a4c-ac84-bfa92a8c4881",
      "name": "Transcript Normalizer",
      "type": "n8n-nodes-base.code",
      "position": [
        1200,
        928
      ],
      "parameters": {
        "jsCode": "const text = $json.text;\n\nreturn [{\n  json: {\n    transcript: text\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "608e3d70-8b58-4dda-acad-8a39b0876251",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        208,
        688
      ],
      "parameters": {
        "color": 7,
        "width": 1152,
        "height": 496,
        "content": "## Zoom Ingestion & Transcript Pipeline\nThis section receives Zoom meeting data through a webhook, extracts recording URL and metadata, downloads the audio file and converts speech into text using OpenAI Whisper. The output is normalized into a clean transcript format, ensuring consistent structure before AI analysis begins."
      },
      "typeVersion": 1
    },
    {
      "id": "8c306a35-7b14-49ac-acbd-39001d0f3469",
      "name": "Meeting Intelligence Engine (LLM Processor)",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1552,
        928
      ],
      "parameters": {
        "text": "=You are an AI meeting intelligence system.\n\nStep 1: Analyze the meeting transcript:\n{{ $json.transcript }}\n\nStep 2: Extract:\n- Clear summary\n- Final decision (if any)\n- Action items (with owners if possible)\n\nStep 3: Use the tool to search past meetings related to this topic.\n\nStep 4: Detect contradictions:\n- Compare current decision with past decisions\n- If conflict exists \u2192 explain clearly\n- If no conflict \u2192 say \"No contradiction found\"\n\nBe precise and structured.",
        "options": {},
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3.1
    },
    {
      "id": "0cdc94e2-b0f7-45e7-b16c-610686624402",
      "name": "GPT-4o Reasoning Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1456,
        1136
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o",
          "cachedResultName": "gpt-4o"
        },
        "options": {},
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "bc5d3aa0-7c37-4ed0-8aae-094581aa0183",
      "name": "AI Response Validator (JSON Enforcer)",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1808,
        1136
      ],
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"summary\": {\n\t\t\t\"type\": \"string\"\n\t\t},\n        \"decision\": {\n\t\t\t\"type\": \"string\"\n\t\t},\n        \"action_items\":{\n\t\t\t\"type\": \"array\",\n\t\t\t\"items\": {\n\t\t\t\t\"type\": \"string\"\n\t\t\t}\n\t\t},\n\t\t\"contradiction_report\": {\n\t\t\t\"type\": \"string\"\n\t\t}\n\t}\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "39bb9e81-cee7-4480-a2f6-00cdc8d961f0",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1392,
        688
      ],
      "parameters": {
        "color": 7,
        "width": 592,
        "height": 656,
        "content": "## Meeting Intelligence (AI Analysis Core)\n\nThis section processes the transcript using GPT-4o. It extracts summary, decision, action items and contradiction analysis. The structured output parser ensures strict JSON formatting so downstream systems like database storage and email formatting work reliably without schema errors or inconsistencies."
      },
      "typeVersion": 1
    },
    {
      "id": "46ddd23f-2864-4566-af6e-d151918c19d1",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1392,
        1376
      ],
      "parameters": {
        "color": 7,
        "width": 592,
        "height": 560,
        "content": "## RAG Memory Retrieval System\nThis section enables retrieval-augmented intelligence. It converts queries into embeddings and searches past meeting decisions stored in Supabase. This allows the system to compare current decisions with historical data and detect contradictions or repeated patterns across meetings."
      },
      "typeVersion": 1
    },
    {
      "id": "b91ff133-fe17-46c1-be4c-59ce26056579",
      "name": "Historical Meeting Search Engine (RAG Retriever)",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
      "position": [
        1568,
        1568
      ],
      "parameters": {
        "mode": "retrieve-as-tool",
        "options": {},
        "tableName": {
          "__rl": true,
          "mode": "list",
          "value": "meeting_memories",
          "cachedResultName": "meeting_memories"
        },
        "toolDescription": "Search past meeting summaries, decisions and action items.\nFocus on retrieving relevant decisions for comparison."
      },
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "41032359-58a5-41a3-b492-9d238428cd54",
      "name": "Semantic Embedding Generator",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "position": [
        1568,
        1760
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "09716848-6809-4690-a894-45d61f5b18cc",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2016,
        688
      ],
      "parameters": {
        "color": 7,
        "width": 832,
        "height": 496,
        "content": "## Deduplication & Workflow Safety Layer\nThis section prevents duplicate processing by generating a unique hash for each transcript. It queries Supabase to check existing records and evaluates results. If a duplicate exists, the workflow stops; otherwise, it continues. This ensures data integrity and avoids redundant AI processing and storage costs."
      },
      "typeVersion": 1
    },
    {
      "id": "31ceb05c-3985-4999-b111-6134f5cc493a",
      "name": "Transcript Fingerprint Generator",
      "type": "n8n-nodes-base.code",
      "position": [
        2080,
        928
      ],
      "parameters": {
        "jsCode": "// Simple hash without crypto (works in n8n)\n\nconst text = $('Mock Data Input').first().json.transcript ||  $input.first().json.content || '';\n\nlet hash = 0;\nfor (let i = 0; i < text.length; i++) {\n  const char = text.charCodeAt(i);\n  hash = ((hash << 5) - hash) + char;\n  hash |= 0;\n}\n\nreturn [{\n  ...$json,\n  transcript_hash: hash.toString()\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "f33588a5-4cf3-437a-9022-39c9f892c68b",
      "name": "Supabase Duplicate Check Query",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "position": [
        2272,
        928
      ],
      "parameters": {
        "url": "https://**.supabase.co/rest/v1/meeting_memories",
        "options": {},
        "sendQuery": true,
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "metadata -> metadata ->> transcript_hash",
              "value": "=eq.{{ $json.transcript_hash }}"
            }
          ]
        },
        "nodeCredentialType": "supabaseApi"
      },
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        },
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4,
      "alwaysOutputData": true
    },
    {
      "id": "b1278c7d-f6ce-4787-8f50-2cf936aa9727",
      "name": "Duplicate Result Analyzer",
      "type": "n8n-nodes-base.code",
      "position": [
        2464,
        928
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\n\nconst valid = items.filter(i => i.json && i.json.id);\n\nreturn [\n  {\n    json: {\n      hasDuplicate: valid.length > 0,\n      count: valid.length\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "95683638-f980-4417-a2af-d8a86b0164f8",
      "name": "Duplicate Gate Controller",
      "type": "n8n-nodes-base.if",
      "position": [
        2640,
        928
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "f9ec8ac0-0700-4ba8-8b9b-0bd2964cbe4e",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.hasDuplicate }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3,
      "alwaysOutputData": false
    },
    {
      "id": "26703b8f-fb16-4c02-a722-9f5e6e452dac",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2880,
        688
      ],
      "parameters": {
        "color": 7,
        "width": 544,
        "height": 656,
        "content": "## Memory Storage (Vector Database Layer)\nThis section formats AI output into structured memory format and converts it into embeddings. It stores both content and metadata in Supabase vector database. This enables long-term semantic search, retrieval and contextual intelligence across past meetings."
      },
      "typeVersion": 1
    },
    {
      "id": "0fb3833e-0819-4e96-9bef-d048639619ec",
      "name": "Structured Memory Builder",
      "type": "n8n-nodes-base.code",
      "position": [
        2944,
        944
      ],
      "parameters": {
        "jsCode": "\nconst input = $('Mock Data Input').first().json;\nconst data = $('Transcript Fingerprint Generator').first().json.output;\n\nreturn [{\n  content: `\nMeeting: $('Mock Data Input').first().json.meeting_title\nDate: $('Mock Data Input').first().json.meeting_date\n\nSummary:\n${data.summary}\n\nDecision:\n${data.decision}\n\nAction Items:\n${data.action_items.join(\", \")}\n\nContradiction:\n${data.contradiction_report}\n  `,\n  metadata: {\n    meeting_title: input.meeting_title,\n    date: input.meeting_date,\n    decision: data.decision,\n    transcript_hash: $('Transcript Fingerprint Generator').first().json.transcript_hash,\n    hashDataWithTranscript: $('Audio Transcription (OpenAI Whisper)')\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "0f845fed-458b-41c9-b1e9-7a7216981b64",
      "name": "Metadata Attachment Engine",
      "type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
      "position": [
        3280,
        1168
      ],
      "parameters": {
        "options": {
          "metadata": {
            "metadataValues": [
              {
                "name": "metadata",
                "value": "={{$json.metadata}}"
              }
            ]
          }
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "2283204f-939d-4a4f-8d79-d5c89d4e1474",
      "name": "Vector Embedding Generator1",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "position": [
        3024,
        1168
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "6726577a-501c-49f6-87ba-468073bd741f",
      "name": "Meeting Memory Storage (Vector DB Insert)",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
      "position": [
        3120,
        944
      ],
      "parameters": {
        "mode": "insert",
        "options": {},
        "tableName": {
          "__rl": true,
          "mode": "list",
          "value": "meeting_memories",
          "cachedResultName": "meeting_memories"
        }
      },
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "fce20c57-8a01-4976-b21f-fd90f44bc8a2",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3456,
        688
      ],
      "parameters": {
        "color": 7,
        "width": 336,
        "height": 496,
        "content": "## Notification System (Email Output Layer)\nThis section delivers the final structured meeting insights to stakeholders via email. It includes summary, decision, action items and contradiction report, ensuring teams receive immediate actionable intelligence after each meeting."
      },
      "typeVersion": 1
    },
    {
      "id": "d475e6ac-e5db-49c8-9642-0d63e2f9877e",
      "name": "Meeting Summary Email Dispatcher",
      "type": "n8n-nodes-base.gmail",
      "position": [
        3552,
        944
      ],
      "parameters": {
        "sendTo": "=",
        "message": "=Meeting Summary  \n\nTitle: {{ $('Mock Data Input').item.json.meeting_title }} \n\nDate: {{ $('Mock Data Input').item.json.meeting_date }}  \n\nSummary: {{ $('Meeting Intelligence Engine (LLM Processor)').item.json.output.summary }}  \n\nDecision: {{ $('Structured Memory Builder').item.json.metadata.decision }} \n\nAction Items: {{ $('Meeting Intelligence Engine (LLM Processor)').item.json.output.action_items[0] }} \n\nContradiction Report: {{ $('Meeting Intelligence Engine (LLM Processor)').item.json.output.contradiction_report }}",
        "options": {},
        "subject": "=Meeting Summary: {{ $('Mock Data Input').item.json.meeting_title }}",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "e4048639-6465-45d4-934b-cdf3eca2ef26",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        208,
        224
      ],
      "parameters": {
        "width": 1152,
        "height": 448,
        "content": "## Workflow Overview & Setup Guide\n\nThis workflow is an end-to-end AI-powered meeting intelligence system built on n8n. It starts with a Zoom webhook that receives meeting recording data. The system downloads the audio file and converts speech into structured text using OpenAI Whisper transcription.\n\nThe transcript is then processed by a GPT-4o-based intelligence engine, which extracts a summary, final decision, action items and contradiction analysis. The output is strictly validated using a structured parser to ensure JSON consistency.\n\nBefore storing or processing further, a deduplication layer generates a unique transcript hash and checks Supabase for existing records. If a duplicate is found, processing is stopped; otherwise, the workflow continues.\n\nNext, the system uses a RAG (Retrieval-Augmented Generation) layer powered by Supabase vector database to fetch past meeting decisions. This allows contextual comparison and contradiction detection across historical meetings.\n\nFinally, the processed data is stored as vector embeddings in Supabase for long-term memory and semantic search. A final email is sent to stakeholders containing meeting summary, decisions and action items.\n\n**Setup Requirements:**\n\n- Configure Zoom webhook for recording events\n- Add OpenAI API key (Whisper + GPT-4o)\n- Set up Supabase table meeting_memories with vector support\n- Enable Gmail credentials for email output\n- Ensure webhook endpoint is publicly accessible"
      },
      "typeVersion": 1
    },
    {
      "id": "7fa1fbf3-1ad0-4981-bb80-82bb3073ab05",
      "name": "Audio Transcription (OpenAI Whisper)",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        976,
        928
      ],
      "parameters": {
        "options": {},
        "resource": "audio",
        "operation": "transcribe"
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "7cb40567-7b69-4048-bb5d-fac32a07a44d",
  "connections": {
    "Transcript Normalizer": {
      "main": [
        [
          {
            "node": "Meeting Intelligence Engine (LLM Processor)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GPT-4o Reasoning Model": {
      "ai_languageModel": [
        [
          {
            "node": "Meeting Intelligence Engine (LLM Processor)",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Meeting Payload Parser": {
      "main": [
        [
          {
            "node": "Audio File Downloader (Zoom Cloud Fetch)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Duplicate Gate Controller": {
      "main": [
        [],
        [
          {
            "node": "Structured Memory Builder",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Duplicate Result Analyzer": {
      "main": [
        [
          {
            "node": "Duplicate Gate Controller",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Memory Builder": {
      "main": [
        [
          {
            "node": "Meeting Memory Storage (Vector DB Insert)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Metadata Attachment Engine": {
      "ai_document": [
        [
          {
            "node": "Meeting Memory Storage (Vector DB Insert)",
            "type": "ai_document",
            "index": 0
          }
        ]
      ]
    },
    "Vector Embedding Generator1": {
      "ai_embedding": [
        [
          {
            "node": "Meeting Memory Storage (Vector DB Insert)",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Semantic Embedding Generator": {
      "ai_embedding": [
        [
          {
            "node": "Historical Meeting Search Engine (RAG Retriever)",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Supabase Duplicate Check Query": {
      "main": [
        [
          {
            "node": "Duplicate Result Analyzer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Transcript Fingerprint Generator": {
      "main": [
        [
          {
            "node": "Supabase Duplicate Check Query",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Audio Transcription (OpenAI Whisper)": {
      "main": [
        [
          {
            "node": "Transcript Normalizer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Response Validator (JSON Enforcer)": {
      "ai_outputParser": [
        [
          {
            "node": "Meeting Intelligence Engine (LLM Processor)",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Audio File Downloader (Zoom Cloud Fetch)": {
      "main": [
        [
          {
            "node": "Audio Transcription (OpenAI Whisper)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Zoom Meeting Trigger (Recording Webhook)": {
      "main": [
        [
          {
            "node": "Meeting Payload Parser",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Meeting Memory Storage (Vector DB Insert)": {
      "main": [
        [
          {
            "node": "Meeting Summary Email Dispatcher",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Meeting Intelligence Engine (LLM Processor)": {
      "main": [
        [
          {
            "node": "Transcript Fingerprint Generator",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Historical Meeting Search Engine (RAG Retriever)": {
      "ai_tool": [
        [
          {
            "node": "Meeting Intelligence Engine (LLM Processor)",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    }
  }
}