

How to Share Notion Meeting Notes to Slack with n8n
Polls a Notion database for newly created meeting note pages and automatically posts a formatted message with the page title, date, and link to the correct Slack channel.
Steps and UI details are based on platform versions at time of writing — check each platform for the latest interface.
Best for
Teams who store meeting notes in a Notion database and need automatic Slack distribution without manually copying links each time.
Not ideal for
Teams who create notes in Notion pages outside a database — this workflow requires a structured Notion database to poll for new entries.
Sync type
scheduledUse case type
notificationReal-World Example
A 20-person product team at a B2B SaaS company runs daily standups, sprint reviews, and customer calls — all documented in a shared Notion database. Before this workflow, the note-taker had to manually paste the Notion link into #product-team or #engineering after every meeting, which got skipped 30-40% of the time. Now n8n polls the database every 5 minutes, detects new pages, and posts a structured Slack message to the right channel based on a 'Team' property in Notion — no manual sharing needed.
What Will This Cost?
Drag the slider to your expected monthly volume.
Each platform counts differently — Zapier: 1 task per trigger. Make: 1 operation per module per record. n8n: 1 execution per run.





Prices shown for annual billing. Based on published pricing as of April 2026.
Estimated ROI
1000
min saved/mo
$583
labor value/mo
Free
no platform cost
Based on ~2 min manual effort per operation at $35/hr fully loaded labor cost.
Implementation
Import this workflow directly into n8n
Copy the pre-built n8n blueprint and paste it straight into n8n. All modules, filters, and field mappings are already configured — you just need to connect your accounts.
Before You Start
Make sure you have everything ready.
Field Mapping
Map these fields between your apps.
| Field | API Name | |
|---|---|---|
| Required | ||
| Page Title | properties.Name.title[0].plain_text | |
| Page URL | url | |
| Created Time | created_time | |
5 optional fields▸ show
| Created By | created_by.name |
| Team | properties.Team.select.name |
| Meeting Date | properties.Meeting Date.date.start |
| Attendees | properties.Attendees.multi_select |
| Summary | properties.Summary.rich_text[0].plain_text |
Step-by-Step Setup
notion.so/my-integrations > + New integration > Capabilities
Create a Notion integration and share your database
Go to notion.so/my-integrations and click '+ New integration'. Name it something like 'n8n Meeting Notes', set the associated workspace, and copy the Internal Integration Token — you'll need it in n8n. Back in Notion, open the database you use for meeting notes, click the '...' menu in the top-right, scroll to 'Connections', and add the integration you just created. Without this step, n8n cannot read any pages in that database.
- 1Go to notion.so/my-integrations and click '+ New integration'
- 2Name the integration 'n8n Meeting Notes' and select your workspace
- 3Under Capabilities, enable 'Read content'
- 4Copy the Internal Integration Token
- 5Open your Notion meeting notes database, click '...' > Connections > add your new integration
api.slack.com/apps > Create New App > OAuth & Permissions > Scopes
Create a Slack app and get a bot token
Go to api.slack.com/apps and click 'Create New App', choose 'From scratch', name it 'Meeting Notes Bot', and select your workspace. Under 'OAuth & Permissions', add the bot scopes: chat:write and channels:read. Install the app to your workspace and copy the Bot User OAuth Token (starts with xoxb-). You'll also need to invite the bot to any Slack channel it should post in.
- 1Go to api.slack.com/apps and click 'Create New App' > 'From scratch'
- 2Name the app 'Meeting Notes Bot' and select your Slack workspace
- 3Navigate to OAuth & Permissions > Bot Token Scopes
- 4Add scopes: chat:write, channels:read
- 5Click 'Install to Workspace', authorize, and copy the Bot User OAuth Token
n8n > Settings > Credentials > + Add Credential
Set up credentials in n8n
In n8n, go to Settings > Credentials and create two credentials. First, click '+ Add Credential', search for 'Notion API', select it, and paste your Internal Integration Token. Second, create another credential, search for 'Slack API', and paste your xoxb- Bot User OAuth Token. Name both clearly — 'Notion – Meeting Notes' and 'Slack – Meeting Notes Bot' — so you can identify them later.
- 1Open n8n and click Settings in the left sidebar
- 2Click Credentials > + Add Credential
- 3Search 'Notion API', select it, paste your Internal Integration Token, click Save
- 4Click + Add Credential again, search 'Slack API', paste your xoxb- token, click Save
n8n > Workflows > + New Workflow > + Add Node > Schedule Trigger
Create a new workflow and add the Schedule trigger
In n8n, click '+ New Workflow'. Click the canvas to add your first node and search for 'Schedule Trigger'. Set the interval to every 5 minutes. This node fires your workflow on a timer — since Notion's API doesn't support real-time webhooks for database page creation, polling is the only approach. Five minutes is a reasonable balance between freshness and API rate limits.
- 1Click '+ New Workflow' from the n8n home screen
- 2Click the '+' node on the canvas and search for 'Schedule Trigger'
- 3Set 'Trigger Interval' to Every 5 Minutes
- 4Click the node header and rename it to 'Poll Every 5 Min'
- 5Click Save
Canvas > + Add Node > Notion > Database Page > Get Many
Add a Notion node to query the database
Add a new node after the Schedule Trigger and search for 'Notion'. Select the 'Get Many' operation under 'Database Page'. Connect it to your 'Notion – Meeting Notes' credential and enter your database ID (the 32-character string from your Notion database URL). Add a filter: set 'Created Time' is on or after a dynamic value. You'll set the exact dynamic timestamp in the next step — for now, confirm the node connects and returns results when you test it.
- 1Click '+' after the Schedule Trigger node and search 'Notion'
- 2Under Resource, select 'Database Page'; under Operation, select 'Get Many'
- 3Select your 'Notion – Meeting Notes' credential
- 4Paste your Notion database ID into the Database ID field
- 5Click 'Test step' to confirm the node returns pages
Canvas > + Add Node > Code
Add a Code node to filter only new pages
Since n8n's Notion node doesn't have a native 'last run time' filter, you need a Code node to compare each page's created_time against the last execution time. Add a Code node after the Notion node. Paste the JavaScript below (see pro_tip_code). This code reads a static workflow variable for the last-run timestamp, filters pages created after that time, updates the variable, and passes only new pages downstream. Without this, every poll would re-send every page in the database.
- 1Click '+' after the Notion node and search 'Code'
- 2Select the Code node and set Mode to 'Run Once for All Items'
- 3Paste the full JavaScript from the Pro Tip section into the code editor
- 4Click 'Test step' — if no new pages exist, the output should show 0 items
This Code node runs after the Notion 'Get Many' node and does three things: reads the last-run timestamp from n8n's persistent staticData, filters the Notion pages to only those created after that timestamp, and updates the stored timestamp for the next run. Paste this into a Code node set to 'Run Once for All Items', placed between the Notion node and the IF node.
JavaScript — Code Node// Code node: filter Notion pages to only new ones since last run▸ Show code
// Code node: filter Notion pages to only new ones since last run // Mode: Run Once for All Items const items = $input.all();
... expand to see full code
// Code node: filter Notion pages to only new ones since last run
// Mode: Run Once for All Items
const items = $input.all();
// Get persistent storage for this workflow
const staticData = $getWorkflowStaticData('global');
// Use stored lastRun time, or fall back to 6 minutes ago on first run
// 6 min covers the 5-min poll interval with buffer for clock drift
const lastRun = staticData.lastNotionPollTime
? new Date(staticData.lastNotionPollTime)
: new Date(Date.now() - 6 * 60 * 1000);
console.log(`Filtering pages created after: ${lastRun.toISOString()}`);
// Filter only pages created since last poll
const newPages = items.filter(item => {
const createdAt = new Date(item.json.created_time);
return createdAt > lastRun;
});
console.log(`Found ${newPages.length} new page(s) out of ${items.length} total`);
// Update the stored timestamp to now before returning
// This ensures the next run only sees pages created after this moment
staticData.lastNotionPollTime = new Date().toISOString();
// If no new pages, return empty array — downstream nodes won't fire
if (newPages.length === 0) {
return [];
}
// Return new pages with a cleaned-up display date added
return newPages.map(item => {
const rawDate = item.json.created_time;
const displayDate = new Date(rawDate).toLocaleDateString('en-US', {
weekday: 'short',
month: 'short',
day: 'numeric',
year: 'numeric'
});
return {
json: {
...item.json,
display_date: displayDate,
page_title: item.json.properties?.Name?.title?.[0]?.plain_text ?? 'Untitled',
team: item.json.properties?.Team?.select?.name ?? 'General',
summary: item.json.properties?.Summary?.rich_text?.[0]?.plain_text ?? ''
}
};
});Canvas > + Add Node > IF
Add an IF node to route by team or meeting type
If your Notion database has a 'Team' or 'Category' property, add an IF node to route notes to different Slack channels. Add the IF node after the Code node. Set Condition 1: the Notion property 'Team' equals 'Engineering' — this branch posts to #engineering. The false branch handles all other teams and posts to a general #meeting-notes channel. You can chain multiple IF nodes for more teams.
- 1Click '+' after the Code node and search 'IF'
- 2Set Value 1 to the Notion 'Team' property using the expression: {{ $json.properties.Team.select.name }}
- 3Set Condition to 'equals'
- 4Set Value 2 to 'Engineering'
- 5Connect the True output to an Engineering Slack node; connect False to a general Slack node
Canvas > + Add Node > Slack > Message > Send
Add Slack nodes to post the message
Add a Slack node on each IF branch. Select Resource: Message, Operation: Send. Connect your 'Slack – Meeting Notes Bot' credential. Set the Channel to the appropriate channel ID (e.g. C04XXXXXXX — use the channel's ID, not its name, to avoid breakage if someone renames the channel). In the Text field, build your message using Notion data: include the page title, creator name, created date, and the Notion URL. Use Block Kit for a cleaner layout if your team prefers it.
- 1Click '+' on the True branch output and search 'Slack'
- 2Set Resource to 'Message', Operation to 'Send'
- 3Select your 'Slack – Meeting Notes Bot' credential
- 4Set Channel to the Slack channel ID (right-click channel in Slack > Copy link to extract ID)
- 5Set Text to: 📝 New meeting notes: *{{ $json.properties.Name.title[0].plain_text }}* 🔗 {{ $json.url }} 👤 {{ $json.created_by.name }} 🗓 {{ $json.created_time }}
channel: {{channel}}
ts: {{ts}}
Slack Node > Settings > Continue on Fail > Error Output > + Add Node
Add error handling with a fallback node
In n8n, click the Slack node, go to Settings, and enable 'Continue on Fail'. Then add an Error Trigger workflow or connect an email/Slack fallback node to catch failures. A simple approach: add a second Slack node connected to the error output of your main Slack node that posts to a #n8n-alerts channel. This ensures you know when a note fails to distribute — otherwise failures are silent.
- 1Click your Slack node, then click Settings in the node panel
- 2Toggle 'Continue on Fail' to ON
- 3Hover over the Slack node — you'll see a red error output handle appear
- 4Connect a second Slack node to that error handle
- 5Set it to post to #n8n-alerts with text: '⚠️ Meeting notes distribution failed for: {{ $json.error.message }}'
n8n > Workflow Editor > Active toggle (top right) > Executions tab
Activate the workflow and verify the first live run
Click 'Save' in the top-right, then toggle the workflow from Inactive to Active using the toggle in the top-right corner. Wait 5 minutes (or create a new test page in your Notion database). Go to the Executions tab in n8n and watch for a new execution row to appear. Click into it to confirm the Notion node returned your test page, the Code node passed it through, and the Slack node shows a success status.
- 1Click Save in the top-right of the workflow editor
- 2Toggle the workflow status from Inactive to Active
- 3Create a new page in your Notion meeting notes database
- 4Wait up to 5 minutes for the next poll to fire
- 5Click the Executions tab and open the latest execution to inspect each node's output
Going live
Production Checklist
Before you turn this on for real, confirm each item.
Troubleshooting
Common errors and how to fix them.
Frequently Asked Questions
Common questions about this workflow.
Analysis
Use n8n for this if your team self-hosts or has privacy requirements that make cloud automation tools a non-starter. Notion and Slack both handle auth over standard OAuth and API tokens — n8n handles both without exposing your tokens to a third-party platform. The second reason to pick n8n here is the Code node: the deduplication logic this workflow requires (tracking last-run timestamps with staticData) is trivial in JavaScript but painful to hack together in Zapier's Formatter or Make's flow control. One scenario where you'd skip n8n: if nobody on your team has any comfort with JSON or reading node output panels, Make is faster to configure for this exact workflow.
Cost math: this workflow executes once every 5 minutes. That's 288 executions per day, roughly 8,640 per month. On n8n cloud's Starter plan ($20/month), you get 2,500 executions — you'll hit the limit in under 9 days. You need the Pro plan at $50/month for 10,000 executions, which covers you with margin. Self-hosted n8n is free with no execution limits, just your server cost. Compare that to Zapier: at 288 zaps/day this workflow burns through the free tier in 4 days, and the Team plan ($69/month) gives you 2,000 tasks — not enough either. Make's Core plan ($10.59/month) includes 10,000 operations and would handle this easily at around 1,700 operations per month (6 ops per execution × 288 runs). Make is cheaper by $39/month on cloud. Self-hosted n8n is cheaper than everything.
Zapier has no native Notion trigger for 'new database page' — it polls too, but the minimum interval on paid plans is 1 minute and the Notion integration lags. Make has a cleaner Notion module with built-in filter support that avoids needing a custom deduplication script. Power Automate has no official Notion connector — you'd be using HTTP actions throughout, which means building every Notion API call manually. Pipedream has a Notion 'New Page in Database' source that wraps the polling in a managed event source, reducing the code you write yourself. n8n is still the right call if you're self-hosting (cost) or if you want the deduplication and channel-routing logic living in one visible, version-controllable workflow file rather than spread across a SaaS platform's UI.
Three things you'll hit after setup. First, Notion's created_by.name field returns the integration name (e.g. 'n8n Meeting Notes'), not a human name, for pages created via API. For pages created by real users in the Notion UI it works fine — but if anyone creates notes programmatically, the author field will look wrong. Second, if your Notion database has a title column named anything other than 'Name', the path properties.Name.title[0].plain_text returns undefined and your Slack message shows nothing. Check the exact property name in the raw node output and update the Code node accordingly. Third, Slack's chat.postMessage API silently succeeds (returns HTTP 200) even when the bot is not in the channel — it just doesn't show the message. Always verify delivery by checking the ts timestamp in the Slack node output, not just the HTTP status code.
Ideas for what to build next
- →Add a daily digest instead of per-note alerts — Change the Schedule Trigger to run once at 5pm, collect all notes created that day, and post a single bulleted Slack digest. This reduces noise for teams with 10+ meetings per day.
- →Post a Slack thread summary using the Notion page body — Use the Notion 'Get Block Children' operation to pull the actual content of the page and post it as a Slack thread reply under the main notification — so teammates can read the key points without opening Notion.
- →Tag relevant Slack users based on the Notion Attendees property — Map the Notion Attendees multi-select or people property to Slack user IDs using a lookup table in a Code node, then include @mentions in the Slack message so the right people are notified directly.
Related guides
How to Share Notion Meeting Notes to Slack with Pipedream
~15 min setup
How to Share Notion Meeting Notes to Slack with Power Automate
~15 min setup
How to Send Notion Meeting Notes to Slack with Zapier
~8 min setup
How to Share Notion Meeting Notes to Slack with Make
~12 min setup
How to Create Notion Tasks from Slack with Pipedream
~15 min setup
How to Create Notion Tasks from Slack with Power Automate
~15 min setup