{ "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[![image.png](https://i.postimg.cc/xCymVp7w/image.png)](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 += ``;\n bulletedListItems = [];\n }\n if (numberedListItems.length > 0) {\n newRichText += `
    ${numberedListItems.join('')}
`;\n numberedListItems = [];\n }\n newRichText += block.html;\n }\n});\n\nif (bulletedListItems.length > 0) {\n newRichText += ``;\n}\nif (numberedListItems.length > 0) {\n newRichText += `
    ${numberedListItems.join('')}
`;\n}\n\nconst output = [{ newRichText }];\nreturn output;\n\n" }, "typeVersion": 2 }, { "id": "e4ca0e5a-21bb-4d38-8448-8195b8994c12", "name": "Turn blocks into HTML1", "type": "n8n-nodes-base.code", "position": [ 860, 4840 ], "parameters": { "jsCode": "const blocks = $input.all().map(item => item.json);\nconst output = [];\n\nblocks.forEach(block => {\n let html = '';\n \n switch (block.type) {\n case 'heading_1':\n html = block.heading_1.text.map(item => item.text.content).join(' ');\n html = `

${html}

`;\n break;\n case 'heading_2':\n html = block.heading_2.text.map(item => item.text.content).join(' ');\n html = `

${html}

`;\n break;\n case 'heading_3':\n html = block.heading_3.text.map(item => item.text.content).join(' ');\n html = `

${html}

`;\n break;\n case 'paragraph':\n html = `

${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 = `
  • ${html}
  • `;\n break;\n case 'numbered_list_item':\n html = block.numbered_list_item.text.map(item => item.text.content).join(' ');\n html = `
  • ${html}
  • `;\n break;\n case 'image':\n const caption = block.image.caption.map(item => item.text.content).join(' ');\n html = `
    \"${caption}\"
    ${caption}
    `;\n break;\n case 'code':\n const codeContent = block.code.text.map(item => item.text.content).join('\\n')\n html = `
    ${codeContent}
    `\n break\n default:\n html = block.content ? `
    ${block.content}
    ` : '';\n }\n\n if (html) {\n output.push({\n block_id: block.id,\n type: block.type,\n html\n });\n }\n});\n\nreturn output;\n" }, "typeVersion": 2 }, { "id": "719f5116-5e60-488c-81c2-d55cea2e2646", "name": "Get blocks1", "type": "n8n-nodes-base.notion", "position": [ 580, 4837 ], "parameters": { "blockId": { "__rl": true, "mode": "id", "value": "={{ $json.id }}" }, "resource": "block", "operation": "getAll", "returnAll": true, "simplifyOutput": false }, "credentials": { "notionApi": { "id": "rxtaEXgFPg96muhy", "name": "My Notion account" } }, "typeVersion": 2.2 }, { "id": "23f88f9c-ef4a-4158-bff5-728e2cf0383a", "name": "Update in \"Blog Posts\"", "type": "n8n-nodes-base.webflow", "maxTries": 3, "position": [ 2660, 4780 ], "parameters": { "itemId": "={{ $json.webflow_item_id }}", "siteId": "65a40576635069142ed11d7c", "fieldsUi": { "fieldValues": [ { "fieldId": "_draft", "fieldValue": "true" }, { "fieldId": "_archived", "fieldValue": "false" }, { "fieldId": "name", "fieldValue": "={{ $json.name }}" }, { "fieldId": "slug", "fieldValue": "={{ $json.property_slug }}" }, { "fieldId": "blog-post-richt-text", "fieldValue": "={{ $json.newRichText }}" }, { "fieldId": "blog-post-featured-image-photo", "fieldValue": "={{ $json.cover_url }}" }, { "fieldId": "blog-post-thumbnail-image-photo", "fieldValue": "={{ $json.cover_url }}" } ] }, "operation": "update", "collectionId": "65a40577635069142ed11dd8", "authentication": "oAuth2" }, "credentials": { "webflowOAuth2Api": { "id": "cGhEXKKL99szTUa1", "name": "Webflow account" } }, "retryOnFail": true, "typeVersion": 1, "alwaysOutputData": false }, { "id": "6db40a4d-4acd-40f3-8830-f17e00678e39", "name": "Add Webflow item id to Notion data", "type": "n8n-nodes-base.code", "position": [ 2400, 4760 ], "parameters": { "mode": "runOnceForEachItem", "jsCode": "const compareResult = $json\nconst notionData = $('Final Notion post data').item.json\n\nconst output = {\n ...notionData, // spread notion data\n webflow_item_id: compareResult.different._id.inputB // add the webflow item id\n}\n\nreturn output" }, "typeVersion": 2 }, { "id": "49e3d52c-a95a-4ac0-ae6a-69e4a722a628", "name": "Final Notion post data", "type": "n8n-nodes-base.merge", "position": [ 1380, 4640 ], "parameters": { "mode": "combine", "options": {}, "combinationMode": "mergeByPosition" }, "typeVersion": 2.1 }, { "id": "23755e8c-0012-4a72-ad9e-f450ceca1de4", "name": "Sticky Note1", "type": "n8n-nodes-base.stickyNote", "position": [ -146, 4720 ], "parameters": { "width": 366.7438380520149, "height": 282.04364735085795, "content": "### No wastes\nThese nodes extract the cover image url of the Notion page to make it easy for you to use it in the collection fields." }, "typeVersion": 1 }, { "id": "cb16a61b-73bc-491b-b4ce-b4dc5a5f21fc", "name": "Schedule Trigger", "type": "n8n-nodes-base.scheduleTrigger", "position": [ -1480, 4640 ], "parameters": { "rule": { "interval": [ {} ] } }, "typeVersion": 1.2 } ], "connections": { "Merge1": { "main": [ [ { "node": "Final Notion post data", "type": "main", "index": 0 }, { "node": "Get blocks1", "type": "main", "index": 0 } ] ] }, "Merge2": { "main": [ [ { "node": "Add slug to posts1", "type": "main", "index": 0 } ] ] }, "Get blocks1": { "main": [ [ { "node": "Turn blocks into HTML1", "type": "main", "index": 0 } ] ] }, "Create post1": { "main": [ [ { "node": "Merge2", "type": "main", "index": 0 } ] ] }, "Take cover url": { "main": [ [ { "node": "Merge1", "type": "main", "index": 1 } ] ] }, "Compare by slug1": { "main": [ [ { "node": "Create post1", "type": "main", "index": 0 }, { "node": "Merge2", "type": "main", "index": 1 } ], null, [ { "node": "Add Webflow item id to Notion data", "type": "main", "index": 0 } ] ] }, "Schedule Trigger": { "main": [ [ { "node": "Get all blog posts1", "type": "main", "index": 0 } ] ] }, "Data transporter1": { "main": [ [ { "node": "For each blog post1", "type": "main", "index": 0 } ] ] }, "Get all page data": { "main": [ [ { "node": "Take cover url", "type": "main", "index": 0 } ] ] }, "Is sync checked?1": { "main": [ [ { "node": "Slug uniqueness checker and differentiator1", "type": "main", "index": 0 } ] ] }, "Add slug to posts1": { "main": [ [ { "node": "Data transporter1", "type": "main", "index": 0 } ] ] }, "For each blog post1": { "main": [ [ { "node": "Success message1", "type": "main", "index": 0 } ], [ { "node": "Get simple page data", "type": "main", "index": 0 }, { "node": "Get all page data", "type": "main", "index": 0 } ] ] }, "Get all blog posts1": { "main": [ [ { "node": "Is sync checked?1", "type": "main", "index": 0 } ] ] }, "Get simple page data": { "main": [ [ { "node": "Merge1", "type": "main", "index": 0 } ] ] }, "Update slug on posts1": { "main": [ [ { "node": "Data transporter1", "type": "main", "index": 0 } ] ] }, "Final Notion post data": { "main": [ [ { "node": "Data transporter, Notion posts to sync1", "type": "main", "index": 0 }, { "node": "Get all collection posts1", "type": "main", "index": 0 } ] ] }, "Turn blocks into HTML1": { "main": [ [ { "node": "Craft the rich text element1", "type": "main", "index": 0 } ] ] }, "Update in \"Blog Posts\"": { "main": [ [ { "node": "Update slug on posts1", "type": "main", "index": 0 } ] ] }, "Get all collection posts1": { "main": [ [ { "node": "Compare by slug1", "type": "main", "index": 1 } ] ] }, "Craft the rich text element1": { "main": [ [ { "node": "Final Notion post data", "type": "main", "index": 1 } ] ] }, "Add Webflow item id to Notion data": { "main": [ [ { "node": "Update in \"Blog Posts\"", "type": "main", "index": 0 } ] ] }, "Data transporter, Notion posts to sync1": { "main": [ [ { "node": "Compare by slug1", "type": "main", "index": 0 } ] ] }, "Slug uniqueness checker and differentiator1": { "main": [ [ { "node": "For each blog post1", "type": "main", "index": 0 } ] ] } } }