Intermediate~15 min setupCommunication & ProductivityVerified April 2026
Slack logo
Notion logo

How to Archive Slack Messages to Notion with Power Automate

Automatically saves a Slack message and its metadata to a designated Notion database page whenever a specific emoji reaction is added or a slash command is triggered.

Steps and UI details are based on platform versions at time of writing — check each platform for the latest interface.

Best for

Microsoft 365 teams already using Power Automate who want to preserve key Slack decisions and discussions directly into a Notion knowledge base without leaving Slack.

Not ideal for

Teams needing to archive entire channel histories in bulk — use Slack's native export plus a Notion import script instead.

Sync type

real-time

Use case type

backup

Real-World Example

💡

A 22-person product team at a SaaS company uses this to save any Slack message bookmarked with a 📌 reaction into a Notion database called 'Decision Log.' Before this flow, important decisions made in #product-strategy would get buried within 48 hours and had to be reconstructed in sprint retros. Now every pinned message lands in Notion within 90 seconds, tagged with the channel name, author, and timestamp.

What Will This Cost?

Drag the slider to your expected monthly volume.

/mo
505005K50K

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

Skip the setup

Import this workflow directly into Power Automate

Copy the pre-built Power Automate blueprint and paste it straight into Power Automate. 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.

Slack workspace admin access or a user account with permission to install OAuth apps — required to authorize Power Automate's Slack connector
Notion workspace with at least one database created and a Notion account that has 'Full access' to that database — Power Automate's Notion connector requires full access, not just comment or view permissions
Power Automate account with a plan that includes premium connectors — both the Slack and Notion connectors are premium in Power Automate and are NOT available on the free tier
The target Notion database must have these properties created in advance: Title (text), Channel (text), Author (text), Archived At (date), Message URL (URL) — the connector maps to existing properties, it does not create them
Microsoft 365 account for the Power Automate login — flows are tied to an M365 identity and the Outlook error-notification step in Step 11 requires an Office 365 Outlook connection

Field Mapping

Map these fields between your apps.

FieldAPI Name
Required
Message Title (truncated)
Full Message Body
Author Display Name
Channel Name
Archived At
Slack Message URL
2 optional fields▸ show
Reaction Used
Thread Timestamp

Step-by-Step Setup

1

make.powerautomate.com > My flows > + New flow > Automated cloud flow

Create a new Automated cloud flow

Go to make.powerautomate.com and sign in. Click 'My flows' in the left sidebar, then click '+ New flow' at the top. Select 'Automated cloud flow' from the dropdown — this is the event-triggered option, not scheduled. Give your flow a name like 'Slack to Notion Archiver' and click 'Skip' on the trigger picker for now, since you'll add Slack manually.

  1. 1Sign in at make.powerautomate.com
  2. 2Click 'My flows' in the left sidebar
  3. 3Click '+ New flow' near the top of the page
  4. 4Select 'Automated cloud flow'
  5. 5Type 'Slack to Notion Archiver' in the name field
  6. 6Click 'Skip' to bypass the trigger template picker
What you should see: You should see the blank flow canvas with a single empty trigger block labeled 'Search connectors and triggers.'
Common mistake — Do NOT select 'Instant cloud flow' — that requires a manual button press and won't fire automatically when Slack events occur.
2

Flow canvas > Trigger block > Search: Slack > When a reaction is added to a message

Add the Slack trigger

Click inside the empty trigger block on the canvas. In the search bar that appears, type 'Slack' and select the Slack connector from the results. You will see a list of available triggers. For emoji-reaction-based archival, choose 'When a reaction is added to a message' — this fires in real time whenever any user adds a reaction in a channel your Slack bot has access to. If your team prefers a slash command approach, choose 'When a slash command is received' instead, but pick one and keep it consistent.

  1. 1Click the empty trigger block on the canvas
  2. 2Type 'Slack' in the connector search bar
  3. 3Click the Slack connector card
  4. 4Select 'When a reaction is added to a message' from the trigger list
What you should see: The trigger block should expand to show configuration fields including 'Channel Name' and 'Reaction Name.'
Common mistake — The Slack connector in Power Automate uses OAuth and requires your Slack workspace admin to approve the connection scope. If you see a 'Connection requires admin approval' banner, you need workspace admin access before proceeding.
Power Automate
+
click +
search apps
Slack
SL
Slack
Add the Slack trigger
Slack
SL
module added
3

Flow canvas > Slack trigger block > Sign in > Channel Name + Reaction Name fields

Authenticate and configure the Slack connection

Click 'Sign in' inside the trigger block. Power Automate will open a Slack OAuth popup. Sign in with the Slack account that has access to the channels you want to monitor. After authentication, the trigger config fields will become active. In 'Channel Name,' select the specific channel (e.g., #product-strategy). In 'Reaction Name,' type the emoji name without colons — for a 📌 use 'pushpin'. Leave 'Reaction Item Type' set to 'message'.

  1. 1Click 'Sign in' in the Slack trigger block
  2. 2Authorize the connection in the Slack OAuth popup
  3. 3Return to the flow canvas — the connection will show your Slack workspace name
  4. 4Select your target channel from the 'Channel Name' dropdown
  5. 5Type 'pushpin' in the 'Reaction Name' field (no colons)
What you should see: The Slack trigger block should now show your workspace name as the connection and display the channel and reaction name you configured.
Common mistake — Power Automate's Slack connector does NOT support wildcard channel monitoring. You must configure one flow per channel, or use a separate HTTP + Slack Events API approach to cover multiple channels from a single flow.
4

Flow canvas > + New step > Slack > Get message

Add a 'Get message' action to fetch full message text

The reaction trigger only gives you the message timestamp and channel ID — it does not include the message body. Click '+ New step' below the trigger. Search for 'Slack' again and choose the action 'Get message.' Map the 'Channel ID' field using the dynamic content token 'Channel' from the trigger output, and map 'Message Timestamp' to the 'Item Timestamp' token from the trigger. This call fetches the full message object including text, author, and thread metadata.

  1. 1Click '+ New step' below the Slack trigger
  2. 2Search for 'Slack' in the action picker
  3. 3Select 'Get message' from the action list
  4. 4Click the 'Channel ID' field and select 'Channel' from the dynamic content panel
  5. 5Click the 'Message Timestamp' field and select 'Item Timestamp' from dynamic content
What you should see: The 'Get message' action block should show both fields populated with blue dynamic content tokens.
Common mistake — Map fields using the variable picker — don't type field names manually. Hand-typed variable names often have invisible spacing errors that produce blank output.
message template
🔔 New Record: {{text}} {{user}}
channel: {{channel}}
ts: {{ts}}
#sales
🔔 New Record: Jane Smith
Company: Acme Corp
5

Flow canvas > + New step > Slack > Get user profile

Add a 'Get user profile' action to resolve the author name

The message object returns a user ID like U04XKTZ88, not a readable name. Click '+ New step', search Slack, and choose 'Get user profile.' Map the 'User ID' field to the 'User' dynamic content token from the 'Get message' output. This gives you the display name and real name to store in Notion instead of a raw ID.

  1. 1Click '+ New step'
  2. 2Search for 'Slack' and select 'Get user profile'
  3. 3In the 'User ID' field, click and select 'User' from the 'Get message' dynamic content section
What you should see: The action block shows 'User' as a dynamic token in the User ID field. You can test this step to confirm it returns 'Display Name' and 'Real Name' in the output.
Common mistake — If the message was posted by a bot or webhook (not a human user), 'Get user profile' will fail with a 'user_not_found' error. Add a condition step after this to check if the 'User' field starts with 'U' before calling this action.

Paste this expression into a Compose action placed directly after the Slack 'Get message' step. It builds the full Slack deep-link URL and strips the decimal from the timestamp in one expression, so you don't need a separate Replace action. Reference the Compose output as 'Slack_Permalink' in the Notion field mapping.

JavaScript — Code Step// Power Automate Expression — paste into a Compose action 'Inputs' field
▸ Show code
// Power Automate Expression — paste into a Compose action 'Inputs' field
// Builds Slack permalink + truncated title + ISO timestamp in one block
// 1. Slack Permalink (paste into Compose: Slack_Permalink)

... expand to see full code

// Power Automate Expression — paste into a Compose action 'Inputs' field
// Builds Slack permalink + truncated title + ISO timestamp in one block

// 1. Slack Permalink (paste into Compose: Slack_Permalink)
concat(
  'https://slack.com/archives/',
  triggerOutputs()?['body/item/channel'],
  '/p',
  replace(outputs('Get_message')?['body/ts'], '.', '')
)

// 2. Truncated Title with ellipsis (paste into Compose: Message_Title)
if(
  greater(length(outputs('Get_message')?['body/text']), 80),
  concat(substring(outputs('Get_message')?['body/text'], 0, 80), '…'),
  outputs('Get_message')?['body/text']
)

// 3. ISO Timestamp from Slack Unix epoch (paste into Compose: Archived_At)
addSeconds(
  '1970-01-01T00:00:00Z',
  int(first(split(outputs('Get_message')?['body/ts'], '.')))
)
6

Flow canvas > + New step > Data Operation > Compose

Parse the message timestamp into a readable date

Slack timestamps are Unix epoch values like '1701432000.000100'. Notion expects ISO 8601 dates. Click '+ New step', search for 'Compose' (Data Operations connector), and add a Compose action. In the Inputs field, use the expression editor to write the conversion formula. Click the 'Expressions' tab in the dynamic content panel and paste the formula to convert the Unix timestamp to a formatted date string.

  1. 1Click '+ New step'
  2. 2Search for 'Data Operation' and select 'Compose'
  3. 3Click inside the 'Inputs' field
  4. 4Click the 'Expression' tab in the dynamic content panel
  5. 5Paste the conversion expression: addSeconds('1970-01-01T00:00:00Z', int(first(split(outputs('Get_message')?['body/ts'], '.'))))
  6. 6Click 'OK' to save the expression
What you should see: The Compose block shows the expression as a formula token. When you test the flow, the output should be a date string like '2023-12-01T10:00:00.0000000Z'.
Common mistake — Slack timestamps have a decimal portion (e.g., '1701432000.000100'). If you pass the full string directly to addSeconds(), it will fail. The split() on '.' is required to strip the sub-second portion before conversion.
7

Flow canvas > + New step > Notion > Create a page

Add the Notion connection

Click '+ New step' and search for 'Notion' in the connector picker. Select the Notion connector. Click 'Create a page' from the action list. You will be prompted to authenticate. Click 'Sign in', which opens Notion's OAuth flow. Select the workspace and grant access to the specific database you want to archive messages into — Notion's permission model requires you to explicitly share the database with the integration at this step.

  1. 1Click '+ New step'
  2. 2Search for 'Notion' in the action picker
  3. 3Select 'Create a page'
  4. 4Click 'Sign in' to initiate Notion OAuth
  5. 5Select your workspace in the Notion authorization screen
  6. 6Check the specific database you want to use and click 'Allow access'
What you should see: The Notion 'Create a page' action block should show your workspace name as the connection and activate the 'Database ID' dropdown.
Common mistake — Power Automate's Notion connector only supports databases where 'Title' is the first property. If your database uses a custom first-property name, the connector will not map the title field correctly and pages will be created with blank titles.
8

Flow canvas > Notion: Create a page > Database ID > property fields

Configure the Notion page fields

In the 'Create a page' action, select your target database from the 'Database ID' dropdown. Power Automate will load the database schema and show matching fields. Map each Notion property to the corresponding Slack data using dynamic content tokens from previous steps. Map 'Title' to the first 80 characters of the message text, 'Channel' to the channel name, 'Author' to the display name from 'Get user profile', 'Archived At' to the output of the Compose timestamp step, and 'Message Link' to a constructed Slack permalink.

  1. 1Select your Notion database from the 'Database ID' dropdown
  2. 2Map the 'Title' property: click the field, go to Expression tab, type: substring(outputs('Get_message')?['body/text'], 0, 80)
  3. 3Map 'Channel' to the 'Channel Name' dynamic token from the Slack trigger
  4. 4Map 'Author' to 'Display Name' from the 'Get user profile' output
  5. 5Map 'Archived At' to the 'Outputs' token from your Compose timestamp action
  6. 6Map 'Message URL' by constructing: concat('https://slack.com/archives/', triggerOutputs()?['body/item/channel'], '/p', replace(outputs('Get_message')?['body/ts'], '.', ''))
What you should see: All property fields in the Notion action block should show blue dynamic content tokens. No field should be left as plain text unless it is a static label.
Slack fields
text
user
channel
ts
thread_ts
available as variables:
1.props.text
1.props.user
1.props.channel
1.props.ts
1.props.thread_ts
9

Flow canvas > + New step > Notion > Append block children

Add the message body as Notion page content

Notion's 'Create a page' action in Power Automate creates the page record but does not automatically populate the page body — only database properties are set. To write the full message text into the page body, add another step: search for 'Notion' and choose 'Append block children.' Set the 'Block ID' to the 'ID' token from the 'Create a page' output. Set the block type to 'paragraph' and the text to the full message body token from 'Get message.'

  1. 1Click '+ New step'
  2. 2Search 'Notion' and select 'Append block children'
  3. 3In 'Block ID', select the 'ID' token from the 'Create a page' output
  4. 4Set 'Block Type' to 'paragraph'
  5. 5Set the text content to the 'Text' dynamic token from the 'Get message' output
What you should see: When you test the flow, the Notion page should appear in your database with the message body visible in the page content area, not just in the properties panel.
Common mistake — The 'Append block children' Notion action in Power Automate has a 2,000-character limit per block. Slack messages longer than 2,000 characters will be silently truncated. Add a condition to split long messages into multiple blocks if your team posts lengthy content.
10

make.powerautomate.com > My flows > [Flow name] > 28-day run history

Test the flow end-to-end

Save the flow by clicking the floppy disk icon or the 'Save' button at the top right. Then go to your configured Slack channel and add a 📌 reaction to any message. Return to make.powerautomate.com, click on your flow name, and scroll down to the '28-day run history' section. The test run should appear within 30–90 seconds. Click the run record to inspect each step's inputs and outputs. Verify the Notion page was created with the correct author, channel, timestamp, and message body.

  1. 1Click 'Save' in the top right of the flow editor
  2. 2Open Slack and add a 📌 reaction to a message in your configured channel
  3. 3Return to make.powerautomate.com and open 'My flows'
  4. 4Click your flow name to open its detail page
  5. 5Scroll to '28-day run history' and wait up to 90 seconds for the run to appear
  6. 6Click the run record and inspect each step's output to confirm correct data
What you should see: The run history should show a green checkmark for all steps. The Notion database should contain a new page with the message text, author name, channel, and a clickable Slack message URL.
Power Automate
▶ Test flow
executed
Slack
Notion
Notion
🔔 notification
received
11

Flow canvas > + New step > Control > Scope > configure Run after on failure

Add error handling with a Scope and Send Email action

Wrap all your actions in a Scope block so you can handle failures cleanly. Click the '...' menu on any action, then 'Add a parallel branch' is not what you want here — instead, use the 'Scope' control from the Control connector to group your steps. After the Scope, add a 'Run after' configured to trigger on failure, and add a 'Send an email (V2)' action (Office 365 Outlook connector) to alert you when the flow fails, including the error message and the Slack channel name in the email body.

  1. 1Click '+ New step' before the Slack 'Get message' action
  2. 2Search 'Control' and select 'Scope'
  3. 3Drag all existing actions into the Scope block
  4. 4Add a new step after the Scope
  5. 5Click '...' on that step and choose 'Configure run after'
  6. 6Check 'has failed' and uncheck 'is successful'
  7. 7Add 'Send an email (V2)' with the error details in the body
What you should see: The flow canvas should show all archival steps nested inside a Scope block, with a separate failure-notification branch below it configured to run only on error.

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

VerdictWhy n8n for this workflow

Use Power Automate for this if your team is already inside the Microsoft 365 ecosystem and your IT department has locked down third-party automation tools. Power Automate is the path of least resistance when you need to get something approved by an M365 admin — it's already in the tenant. It also makes sense if you need the failure notification to route through Outlook or Teams, since those connectors are native and don't cost extra. The one scenario where you'd pick something else: if you need to cover more than 3-4 Slack channels, the one-flow-per-channel limitation becomes a real maintenance problem. Use Make instead — its Slack module supports wildcard channel monitoring in a single scenario.

Cost

The cost math here is straightforward. Power Automate charges per flow run, and this workflow consumes 5 actions per archived message: Get message, Get user profile, Compose, Create a page, Append block children. At the $15/user/month Power Automate Premium plan, you get 40,000 action runs per month. If your team archives 200 messages per month, that's 1,000 action runs — well within the limit. At 500 messages/month you're at 2,500 runs, still fine. The cost only becomes a factor above 8,000 archived messages/month, which is extremely rare for this use case. Compare that to Zapier's Professional plan at $49/month, which gives you 2,000 tasks — at 200 archives/month, Zapier would consume 800 tasks just for this flow (4 steps per Zap). Power Automate is cheaper at any meaningful volume if you're already paying for M365.

Tradeoffs

Here's how the alternatives stack up. Make handles multi-channel archival in one scenario using a Router module with channel-based filters — Power Automate can't do that cleanly. Zapier has a native Slack 'New Reaction Added' trigger that's faster to configure, but their Notion integration doesn't support Append Block Children, so you lose the page body — just metadata in properties. n8n gives you a Notion node that handles both Create Page and Append Blocks in one node with full JSON control, which is cleaner than Power Automate's two-step approach. Pipedream lets you call the Slack and Notion APIs directly with full JavaScript, which means you can handle thread replies, attachments, and custom formatting that no connector supports. Power Automate is still the right call if M365 compliance, DLP policies, and staying inside the Microsoft trust boundary matter to your organization — that's a real constraint in healthcare, finance, and government.

Three things you'll hit after setup. First, the Slack connector in Power Automate throttles at around 100 connection requests per minute across all flows in your tenant using the same connection — if another team has Slack flows running, your archival flow can get queued and delayed beyond 90 seconds. Second, Notion's API rate limit is 3 requests per second. The 'Create a page' and 'Append block children' calls happen sequentially, and if a burst of reactions fires simultaneously (e.g., 10 people react to the same message in 5 seconds), you'll see 429 errors on the Notion side. Power Automate does not have built-in retry-with-backoff for premium connector calls — you'd need to add a Delay action manually. Third, Slack's message text field returns unrendered mrkdwn, not plain text or HTML. Asterisks, backticks, and angle brackets will appear as raw characters in your Notion page. If readable formatting matters, add a Compose step with replace() expressions to convert *bold* to the word 'bold' in brackets, or accept that the Notion archive will look slightly different from Slack's rendered view.

Ideas for what to build next

  • Archive full Slack threads, not just single messagesAdd a condition that checks for a thread_ts value in the trigger output. If the message is part of a thread, call the Slack 'Get replies' action and loop through each reply, appending each one as a separate paragraph block in the same Notion page.
  • Tag archived messages by topic using OpenAIAdd an Azure OpenAI or OpenAI HTTP action between 'Get message' and 'Create a page.' Pass the message body and ask it to return one of 5 predefined topic tags (Decision, Blocker, Action Item, Announcement, Question). Write the tag to a Notion select property so the database is filterable by type.
  • Send a confirmation reaction back to SlackAfter the Notion page is successfully created, add a Slack 'Add reaction' action at the end of the flow. Post a ✅ reaction to the original message using its timestamp and channel ID. This gives the person who pinned the message instant visual confirmation that the archive succeeded.

Related guides

Was this guide helpful?
Slack + Notion overviewPower Automate profile →