{
  "name": "Zoom Transcripts",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "zoom-transcript-webhook",
        "responseMode": "responseNode",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        0,
        -336
      ],
      "id": "be168675-6292-49cf-a2f8-f88e5689446c",
      "name": "Webhook"
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Function Node nach dem Webhook\nconst body = $input.item.json.body;\n\n// Zoom Verification\nif (body.event === 'endpoint.url_validation') {\n  const crypto = require('crypto');\n  const secretToken = '<TOKEN>';\n  \n  const hash = crypto\n    .createHmac('sha256', secretToken)\n    .update(body.payload.plainToken)\n    .digest('hex');\n  \n  return {\n    json: {\n      plainToken: body.payload.plainToken,\n      encryptedToken: hash\n    }\n  };\n}\n\n// Normale Events durchreichen\nreturn $input.item;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        224,
        -336
      ],
      "id": "bd828955-c13f-48ab-821d-d0232c2b3e63",
      "name": "Challenge",
      "notes": "Zoom verifies you webhook by sending a hash and expecting a certain return value. Only if this challenges succeeds, you can use this endpoint in your webhook"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ $json }}",
        "options": {}
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.4,
      "position": [
        448,
        -336
      ],
      "id": "1eda573a-96ec-4f65-81a0-a9bc9999aad1",
      "name": "Respond to Webhook"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "8c98ec4c-1fe2-48ed-bd10-85ba866b9fec",
              "name": "start_time",
              "value": "={{ $json.body.payload.object.meeting_start_time }}",
              "type": "string"
            },
            {
              "id": "908904d9-55d5-4f1e-8b9d-2c4f55435aa1",
              "name": "meeting_topic",
              "value": "={{ $json.body.payload.object.meeting_topic }}",
              "type": "string"
            },
            {
              "id": "8e6987b0-207e-4cd9-8518-860ce7df82c5",
              "name": "meeting_uuid",
              "value": "={{ $json.body.payload.object.meeting_uuid }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        896,
        -144
      ],
      "id": "254c6676-c330-4b48-a0dd-56f9e85069cf",
      "name": "Input"
    },
    {
      "parameters": {
        "url": "=https://api.zoom.us/v2/meetings/{{ $json.meeting_uuid }}/meeting_summary",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "zoomOAuth2Api",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        1344,
        -144
      ],
      "id": "1e0e1624-6767-4eee-83b5-3bd75e3473d0",
      "name": "Get Summary",
      "credentials": {
        "zoomOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.notion.com/v1/pages",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "notionApi",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ $json }}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        1792,
        -144
      ],
      "id": "733cbac6-0b44-4e01-b58e-1a72b58b50ed",
      "name": "Create a database Page",
      "credentials": {
        "notionApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Extract data from Zoom webhook\nconst url = $json.summary_doc_url || '';\nconst summaryDetails = $json.summary_details || [];\nconst nextSteps = $json.next_steps || [];\nconst meetingTopic = $json.meeting_topic || 'Meeting Summary';\nconst meetingDate = $json.meeting_start_time || new Date().toISOString();\n\n// Build Notion blocks - richtig strukturiert\nconst children = [];\n\n// Add summary details sections\nsummaryDetails.forEach(detail => {\n  // Header block (heading_2)\n  children.push({\n    object: 'block',\n    type: 'heading_2',\n    heading_2: {\n      rich_text: [{\n        type: 'text',\n        text: { content: detail.label }\n      }]\n    }\n  });\n  \n  // Paragraph block\n  children.push({\n    object: 'block',\n    type: 'paragraph',\n    paragraph: {\n      rich_text: [{\n        type: 'text',\n        text: { content: detail.summary }\n      }]\n    }\n  });\n});\n\n// Add Next Steps header\nchildren.push({\n  object: 'block',\n  type: 'heading_2',\n  heading_2: {\n    rich_text: [{\n      type: 'text',\n      text: { content: 'Next Steps' }\n    }]\n  }\n});\n\n// Add each next step as bullet point\nnextSteps.forEach(step => {\n  children.push({\n    object: 'block',\n    type: 'bulleted_list_item',\n    bulleted_list_item: {\n      rich_text: [{\n        type: 'text',\n        text: { content: step }\n      }]\n    }\n  });\n});\n\n// Return complete Notion page payload\nreturn {\n  json: {\n    parent: {\n      database_id: '2c7eaa1d973e80089564cd127081ff2a' // Hier deine DB ID einf\u00fcgen\n    },\n    properties: {\n      'Name': {\n        title: [{\n          text: { content: meetingTopic }\n        }]\n      },\n      'Typ': {\n        select: {\n          name: 'Zoom'\n        }\n      },\n      'URL': {\n        url\n      },\n      'Datum': {\n        date: {\n          start: meetingDate.split('T')[0]\n        }\n      }\n    },\n    children: children\n  }\n};"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1568,
        -144
      ],
      "id": "06ce85cd-1dc8-4323-b967-7eeb2a7aa88b",
      "name": "Create Request Body"
    },
    {
      "parameters": {
        "authentication": "oAuth2",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "value": "C0918U5CGLD",
          "mode": "list",
          "cachedResultName": "automations"
        },
        "messageType": "block",
        "blocksUi": "={\n\t\"blocks\": [\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"text\": {\n\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\"text\": \"Neues Transkript f\u00fcr Meeting '{{ $('Input').item.json.meeting_topic }}' verf\u00fcgbar, weise es jetzt einem Kunden zu\"\n\t\t\t},\n\t\t\t\"accessory\": {\n\t\t\t\t\"type\": \"button\",\n\t\t\t\t\"text\": {\n\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\"text\": \"Seite in Notion \u00f6ffnen\",\n\t\t\t\t\t\"emoji\": true\n\t\t\t\t},\n\t\t\t\t\"value\": \"submit-button\",\n\t\t\t\t\"url\": \"{{ $json.url }}\",\n\t\t\t\t\"action_id\": \"button-action\"\n\t\t\t}\n\t\t}\n\t]\n}",
        "text": "Neues Meetingtranskript verf\u00fcgbar",
        "otherOptions": {}
      },
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.3,
      "position": [
        2016,
        -144
      ],
      "id": "0af425ac-52b2-4a09-b2d4-5f5f1ec042ea",
      "name": "Send a message",
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "8c98ec4c-1fe2-48ed-bd10-85ba866b9fec",
              "name": "body.payload.object.meeting_start_time",
              "value": "={{ $now }}",
              "type": "string"
            },
            {
              "id": "908904d9-55d5-4f1e-8b9d-2c4f55435aa1",
              "name": "body.payload.object.meeting_topic",
              "value": "Test Meeting",
              "type": "string"
            },
            {
              "id": "8e6987b0-207e-4cd9-8518-860ce7df82c5",
              "name": "body.payload.object.meeting_uuid",
              "value": "=uuid_of_the_meeting",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        672,
        -96
      ],
      "id": "96e057a9-34d9-4a6b-bcd9-36d6a32290bd",
      "name": "Test Data"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "b62c06c6-2b5b-49b3-9fc4-b7e5fed00c3f",
              "leftValue": "={{ $('Webhook').item.json.body.event }}",
              "rightValue": "endpoint.url_validation",
              "operator": {
                "type": "string",
                "operation": "equals",
                "name": "filter.operator.equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        672,
        -336
      ],
      "id": "d88b7c55-e7b5-49c4-b343-3b7af1d1ab16",
      "name": "Endpoint validation"
    },
    {
      "parameters": {},
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        896,
        -384
      ],
      "id": "a3f12163-9828-4acc-a81b-5102455cde5b",
      "name": "No Operation, do nothing"
    },
    {
      "parameters": {
        "content": "## Zoom Setup \n\nA Zoom oauth app has to be created in order for this to work "
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -16,
        -544
      ],
      "typeVersion": 1,
      "id": "32182bc2-3da0-4437-83a4-e24b35323342",
      "name": "Sticky Note"
    },
    {
      "parameters": {
        "content": "Execute here to test the workflow.",
        "color": 4
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        528,
        80
      ],
      "typeVersion": 1,
      "id": "7d805be5-a363-4301-9805-771b8002e475",
      "name": "Sticky Note1"
    },
    {
      "parameters": {},
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        448,
        -96
      ],
      "id": "589c52ef-2184-4334-92c8-afddfe8fe5af",
      "name": "Test Workflow"
    },
    {
      "parameters": {
        "amount": 1,
        "unit": "minutes"
      },
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        1120,
        -144
      ],
      "id": "ad67ef23-cfd0-4a52-b1a3-24a44315d272",
      "name": "Wait for transcript to be available",
      "notes": "The transcript/summary is not directly available - although the event \"meeting.aic_transcript_completed\" might suggest that."
    },
    {
      "parameters": {
        "content": "Notion has a limit of 2000 chars per richt text block, so we are creating seperate header/text blocks for each topic of the summary.",
        "width": 368
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1552,
        48
      ],
      "typeVersion": 1,
      "id": "76fd0465-21dd-4bd7-b83f-a4042c635d9a",
      "name": "Sticky Note2"
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Challenge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Challenge": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Respond to Webhook": {
      "main": [
        [
          {
            "node": "Endpoint validation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Input": {
      "main": [
        [
          {
            "node": "Wait for transcript to be available",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Summary": {
      "main": [
        [
          {
            "node": "Create Request Body",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create a database Page": {
      "main": [
        [
          {
            "node": "Send a message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Request Body": {
      "main": [
        [
          {
            "node": "Create a database Page",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Test Data": {
      "main": [
        [
          {
            "node": "Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Endpoint validation": {
      "main": [
        [
          {
            "node": "No Operation, do nothing",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Test Workflow": {
      "main": [
        [
          {
            "node": "Test Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait for transcript to be available": {
      "main": [
        [
          {
            "node": "Get Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": true,
  "settings": {
    "executionOrder": "v1",
    "callerPolicy": "workflowsFromSameOwner",
    "availableInMCP": false,
    "errorWorkflow": "MvPyZF1GJihUpOGU",
    "timeSavedPerExecution": 5
  },
  "versionId": "7b060ec0-5824-432a-86c3-40d91b9d03ef",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "LYAygmgEQFh40ZBA",
  "tags": []
}