This workflow follows the Chainllm → Anthropic Chat 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 →
{
"name": "NTF 05 - Meeting Notes to Tasks",
"tags": [
{
"name": "NTF-Playbook"
}
],
"settings": {
"executionOrder": "v1"
},
"nodes": [
{
"id": "sticky-readme",
"name": "README",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-60,
-520
],
"parameters": {
"content": "## NTF 05 - Meeting Notes to Tasks\n\n**Trigger:** Webhook - POST `{ transcript: \"...\", meeting_title: \"...\", date: \"...\" }`\n\n**Flow:**\n1. Receive meeting transcript via webhook\n2. Claude extracts action items, decisions, and attendees\n3. Create a Notion page with the meeting summary\n4. Create individual Notion tasks for each action item\n5. Send Slack recap with task list\n\n**Setup:**\n- Connect Notion OAuth credential\n- Set your Notion Database ID for tasks\n- Set your Notion Database ID for meeting notes\n- Set your Slack channel ID\n- Works with any transcript format (Otter.ai, Fireflies, manual notes)",
"height": 360,
"width": 540,
"color": 6
}
},
{
"id": "webhook-trigger",
"name": "Meeting Transcript Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
0,
0
],
"parameters": {
"httpMethod": "POST",
"path": "meeting-notes",
"responseMode": "responseNode",
"options": {}
}
},
{
"id": "extract-fields",
"name": "Extract Meeting Fields",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
220,
0
],
"parameters": {
"mode": "manual",
"assignments": {
"assignments": [
{
"id": "transcript",
"name": "transcript",
"value": "={{ $json.body.transcript }}",
"type": "string"
},
{
"id": "meeting_title",
"name": "meeting_title",
"value": "={{ $json.body.meeting_title || 'Meeting' }}",
"type": "string"
},
{
"id": "meeting_date",
"name": "meeting_date",
"value": "={{ $json.body.date || $now.format('YYYY-MM-DD') }}",
"type": "string"
}
]
}
}
},
{
"id": "claude-llm",
"name": "Claude Extraction Model",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"typeVersion": 1.3,
"position": [
440,
0
],
"parameters": {
"model": "claude-sonnet-4-5",
"options": {
"maxTokens": 2000
}
},
"credentials": {
"anthropicApi": {
"name": "<your credential>"
}
}
},
{
"id": "extract-chain",
"name": "Extract Actions and Decisions",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"typeVersion": 1.4,
"position": [
440,
0
],
"parameters": {
"promptType": "define",
"text": "=You are a meeting assistant. Analyze this meeting transcript and return a JSON object with:\n- summary: 2-3 sentence executive summary of what was discussed and decided\n- decisions: array of strings, key decisions made (max 5)\n- action_items: array of objects, each with { task, owner, due_date, priority }\n - task: clear actionable description\n - owner: person responsible (use 'Unassigned' if not clear)\n - due_date: ISO date string if mentioned, otherwise null\n - priority: 'high' | 'medium' | 'low'\n- attendees: array of names mentioned in the transcript\n\nMeeting: {{ $('Extract Meeting Fields').item.json.meeting_title }}\nDate: {{ $('Extract Meeting Fields').item.json.meeting_date }}\n\nTranscript:\n{{ $('Extract Meeting Fields').item.json.transcript }}\n\nReturn only valid JSON. No markdown fencing."
}
},
{
"id": "parse-meeting",
"name": "Parse Meeting Data",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
660,
0
],
"parameters": {
"jsCode": "const raw = $input.first().json.text || '{}';\nlet parsed = {};\ntry {\n parsed = JSON.parse(raw.replace(/```json|```/g, '').trim());\n} catch(e) {\n parsed = { summary: raw, decisions: [], action_items: [], attendees: [] };\n}\nconst fields = $('Extract Meeting Fields').first().json;\nreturn [{ json: { ...parsed, ...fields } }];"
}
},
{
"id": "create-notion-summary",
"name": "Notion Meeting Summary Page",
"type": "n8n-nodes-base.notion",
"typeVersion": 2.2,
"position": [
880,
-120
],
"parameters": {
"operation": "create",
"databaseId": "YOUR_NOTION_MEETING_NOTES_DB_ID",
"title": "={{ $json.meeting_title }} - {{ $json.meeting_date }}",
"propertiesUi": {
"propertyValues": [
{
"key": "Date",
"type": "date",
"dateValue": "={{ $json.meeting_date }}"
},
{
"key": "Summary",
"type": "richText",
"textContent": "={{ $json.summary }}"
},
{
"key": "Attendees",
"type": "richText",
"textContent": "={{ ($json.attendees || []).join(', ') }}"
}
]
}
},
"credentials": {
"notionApi": {
"name": "<your credential>"
}
}
},
{
"id": "split-tasks",
"name": "Split Action Items",
"type": "n8n-nodes-base.splitOut",
"typeVersion": 1,
"position": [
880,
80
],
"parameters": {
"fieldToSplitOut": "action_items",
"options": {}
}
},
{
"id": "create-notion-tasks",
"name": "Notion Create Task",
"type": "n8n-nodes-base.notion",
"typeVersion": 2.2,
"position": [
1100,
80
],
"parameters": {
"operation": "create",
"databaseId": "YOUR_NOTION_TASKS_DB_ID",
"title": "={{ $json.task }}",
"propertiesUi": {
"propertyValues": [
{
"key": "Owner",
"type": "richText",
"textContent": "={{ $json.owner }}"
},
{
"key": "Priority",
"type": "select",
"selectValue": "={{ $json.priority }}"
},
{
"key": "Due Date",
"type": "date",
"dateValue": "={{ $json.due_date }}"
},
{
"key": "Source",
"type": "richText",
"textContent": "={{ $('Extract Meeting Fields').item.json.meeting_title }}"
}
]
}
},
"credentials": {
"notionApi": {
"name": "<your credential>"
}
}
},
{
"id": "slack-recap",
"name": "Slack Meeting Recap",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.3,
"position": [
1100,
-120
],
"parameters": {
"operation": "post",
"channel": "YOUR_SLACK_CHANNEL_ID",
"text": "=*Meeting Recap: {{ $('Extract Meeting Fields').item.json.meeting_title }}*\n{{ $('Extract Meeting Fields').item.json.meeting_date }}\n\n{{ $('Parse Meeting Data').item.json.summary }}\n\n*Action Items:*\n{{ ($('Parse Meeting Data').item.json.action_items || []).map(a => `- ${a.task} -> ${a.owner}`).join('\\n') }}"
},
"credentials": {
"slackApi": {
"name": "<your credential>"
}
}
},
{
"id": "webhook-response",
"name": "Webhook Response",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.1,
"position": [
1320,
0
],
"parameters": {
"respondWith": "json",
"responseBody": "={{ JSON.stringify({ received: true, tasks_created: $('Parse Meeting Data').item.json.action_items?.length || 0 }) }}"
}
}
],
"connections": {
"Meeting Transcript Webhook": {
"main": [
[
{
"node": "Extract Meeting Fields",
"type": "main",
"index": 0
}
]
]
},
"Extract Meeting Fields": {
"main": [
[
{
"node": "Extract Actions and Decisions",
"type": "main",
"index": 0
}
]
]
},
"Claude Extraction Model": {
"ai_languageModel": [
[
{
"node": "Extract Actions and Decisions",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Extract Actions and Decisions": {
"main": [
[
{
"node": "Parse Meeting Data",
"type": "main",
"index": 0
}
]
]
},
"Parse Meeting Data": {
"main": [
[
{
"node": "Notion Meeting Summary Page",
"type": "main",
"index": 0
},
{
"node": "Split Action Items",
"type": "main",
"index": 0
},
{
"node": "Slack Meeting Recap",
"type": "main",
"index": 0
}
]
]
},
"Split Action Items": {
"main": [
[
{
"node": "Notion Create Task",
"type": "main",
"index": 0
}
]
]
},
"Notion Meeting Summary Page": {
"main": [
[
{
"node": "Webhook Response",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
anthropicApinotionApislackApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
How this works
Transform your meeting transcripts into actionable tasks effortlessly, saving hours of manual note-taking and ensuring nothing slips through the cracks. This workflow is ideal for team leads and project managers who conduct regular meetings and need to capture decisions and action items quickly. It starts with a webhook receiving the transcript, then uses AI via lmChatAnthropic and chainLlm to extract key fields like actions and decisions, before creating a structured summary in Notion and notifying your team on Slack.
Use this workflow when you have transcribed meetings from tools like Zoom or Microsoft Teams and want automated task distribution to boost productivity. Avoid it for one-off notes or unstructured discussions lacking clear outcomes, as the AI extraction thrives on formal agendas. Common variations include routing tasks directly to tools like Asana instead of Notion, or adding email notifications alongside Slack for broader reach.
About this workflow
NTF 05 - Meeting Notes to Tasks. Uses lmChatAnthropic, chainLlm, notion, slack. Webhook trigger; 11 nodes.
Source: https://github.com/MinaSaad1/n8n-meeting-notes-to-tasks/blob/main/workflows/01-meeting-notes-to-tasks.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Story Generation – Your idea is transformed into a narrative split into scenes using DeepSeek LLM. Visuals – Each scene is illustrated with AI images via Replicate, then animated into cinematic video
NTF 04 - Content Repurposing. Uses httpRequest, lmChatAnthropic, chainLlm, googleDocs. Webhook trigger; 10 nodes.
Content - Short Form News Script Generator. Uses httpRequest, s3, chainLlm, slack. Scheduled trigger; 45 nodes.
Stop finding out about updates after something breaks. Claude reads every changelog and tells you exactly what changed, what might break, and how urgent the update is — with a ready-to-run Docker upda
The Recap AI - VEO 3 Bigfoot Video. Uses formTrigger, lmChatAnthropic, chainLlm, slack. Event-driven trigger; 26 nodes.