{
  "id": "XefJqh-wJ0hMc3QLhXVaH",
  "name": "Transcribe meeting recordings and extract action items to Notion using AssemblyAI and Gemini",
  "tags": [],
  "nodes": [
    {
      "id": "197f742d-9cff-4fda-8531-3930e50cbe2b",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        0
      ],
      "parameters": {
        "width": 480,
        "height": 880,
        "content": "## Transcribe meeting recordings and extract action items to Notion using AssemblyAI and Gemini\n\n### How it works\n\nThis workflow receives a meeting recording URL through a webhook, submits it to AssemblyAI for transcription, and repeatedly checks until the transcript is ready. Once complete, it sends the transcript to Gemini to extract action items and formats the result. It then creates meeting notes in Notion and notifies the team in Slack.\n\n### Setup steps\n\n- Configure the webhook URL in the system that sends meeting recording details, ensuring it includes the audio URL and meeting title fields expected by the workflow.\n- Add an AssemblyAI API key to the HTTP request nodes that submit audio and check transcription status.\n- Configure the Gemini API key and model endpoint in the action item extraction HTTP request node.\n- Set the Notion integration token, target database or parent page ID, and required page properties in the Notion creation request.\n- Configure the Slack bot token, target channel, and message format in the Slack notification request.\n\n### Customization\n\nAdjust the wait interval or polling logic based on typical transcription duration, update the Gemini prompt to change the meeting summary or action item format, and modify the Notion page schema or Slack message content to match the team's workflow."
      },
      "typeVersion": 1
    },
    {
      "id": "671bf947-00bc-44b1-9c68-b619b7734fdb",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        560,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 336,
        "content": "## Receive meeting input\n\nReceives the incoming meeting recording webhook and extracts the key fields needed downstream, including the audio URL, meeting title, and receipt timestamp."
      },
      "typeVersion": 1
    },
    {
      "id": "99c20f28-f51b-4190-9787-8673da2d0f4e",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1056,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 336,
        "content": "## Submit transcription job\n\nSends the audio URL to AssemblyAI to start transcription, then stores the returned transcript ID together with the original meeting metadata."
      },
      "typeVersion": 1
    },
    {
      "id": "2704acb7-642e-40fd-9d7b-5a90a75a551e",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1520,
        16
      ],
      "parameters": {
        "color": 7,
        "width": 640,
        "height": 320,
        "content": "## Poll transcription status\n\nWaits between status checks, queries AssemblyAI for the transcript state, and loops until the transcription is complete before allowing the workflow to continue."
      },
      "typeVersion": 1
    },
    {
      "id": "a7901e15-3ac9-46a0-9162-4eabb0957e1a",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2192,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 336,
        "content": "## Extract action items\n\nSends the completed transcript to Gemini for action item extraction, then parses and structures the model output with meeting details for publishing."
      },
      "typeVersion": 1
    },
    {
      "id": "38053427-861f-4af6-aa2c-ae66d1aab04c",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2640,
        16
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 320,
        "content": "## Publish and notify\n\nCreates a Notion page containing the meeting notes and extracted action items, then posts a Slack notification to inform the team."
      },
      "typeVersion": 1
    },
    {
      "id": "43e61303-35cc-40b8-9db1-5c47aac116e1",
      "name": "When Meeting Recorded",
      "type": "n8n-nodes-base.webhook",
      "position": [
        608,
        176
      ],
      "parameters": {
        "path": "meeting-transcribe",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2
    },
    {
      "id": "5e7b8413-26da-4bdc-84ba-e3c027f29af6",
      "name": "Set Meeting Input Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        832,
        176
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "4df6679e-8a16-460e-8925-13d0e5f6dc56",
      "name": "Post Audio to AssemblyAI",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1104,
        176
      ],
      "parameters": {
        "url": "https://api.assemblyai.com/v2/transcript",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {}
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "YOUR_ASSEMBLYAI_API_KEY"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4
    },
    {
      "id": "ca1ff265-4232-4f9c-a224-3a5a6671b6c5",
      "name": "Store AssemblyAI Transcript ID",
      "type": "n8n-nodes-base.set",
      "position": [
        1328,
        176
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "aae6bc20-3efc-43d9-9e15-a289047acbef",
      "name": "Wait for AssemblyAI Process",
      "type": "n8n-nodes-base.wait",
      "position": [
        1568,
        176
      ],
      "parameters": {
        "unit": "seconds",
        "amount": 15
      },
      "typeVersion": 1
    },
    {
      "id": "ca3ba8de-076e-4736-a621-125a26b79010",
      "name": "Fetch Transcription Status",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1792,
        176
      ],
      "parameters": {
        "url": "=https://api.assemblyai.com/v2/transcript/{{ $('Store AssemblyAI Transcript ID').item.json.transcript_id }}",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "YOUR_ASSEMBLYAI_API_KEY"
            }
          ]
        }
      },
      "typeVersion": 4
    },
    {
      "id": "575c8a84-4550-467a-bce8-cf874ae6796a",
      "name": "If Transcription Done",
      "type": "n8n-nodes-base.if",
      "position": [
        2016,
        176
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "condition-completed",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "completed"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "8ebf7f1b-62e6-4c4a-92a2-37a47c611624",
      "name": "Post to Gemini for Action Items",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2240,
        176
      ],
      "parameters": {
        "url": "=https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro:generateContent?key=YOUR_GEMINI_API_KEY",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {}
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4
    },
    {
      "id": "110e54e6-1f32-4a62-abee-a293164cb183",
      "name": "Set Parsed Gemini Output",
      "type": "n8n-nodes-base.set",
      "position": [
        2448,
        176
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "00f98fbd-5b7e-4a1c-b5f6-98329078fe04",
      "name": "Post Notes to Notion",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2688,
        176
      ],
      "parameters": {
        "url": "https://api.notion.com/v1/pages",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {}
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Notion-Version",
              "value": "2022-06-28"
            }
          ]
        }
      },
      "typeVersion": 4
    },
    {
      "id": "e29c82e3-df0a-4a08-88a6-449af864c5ff",
      "name": "Post Notification to Slack",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2912,
        176
      ],
      "parameters": {
        "url": "https://slack.com/api/chat.postMessage",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {}
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "",
  "connections": {
    "Post Notes to Notion": {
      "main": [
        [
          {
            "node": "Post Notification to Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Transcription Done": {
      "main": [
        [
          {
            "node": "Post to Gemini for Action Items",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait for AssemblyAI Process",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When Meeting Recorded": {
      "main": [
        [
          {
            "node": "Set Meeting Input Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post Audio to AssemblyAI": {
      "main": [
        [
          {
            "node": "Store AssemblyAI Transcript ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Meeting Input Fields": {
      "main": [
        [
          {
            "node": "Post Audio to AssemblyAI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Parsed Gemini Output": {
      "main": [
        [
          {
            "node": "Post Notes to Notion",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Transcription Status": {
      "main": [
        [
          {
            "node": "If Transcription Done",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait for AssemblyAI Process": {
      "main": [
        [
          {
            "node": "Fetch Transcription Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Store AssemblyAI Transcript ID": {
      "main": [
        [
          {
            "node": "Wait for AssemblyAI Process",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post to Gemini for Action Items": {
      "main": [
        [
          {
            "node": "Set Parsed Gemini Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}