{ "nodes": [ { "id": "adb2d3bc-c6ab-4bb6-b954-61956ca2836d", "name": "Sticky Note", "type": "n8n-nodes-base.stickyNote", "position": [ -1528.3572519550153, 3540 ], "parameters": { "width": 830.4857444594224, "height": 495.4835100729081, "content": "## Workflow installation\n* Add a \"slug\" text property to each blog post (this parameter will be synced with Webflow and will be used to determine if a post is new or already present in your Webflow collection)\n* Add a \"Sync to Webflow?\" checkbox to each blog post\n* Connect your accounts and run a test to fill Webflow nodes with the right fields\n\n[](https://postimg.cc/BLbbxpJp)" }, "typeVersion": 1 }, { "id": "a5a79fd3-7adb-4e56-8aa7-2fd0cfc22927", "name": "Get simple page data", "type": "n8n-nodes-base.notion", "position": [ -80, 4520 ], "parameters": { "pageId": { "__rl": true, "mode": "id", "value": "={{ $json.id }}" }, "resource": "databasePage", "operation": "get" }, "credentials": { "notionApi": { "id": "rxtaEXgFPg96muhy", "name": "My Notion account" } }, "executeOnce": true, "typeVersion": 2.2 }, { "id": "dbb56719-e091-4475-94fb-430cd58ce8bb", "name": "Get all page data", "type": "n8n-nodes-base.notion", "position": [ -120, 4840 ], "parameters": { "pageId": { "__rl": true, "mode": "id", "value": "={{ $json.id }}" }, "simple": false, "resource": "databasePage", "operation": "get" }, "credentials": { "notionApi": { "id": "rxtaEXgFPg96muhy", "name": "My Notion account" } }, "executeOnce": true, "typeVersion": 2.2 }, { "id": "af3fd27a-642e-4ec6-bc07-5d02076830e2", "name": "Take cover url", "type": "n8n-nodes-base.set", "position": [ 100, 4840 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "7f9960fb-9898-4d1a-b4d9-29c95fb7c144", "name": "cover_url", "type": "string", "value": "={{ $json.cover.external.url }}" } ] } }, "typeVersion": 3.3 }, { "id": "5910292c-2548-4ca2-b7e4-304f99712e8d", "name": "Merge1", "type": "n8n-nodes-base.merge", "position": [ 320, 4640 ], "parameters": { "mode": "combine", "options": {}, "combinationMode": "mergeByPosition" }, "typeVersion": 2.1 }, { "id": "65c81d79-770c-48d4-97b9-f22328c22465", "name": "Data transporter1", "type": "n8n-nodes-base.noOp", "position": [ 3220, 4900 ], "parameters": {}, "typeVersion": 1 }, { "id": "1bc81efb-d293-4c97-bcb8-e114de0e482c", "name": "Get all blog posts1", "type": "n8n-nodes-base.notion", "position": [ -1220, 4640 ], "parameters": { "options": {}, "resource": "databasePage", "operation": "getAll", "returnAll": true, "databaseId": { "__rl": true, "mode": "list", "value": "4587b66c-d670-45b5-93f0-69ba1b0f3924", "cachedResultUrl": "https://www.notion.so/4587b66cd67045b593f069ba1b0f3924", "cachedResultName": "My blog" } }, "credentials": { "notionApi": { "id": "rxtaEXgFPg96muhy", "name": "My Notion account" } }, "typeVersion": 2.2 }, { "id": "56392232-05c7-477f-911f-7713d6cfa25f", "name": "Is sync checked?1", "type": "n8n-nodes-base.filter", "position": [ -940, 4640 ], "parameters": { "options": {}, "conditions": { "options": { "leftValue": "", "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "461a5a59-f894-4dda-9233-175a1e228d23", "operator": { "type": "boolean", "operation": "true", "singleValue": true }, "leftValue": "={{ $json.property_sync_to_webflow }}", "rightValue": "" } ] } }, "typeVersion": 2 }, { "id": "2a9fab27-612e-4eb9-935c-fd802f39c96e", "name": "For each blog post1", "type": "n8n-nodes-base.splitInBatches", "position": [ -360, 4640 ], "parameters": { "options": {} }, "typeVersion": 3 }, { "id": "8f6d8e51-b92b-4780-b782-3f72203f40aa", "name": "Sticky Note17", "type": "n8n-nodes-base.stickyNote", "position": [ 540, 4720 ], "parameters": { "width": 777.880012347261, "height": 287.94399632670337, "content": "### ⚙️ Turn blocks into rich text\nThis is where the magic happens — Notion blocks are mapped and turned into their respective html version. Works with all the major rich text elements: headings 1, headings 2, headings 3, normal, bold and italic text, quotes, bulleted lists, numbered lists and images with captions." }, "typeVersion": 1 }, { "id": "9592c56d-9bb2-433e-b49c-ec634e3d1db2", "name": "Sticky Note18", "type": "n8n-nodes-base.stickyNote", "position": [ 1980, 4420 ], "parameters": { "width": 218.00983675699544, "height": 394.8629861599825, "content": "### ✅ Create a new post or update an existing one?\nThis node compares (by slug) your Notion post with all your Webflow posts and chooses whether to create a new one (in \"A only\" branch) or update an existing one (in \"different\" branch)." }, "typeVersion": 1 }, { "id": "3ffb06d2-c1f1-4ce1-961f-8ece894d6cca", "name": "Create post1", "type": "n8n-nodes-base.webflow", "position": [ 2400, 4460 ], "parameters": { "siteId": "65a40576635069142ed11d7c", "fieldsUi": { "fieldValues": [ { "fieldId": "name", "fieldValue": "={{ $json[\"name\"] }}" }, { "fieldId": "slug", "fieldValue": "={{ $json.property_slug }}" }, { "fieldId": "blog-post-richt-text", "fieldValue": "={{ $json.newRichText }}" }, { "fieldId": "_archived", "fieldValue": "false" }, { "fieldId": "_draft", "fieldValue": "true" }, { "fieldId": "blog-post-featured-image-photo", "fieldValue": "={{ $json.cover_url }}" }, { "fieldId": "blog-post-thumbnail-image-photo", "fieldValue": "={{ $json.cover_url }}" } ] }, "operation": "create", "collectionId": "65a40577635069142ed11dd8", "authentication": "oAuth2" }, "credentials": { "webflowOAuth2Api": { "id": "cGhEXKKL99szTUa1", "name": "Webflow account" } }, "retryOnFail": true, "typeVersion": 1 }, { "id": "e6490f39-b420-488c-b407-948425615764", "name": "Sticky Note19", "type": "n8n-nodes-base.stickyNote", "position": [ -140, 3960 ], "parameters": { "width": 233.87813121439967, "height": 389.3234455133497, "content": "### 🎉 Success\nSend a success message where you want.\n\nYou can remove this node.\n\nNote: If you're on it, you may need to refresh the Webflow page." }, "typeVersion": 1 }, { "id": "13568b0a-9665-4149-b848-2dc355b91126", "name": "Update slug on posts1", "type": "n8n-nodes-base.notion", "position": [ 2920, 4760 ], "parameters": { "pageId": { "__rl": true, "mode": "id", "value": "={{ $('Compare by slug1').item.json.different.id.inputA }}" }, "options": {}, "resource": "databasePage", "operation": "update", "propertiesUi": { "propertyValues": [ { "key": "slug|rich_text", "textContent": "={{ $json.slug }}" } ] } }, "credentials": { "notionApi": { "id": "rxtaEXgFPg96muhy", "name": "My Notion account" } }, "retryOnFail": true, "typeVersion": 2.2 }, { "id": "8574c1d2-491d-4bbb-bcc1-0bef64b321a2", "name": "Slug uniqueness checker and differentiator1", "type": "n8n-nodes-base.code", "notes": "Add a number to the slug if it's not unique", "position": [ -660, 4640 ], "parameters": { "jsCode": "const data = $input.all().map(item => item.json)\nconst slugCount = {};\n\nreturn data.map(item => {\n let slug = item.property_slug;\n \n if (slugCount[slug]) {\n slugCount[slug] += 1;\n slug = `${slug}-${slugCount[slug]}`;\n } else {\n slugCount[slug] = 1;\n }\n \n item.property_slug = slug;\n return item;\n});" }, "notesInFlow": true, "typeVersion": 2 }, { "id": "21755856-9123-4acd-b343-3af878d665ad", "name": "Success message1", "type": "n8n-nodes-base.slack", "position": [ -80, 4175 ], "parameters": { "text": "=[Notion to Webflow] — \"{{ $json.name }}\" successfully synced 🎉", "select": "channel", "channelId": { "__rl": true, "mode": "list", "value": "C07719A0GF5", "cachedResultName": "general" }, "otherOptions": {}, "authentication": "oAuth2" }, "credentials": { "slackOAuth2Api": { "id": "qY28oJXU3BH6OrP3", "name": "Desengineers Account" } }, "typeVersion": 2.2 }, { "id": "6c232d4a-464b-4d5a-992b-f649d955eb1e", "name": "Merge2", "type": "n8n-nodes-base.merge", "position": [ 2660, 4540 ], "parameters": { "mode": "combine", "options": {}, "combinationMode": "mergeByPosition" }, "typeVersion": 2.1 }, { "id": "6af0cab5-8f70-435f-a341-c22d157d9200", "name": "Compare by slug1", "type": "n8n-nodes-base.compareDatasets", "position": [ 2040, 4640 ], "parameters": { "options": {}, "mergeByFields": { "values": [ { "field1": "property_slug", "field2": "slug" } ] } }, "typeVersion": 2.3 }, { "id": "54a7dcf6-188e-4ca5-bc1e-3e76d5536236", "name": "Add slug to posts1", "type": "n8n-nodes-base.notion", "position": [ 2900, 4540 ], "parameters": { "pageId": { "__rl": true, "mode": "id", "value": "={{ $json.id }}" }, "options": {}, "resource": "databasePage", "operation": "update", "propertiesUi": { "propertyValues": [ { "key": "slug|rich_text", "textContent": "={{ $json.slug }}" } ] } }, "credentials": { "notionApi": { "id": "rxtaEXgFPg96muhy", "name": "My Notion account" } }, "retryOnFail": true, "typeVersion": 2.2 }, { "id": "f9a66b20-ce82-4f36-b145-283dadf97d34", "name": "Get all collection posts1", "type": "n8n-nodes-base.webflow", "position": [ 1720, 4780 ], "parameters": { "siteId": "65a40576635069142ed11d7c", "operation": "getAll", "returnAll": true, "collectionId": "65a40577635069142ed11dd8", "authentication": "oAuth2" }, "credentials": { "webflowOAuth2Api": { "id": "cGhEXKKL99szTUa1", "name": "Webflow account" } }, "typeVersion": 1 }, { "id": "c09f3782-12a1-4a91-945d-cd1ed14bfeb3", "name": "Data transporter, Notion posts to sync1", "type": "n8n-nodes-base.noOp", "position": [ 1720, 4480 ], "parameters": {}, "typeVersion": 1 }, { "id": "9dc3ee15-4b4c-463c-a3b5-17b1dcb275da", "name": "Craft the rich text element1", "type": "n8n-nodes-base.code", "position": [ 1160, 4836 ], "parameters": { "jsCode": "const blocks = $input.all().map(item => item.json);\n\nlet newRichText = '';\nlet bulletedListItems = [];\nlet numberedListItems = [];\n\nblocks.forEach(block => {\n if (block.type === 'bulleted_list_item') {\n bulletedListItems.push(block.html);\n } else if (block.type === 'numbered_list_item') {\n numberedListItems.push(block.html);\n } else {\n if (bulletedListItems.length > 0) {\n newRichText += `
${block.paragraph.text.map(item => {\n let content = item.text.content.trim();\n if (item.annotations.bold) content = `${content}`;\n if (item.annotations.italic) content = `${content}`;\n if (item.text.link) content = `${content}`;\n return content;\n }).join(' ') || ' '}
`; // the space inside the apostrophes is on purpose, otherwise Webflow will automatically delete the empty blocks\n break;\n case 'quote':\n html = block.quote.text.map(item => item.text.content).join(' ');\n html = `${html}`;\n break;\n case 'bulleted_list_item':\n html = block.bulleted_list_item.text.map(item => item.text.content).join(' ');\n html = `
${codeContent}
`\n break\n default:\n html = block.content ? `