This workflow follows the HTTP Request → Slack 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": "Enterprise: Outlook & Slack Email Inbox Manager",
"nodes": [
{
"parameters": {
"event": "messageReceived",
"folderId": "Inbox",
"options": {}
},
"id": "outlook-trigger",
"name": "Outlook Trigger (New Email)",
"type": "n8n-nodes-base.microsoftOutlookTrigger",
"typeVersion": 1,
"position": [
100,
200
],
"credentials": {
"microsoftOutlookOAuth2Api": {
"name": "<your credential>"
}
},
"notes": "\u26a1 Trigger khi nh\u1eadn email m\u1edbi trong Inbox. C\u1ea7n credentials Microsoft Graph API OAuth2. Thay OUTLOOK_CREDENTIAL_ID b\u1eb1ng ID credential th\u1ef1c trong n8n."
},
{
"parameters": {
"values": {
"string": [
{
"name": "slackChannelId",
"value": "YOUR_SLACK_CHANNEL_ID"
}
]
},
"options": {}
},
"id": "config-vars",
"name": "Config Vars",
"type": "n8n-nodes-base.set",
"typeVersion": 2,
"position": [
250,
200
],
"notes": "C\u1ea5u h\u00ecnh c\u00e1c bi\u1ebfn m\u00f4i tr\u01b0\u1eddng cho workflow (VD: Slack Channel ID)"
},
{
"parameters": {
"jsCode": "// Ph\u00e2n lo\u1ea1i email d\u1ef1a tr\u00ean VIP senders, keywords kh\u1ea9n c\u1ea5p v\u00e0 lo\u1ea1i tr\u1eeb qu\u1ea3ng c\u00e1o/newsletter\nconst email = $input.first().json;\n\n// Ch\u1ec9 x\u1eed l\u00fd email ch\u01b0a \u0111\u1ecdc\n// FIX: Th\u00eam console.log \u0111\u1ec3 d\u1ec5 debug khi email b\u1ecb b\u1ecf qua\nconst isRead = email.isRead === true;\nif (isRead) {\n console.log(`[SKIP] Email \u0111\u00e3 \u0111\u1ecdc: id=${email.id} | subject=\"${email.subject}\" \u2014 b\u1ecf qua, kh\u00f4ng x\u1eed l\u00fd.`);\n return [];\n}\n\nconst subject = (email.subject || '').toLowerCase();\nconst fromAddress = (email.from?.emailAddress?.address || '').toLowerCase();\nconst fromName = email.from?.emailAddress?.name || '';\nconst bodyPreview = email.bodyPreview || '';\nconst bodyContent = (email.body?.content || '').toLowerCase();\nconst fullText = `${subject} ${fromAddress} ${bodyContent}`;\n\n// Danh s\u00e1ch ng\u01b0\u1eddi g\u1eedi VIP c\u1ea7n ch\u00fa \u00fd ngay l\u1eadp t\u1ee9c\nconst vipSenders = [\n 'boss@company.com',\n 'director@company.com',\n 'important-client@corp.com',\n 'partner@company.com'\n];\n\n// T\u1eeb kh\u00f3a kh\u1ea9n c\u1ea5p c\u1ea7n h\u00e0nh \u0111\u1ed9ng ngay\nconst urgentKeywords = [\n 'urgent', 'kh\u1ea9n', 'g\u1ea5p', 'important', 'quan tr\u1ecdng', 'deadline', 'h\u1ea1n ch\u00f3t',\n 'payment', 'thanh to\u00e1n', 'overdue', 'qu\u00e1 h\u1ea1n', 'c\u1ea3nh b\u00e1o', 'warning', 'incident', 's\u1ef1 c\u1ed1'\n];\n\n// T\u1eeb kh\u00f3a b\u1ea3n tin ho\u1eb7c email t\u1ef1 \u0111\u1ed9ng kh\u00f4ng quan tr\u1ecdng\nconst newsletterKeywords = [\n 'unsubscribe', 'newsletter', 'digest', 'b\u1ea3n tin', 'h\u1ee7y \u0111\u0103ng k\u00fd',\n 'no-reply', 'noreply', 'do-not-reply', 'mailing list'\n];\n\n// T\u1eeb kh\u00f3a khuy\u1ebfn m\u00e3i ho\u1eb7c qu\u1ea3ng c\u00e1o\nconst promoKeywords = [\n 'sale', 'discount', 'gi\u1ea3m gi\u00e1', 'khuy\u1ebfn m\u00e3i', 'flash sale', '\u01b0u \u0111\u00e3i',\n 'coupon', 'voucher', '\u0111\u1eb7c bi\u1ec7t', 'qu\u00e0 t\u1eb7ng', 'offer', 'black friday'\n];\n\nconst isVip = vipSenders.some(sender => fromAddress.includes(sender));\nconst hasUrgent = urgentKeywords.some(kw => fullText.includes(kw));\nconst hasNewsletter = newsletterKeywords.some(kw => fullText.includes(kw));\nconst hasPromo = promoKeywords.some(kw => fullText.includes(kw));\n\nlet category = 'normal';\nlet action = 'notify_quiet';\nlet priority = 'medium';\n\nif (isVip || hasUrgent || email.importance === 'high') {\n category = 'important';\n action = 'notify_interactive';\n priority = 'high';\n} else if (hasNewsletter || hasPromo) {\n category = 'newsletter_promo';\n action = 'auto_archive';\n priority = 'low';\n} else {\n category = 'normal';\n action = 'notify_quiet';\n priority = 'medium';\n}\n\nreturn [{\n json: {\n id: email.id,\n subject: email.subject,\n from: email.from,\n bodyPreview: bodyPreview,\n receivedDateTime: email.receivedDateTime,\n importance: email.importance,\n category: category,\n action: action,\n priority: priority,\n classified_at: new Date().toISOString()\n }\n}];"
},
"id": "classify-email",
"name": "Classify Email",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
400,
200
],
"notes": "Ph\u00e2n lo\u1ea1i email th\u00e0nh: important (c\u1ea7n t\u01b0\u01a1ng t\u00e1c), newsletter_promo (t\u1ef1 \u0111\u1ed9ng l\u01b0u tr\u1eef), v\u00e0 normal (th\u00f4ng b\u00e1o th\u01b0\u1eddng). FIX: Email \u0111\u00e3 \u0111\u1ecdc \u2192 return [] d\u1eebng execution kh\u00f4ng l\u1ed7i, c\u00f3 ghi console.log \u0111\u1ec3 debug."
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": false,
"leftValue": "",
"typeValidation": "loose"
},
"conditions": [
{
"id": "notify-interactive-check",
"leftValue": "={{ $json.action }}",
"rightValue": "notify_interactive",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "notify_interactive"
},
{
"conditions": {
"options": {
"caseSensitive": false,
"leftValue": "",
"typeValidation": "loose"
},
"conditions": [
{
"id": "auto-archive-check",
"leftValue": "={{ $json.action }}",
"rightValue": "auto_archive",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "auto_archive"
},
{
"conditions": {
"options": {
"caseSensitive": false,
"leftValue": "",
"typeValidation": "loose"
},
"conditions": [
{
"id": "notify-quiet-check",
"leftValue": "={{ $json.action }}",
"rightValue": "notify_quiet",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "notify_quiet"
}
]
},
"options": {}
},
"id": "switch-action",
"name": "Switch Action",
"type": "n8n-nodes-base.switch",
"typeVersion": 3.2,
"position": [
500,
200
]
},
{
"parameters": {
"jsCode": "// Build Slack Block Kit payload \u0111\u1ec3 g\u1eedi interactive message\nconst d = $input.first().json;\nconst slackChannelId = $('Config Vars').first().json.slackChannelId;\n\nconst fromName = d.from?.emailAddress?.name || 'Kh\u00f4ng r\u00f5';\nconst fromAddr = d.from?.emailAddress?.address || '';\nconst subject = d.subject || '(Kh\u00f4ng c\u00f3 ti\u00eau \u0111\u1ec1)';\nconst preview = d.bodyPreview || 'Kh\u00f4ng c\u00f3 n\u1ed9i dung xem tr\u01b0\u1edbc.';\nconst priority = d.priority || 'medium';\nconst emailId = d.id || '';\nconst receivedAt = d.receivedDateTime\n ? new Date(d.receivedDateTime).toLocaleString('vi-VN', { timeZone: 'Asia/Ho_Chi_Minh' })\n : 'Kh\u00f4ng r\u00f5';\n\nconst blocks = [\n {\n type: 'header',\n text: { type: 'plain_text', text: '\ud83d\udce7 Outlook Inbox Manager', emoji: true }\n },\n {\n type: 'section',\n text: {\n type: 'mrkdwn',\n text: `*Email quan tr\u1ecdng m\u1edbi!* \ud83d\udd34\n\n*Ng\u01b0\u1eddi g\u1eedi:* ${fromName} <${fromAddr}>\n*Ch\u1ee7 \u0111\u1ec1:* ${subject}\n*Th\u1eddi gian:* ${receivedAt}\n\n*Xem tr\u01b0\u1edbc:*\n> ${preview.substring(0, 200)}`\n }\n },\n {\n type: 'actions',\n elements: [\n {\n type: 'button',\n text: { type: 'plain_text', text: 'L\u01b0u tr\u1eef \ud83d\udce6', emoji: true },\n style: 'primary',\n value: emailId,\n action_id: 'archive'\n },\n {\n type: 'button',\n text: { type: 'plain_text', text: '\u0110\u00e1nh d\u1ea5u \u0111\u00e3 \u0111\u1ecdc \u2705', emoji: true },\n value: emailId,\n action_id: 'mark_read'\n },\n {\n type: 'button',\n text: { type: 'plain_text', text: 'G\u1eafn c\u1edd \u2b50\ufe0f', emoji: true },\n value: emailId,\n action_id: 'flag'\n }\n ]\n }\n];\n\nreturn [{\n json: {\n channel: slackChannelId,\n text: `\ud83d\udce7 Email quan tr\u1ecdng t\u1eeb ${fromName}: ${subject}`,\n blocks: blocks,\n // Pass through email data\n _emailId: emailId,\n _subject: subject\n }\n}];"
},
"id": "code-build-slack-blocks",
"name": "Code: Build Slack Blocks",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
720,
100
],
"notes": "Build Block Kit JSON ph\u00eda JavaScript \u0111\u1ec3 \u0111\u1ea3m b\u1ea3o blocks \u0111\u01b0\u1ee3c serialize \u0111\u00fang."
},
{
"parameters": {
"method": "POST",
"url": "https://slack.com/api/chat.postMessage",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendBody": true,
"contentType": "json",
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ channel: $json.channel, text: $json.text, blocks: $json.blocks }) }}",
"options": {
"timeout": 10000
}
},
"id": "slack-interactive-alert",
"name": "Slack: Interactive Alert",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [
920,
100
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"notes": "G\u1ecdi tr\u1ef1c ti\u1ebfp Slack chat.postMessage API v\u1edbi blocks JSON. Credential: HTTP Header Auth v\u1edbi Name='Authorization', Value='Bearer xoxb-YOUR-BOT-TOKEN'."
},
{
"parameters": {
"resource": "message",
"operation": "move",
"messageId": "={{ $json.id }}",
"destinationId": "archive"
},
"id": "outlook-auto-archive",
"name": "Outlook: Auto Archive",
"type": "n8n-nodes-base.microsoftOutlook",
"typeVersion": 2,
"position": [
720,
240
],
"credentials": {
"microsoftOutlookOAuth2Api": {
"name": "<your credential>"
}
},
"notes": "T\u1ef1 \u0111\u1ed9ng di chuy\u1ec3n email qu\u1ea3ng c\u00e1o/newsletter v\u00e0o th\u01b0 m\u1ee5c Archive. FIX: D\u00f9ng destinationId='archive' (wellKnownFolderName h\u1ee3p l\u1ec7 theo Microsoft Graph API)."
},
{
"parameters": {
"resource": "message",
"operation": "update",
"messageId": "={{ $json.id }}",
"updateFields": {
"isRead": true
}
},
"id": "outlook-mark-read-auto",
"name": "Outlook: Mark Read (Auto)",
"type": "n8n-nodes-base.microsoftOutlook",
"typeVersion": 2,
"position": [
920,
240
],
"credentials": {
"microsoftOutlookOAuth2Api": {
"name": "<your credential>"
}
},
"notes": "\u0110\u00e1nh d\u1ea5u email qu\u1ea3ng c\u00e1o/newsletter \u0111\u00e3 l\u01b0u tr\u1eef l\u00e0 \u0111\u00e3 \u0111\u1ecdc."
},
{
"parameters": {
"select": "channel",
"channelId": "={{ $('Config Vars').first().json.slackChannelId }}",
"sendAsText": true,
"text": "=\ud83d\udce7 *Email th\u00f4ng th\u01b0\u1eddng:* \"{{ $json.subject || '(Kh\u00f4ng c\u00f3 ti\u00eau \u0111\u1ec1)' }}\" t\u1eeb *{{ $json.from?.emailAddress?.name || $json.from?.emailAddress?.address || 'Kh\u00f4ng r\u00f5' }}*",
"otherOptions": {}
},
"id": "slack-quiet-alert",
"name": "Slack: Quiet Alert",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.1,
"position": [
720,
380
],
"credentials": {
"slackApi": {
"name": "<your credential>"
}
},
"notes": "FIX: Th\u00eam '=' prefix \u0111\u1ec3 n8n evaluate expression trong text. G\u1eedi th\u00f4ng b\u00e1o text ng\u1eafn g\u1ecdn, kh\u00f4ng l\u00e0m \u1ed3n k\u00eanh."
},
{
"parameters": {
"httpMethod": "POST",
"path": "slack-interactive-outlook",
"responseMode": "onReceived",
"options": {}
},
"id": "slack-webhook",
"name": "Slack Interactivity Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
100,
600
],
"notes": "L\u1eafng nghe s\u1ef1 ki\u1ec7n ng\u01b0\u1eddi d\u00f9ng nh\u1ea5n n\u00fat tr\u00ean Slack. C\u1ea7n c\u1ea5u h\u00ecnh URL n\u00e0y trong Slack App \u2192 Interactive Components \u2192 Request URL: https://<n8n-host>/webhook/slack-interactive-outlook"
},
{
"parameters": {
"jsCode": "// FIX: Parse payload an to\u00e0n v\u1edbi error handling r\u00f5 r\u00e0ng\nconst body = $input.first().json.body;\n\nif (!body) {\n throw new Error('Kh\u00f4ng t\u00ecm th\u1ea5y body t\u1eeb Slack webhook. Ki\u1ec3m tra l\u1ea1i c\u1ea5u h\u00ecnh Slack App Interactivity.');\n}\n\nif (!body.payload) {\n throw new Error('Kh\u00f4ng t\u00ecm th\u1ea5y payload trong body. \u0110\u1ea3m b\u1ea3o Slack g\u1eedi \u0111\u00fang \u0111\u1ecbnh d\u1ea1ng application/x-www-form-urlencoded.');\n}\n\nlet payload;\ntry {\n payload = JSON.parse(body.payload);\n} catch (e) {\n throw new Error(`Kh\u00f4ng th\u1ec3 parse payload JSON t\u1eeb Slack: ${e.message}`);\n}\n\nif (!payload.actions || payload.actions.length === 0) {\n throw new Error('Payload kh\u00f4ng ch\u1ee9a actions. C\u00f3 th\u1ec3 \u0111\u00e2y kh\u00f4ng ph\u1ea3i s\u1ef1 ki\u1ec7n n\u00fat b\u1ea5m.');\n}\n\nconst action = payload.actions[0];\nconst actionId = action.action_id; // 'archive', 'mark_read', 'flag'\nconst emailId = action.value; // ID c\u1ee7a email Outlook\nconst responseUrl = payload.response_url;\nconst userName = payload.user?.username || payload.user?.name || 'unknown';\nconst channelId = payload.channel?.id;\nconst messageTs = payload.message?.ts;\nconst originalBlocks = payload.message?.blocks || [];\n\nreturn [{\n json: {\n action_id: actionId,\n email_id: emailId,\n response_url: responseUrl,\n user_name: userName,\n channel_id: channelId,\n message_ts: messageTs,\n original_blocks: originalBlocks\n }\n}];"
},
"id": "parse-slack-payload",
"name": "Parse Slack Payload",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
300,
600
],
"notes": "FIX: Th\u00eam error handling r\u00f5 r\u00e0ng cho t\u1eebng b\u01b0\u1edbc parse. Gi\u1ea3i m\u00e3 payload url-encoded c\u1ee7a Slack v\u00e0 tr\u1ea3 v\u1ec1 action_id, email_id, response_url."
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": false,
"leftValue": "",
"typeValidation": "loose"
},
"conditions": [
{
"id": "archive-check",
"leftValue": "={{ $json.action_id }}",
"rightValue": "archive",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "archive"
},
{
"conditions": {
"options": {
"caseSensitive": false,
"leftValue": "",
"typeValidation": "loose"
},
"conditions": [
{
"id": "mark-read-check",
"leftValue": "={{ $json.action_id }}",
"rightValue": "mark_read",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "mark_read"
},
{
"conditions": {
"options": {
"caseSensitive": false,
"leftValue": "",
"typeValidation": "loose"
},
"conditions": [
{
"id": "flag-check",
"leftValue": "={{ $json.action_id }}",
"rightValue": "flag",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "flag"
}
]
},
"options": {}
},
"id": "switch-action-slack",
"name": "Switch Action Slack",
"type": "n8n-nodes-base.switch",
"typeVersion": 3.2,
"position": [
500,
600
]
},
{
"parameters": {
"resource": "message",
"operation": "move",
"messageId": "={{ $json.email_id }}",
"destinationId": "archive"
},
"id": "outlook-action-archive",
"name": "Outlook Action: Archive",
"type": "n8n-nodes-base.microsoftOutlook",
"typeVersion": 2,
"position": [
720,
500
],
"credentials": {
"microsoftOutlookOAuth2Api": {
"name": "<your credential>"
}
},
"notes": "FIX: D\u00f9ng destinationId thay folderId. 'archive' l\u00e0 wellKnownFolderName h\u1ee3p l\u1ec7 theo Microsoft Graph API."
},
{
"parameters": {
"resource": "message",
"operation": "update",
"messageId": "={{ $json.email_id }}",
"updateFields": {
"isRead": true
}
},
"id": "outlook-action-mark-read",
"name": "Outlook Action: Mark Read",
"type": "n8n-nodes-base.microsoftOutlook",
"typeVersion": 2,
"position": [
720,
620
],
"credentials": {
"microsoftOutlookOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"resource": "message",
"operation": "update",
"messageId": "={{ $json.email_id }}",
"updateFields": {
"isRead": false,
"categories": [
"Important"
]
}
},
"id": "outlook-action-flag",
"name": "Outlook Action: Flag & Category",
"type": "n8n-nodes-base.microsoftOutlook",
"typeVersion": 2,
"position": [
720,
740
],
"credentials": {
"microsoftOutlookOAuth2Api": {
"name": "<your credential>"
}
},
"notes": "FIX: \u0110\u1eb7t isRead=false (gi\u1eef n\u1ed5i b\u1eadt) + g\u00e1n category 'Important'. \u26a0\ufe0f Category 'Important' ph\u1ea3i \u0111\u01b0\u1ee3c t\u1ea1o tr\u01b0\u1edbc trong Outlook: Settings \u2192 Categories \u2192 New. N\u1ebfu mu\u1ed1n d\u00f9ng flag thay category, c\u1ea7n HTTP Request node g\u1ecdi Graph API PATCH /messages/{id} v\u1edbi body {\"flag\":{\"flagStatus\":\"flagged\"}}."
},
{
"parameters": {
"jsCode": "// FIX: L\u1ea5y d\u1eef li\u1ec7u t\u1eeb Parse Slack Payload th\u00f4ng qua $() - an to\u00e0n trong c\u00f9ng m\u1ed9t execution\nconst slackData = $('Parse Slack Payload').first().json;\nconst originalBlocks = slackData.original_blocks || [];\nconst actionId = slackData.action_id;\nconst userName = slackData.user_name;\n\n// X\u00f3a b\u1ecf blocks ch\u1ee9a c\u00e1c n\u00fat b\u1ea5m (actions) \u0111\u1ec3 tr\u00e1nh click l\u1eb7p\nconst updatedBlocks = originalBlocks.filter(block => block.type !== 'actions');\n\nlet actionText = '';\nif (actionId === 'archive') {\n actionText = '\ud83d\udce6 \u0110\u00e3 l\u01b0u tr\u1eef (Archived)';\n} else if (actionId === 'mark_read') {\n actionText = '\u2705 \u0110\u00e3 \u0111\u00e1nh d\u1ea5u \u0111\u00e3 \u0111\u1ecdc (Marked Read)';\n} else if (actionId === 'flag') {\n actionText = '\u2b50\ufe0f \u0110\u00e3 g\u1eafn nh\u00e3n quan tr\u1ecdng (Flagged)';\n} else {\n actionText = `\u2753 H\u00e0nh \u0111\u1ed9ng kh\u00f4ng x\u00e1c \u0111\u1ecbnh: ${actionId}`;\n}\n\nconst processedAt = new Date().toLocaleTimeString('vi-VN', {\n timeZone: 'Asia/Ho_Chi_Minh',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit'\n});\n\n// Th\u00eam context th\u00f4ng b\u00e1o tr\u1ea1ng th\u00e1i m\u1edbi b\u00ean d\u01b0\u1edbi tin nh\u1eafn g\u1ed1c\nupdatedBlocks.push({\n \"type\": \"context\",\n \"elements\": [\n {\n \"type\": \"mrkdwn\",\n \"text\": `\ud83d\udfe2 *Tr\u1ea1ng th\u00e1i:* ${actionText} | Ng\u01b0\u1eddi x\u1eed l\u00fd: *@${userName}* l\u00fac ${processedAt}`\n }\n ]\n});\n\nreturn [{\n json: {\n response_url: slackData.response_url,\n payload: {\n blocks: updatedBlocks,\n replace_original: true\n }\n }\n}];"
},
"id": "prepare-slack-update",
"name": "Prepare Slack Update",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
980,
620
],
"notes": "C\u1eadp nh\u1eadt block kit g\u1ed1c: x\u00f3a n\u00fat b\u1ea5m, b\u1ed5 sung badge tr\u1ea1ng th\u00e1i. D\u00f9ng $('Parse Slack Payload') \u0111\u1ec3 truy c\u1eadp d\u1eef li\u1ec7u t\u1eeb node upstream trong c\u00f9ng execution."
},
{
"parameters": {
"method": "POST",
"url": "={{ $json.response_url }}",
"sendBody": true,
"contentType": "json",
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify($json.payload) }}",
"options": {
"timeout": 5000
}
},
"id": "update-slack-message",
"name": "Update Slack Message",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [
1200,
620
],
"notes": "FIX: S\u1eeda c\u1ea5u tr\u00fac body params \u2014 specifyBody v\u00e0 jsonBody ph\u1ea3i n\u1eb1m \u1edf top-level parameters, kh\u00f4ng l\u1ed3ng trong bodyParameters. D\u00f9ng JSON.stringify($json.payload) \u0111\u1ec3 serialize \u0111\u00fang c\u00e1ch."
}
],
"connections": {
"Outlook Trigger (New Email)": {
"main": [
[
{
"node": "Config Vars",
"type": "main",
"index": 0
}
]
]
},
"Config Vars": {
"main": [
[
{
"node": "Classify Email",
"type": "main",
"index": 0
}
]
]
},
"Classify Email": {
"main": [
[
{
"node": "Switch Action",
"type": "main",
"index": 0
}
]
]
},
"Switch Action": {
"main": [
[
{
"node": "Code: Build Slack Blocks",
"type": "main",
"index": 0
}
],
[
{
"node": "Outlook: Auto Archive",
"type": "main",
"index": 0
}
],
[
{
"node": "Slack: Quiet Alert",
"type": "main",
"index": 0
}
]
]
},
"Code: Build Slack Blocks": {
"main": [
[
{
"node": "Slack: Interactive Alert",
"type": "main",
"index": 0
}
]
]
},
"Outlook: Auto Archive": {
"main": [
[
{
"node": "Outlook: Mark Read (Auto)",
"type": "main",
"index": 0
}
]
]
},
"Slack Interactivity Webhook": {
"main": [
[
{
"node": "Parse Slack Payload",
"type": "main",
"index": 0
}
]
]
},
"Parse Slack Payload": {
"main": [
[
{
"node": "Switch Action Slack",
"type": "main",
"index": 0
}
]
]
},
"Switch Action Slack": {
"main": [
[
{
"node": "Outlook Action: Archive",
"type": "main",
"index": 0
}
],
[
{
"node": "Outlook Action: Mark Read",
"type": "main",
"index": 0
}
],
[
{
"node": "Outlook Action: Flag & Category",
"type": "main",
"index": 0
}
]
]
},
"Outlook Action: Archive": {
"main": [
[
{
"node": "Prepare Slack Update",
"type": "main",
"index": 0
}
]
]
},
"Outlook Action: Mark Read": {
"main": [
[
{
"node": "Prepare Slack Update",
"type": "main",
"index": 0
}
]
]
},
"Outlook Action: Flag & Category": {
"main": [
[
{
"node": "Prepare Slack Update",
"type": "main",
"index": 0
}
]
]
},
"Prepare Slack Update": {
"main": [
[
{
"node": "Update Slack Message",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1",
"saveManualExecutions": true,
"timezone": "Asia/Ho_Chi_Minh"
},
"staticData": null,
"tags": [
"enterprise",
"email",
"outlook",
"slack",
"automation",
"vietnamese"
],
"triggerCount": 2,
"versionId": "1.1.0",
"meta": {
"templateCredsSetupCompleted": false,
"usage": "H\u1ec7 th\u1ed1ng qu\u1ea3n l\u00fd h\u1ed9p th\u01b0 Outlook chuy\u00ean nghi\u1ec7p qua Slack, cho ph\u00e9p x\u1eed l\u00fd email nhanh (L\u01b0u tr\u1eef, \u0110\u00e1nh d\u1ea5u \u0111\u1ecdc, G\u1eafn c\u1edd) ngay tr\u00ean giao di\u1ec7n Slack.",
"version": "1.1.0",
"changelog": "v1.1.0: Fix Block Kit expressions (= prefix), fix HTTP body params, fix folderId\u2192destinationId, fix categories+isRead, add credentials, add error handling in Parse Slack Payload, add console.log for skipped emails."
}
}
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.
httpHeaderAuthmicrosoftOutlookOAuth2ApislackApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Enterprise: Outlook & Slack Email Inbox Manager. Uses microsoftOutlookTrigger, httpRequest, microsoftOutlook, slack. Event-driven trigger; 17 nodes.
Source: https://github.com/congdinh2008/n8n-compose/blob/e5a0032a41bd3c865a48d6219c819f70b9e0ec08/workflows/enterprise/14-outlook-slack-inbox/workflow.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.
This template is built to be customized for your specific needs. This template has the core logic and n8n node specific references sorted to work with dynamic file names throughout the workflow. Store
📘 Description
This workflow automatically detects duplicate invoices from Gmail. Incoming PDF attachments are scanned by the easybits AI Extractor, then checked against the Master Finance File in Google Sheets. Dup
This n8n workflow provides a comprehensive automation solution for processing email attachments, specifically targeting enhanced security protocols for organizations that use platforms like Outlook. I
This workflow automatically classifies and routes incoming Outlook emails into smart categories using n8n + OpenAI GPT-4.1-mini. It helps professionals and teams stay organized by intelligently sortin