{ "meta": { "instanceId": "431926ace0ab32761b92304a05ffb4819a2a2a8ee5de45404953945769b5412a" }, "nodes": [ { "id": "53bf4cb6-8f55-4d8d-b4af-48345f75cdd5", "name": "Daily Trigger1", "type": "n8n-nodes-base.scheduleTrigger", "position": [ -660, 6580 ], "parameters": { "rule": { "interval": [ {} ] } }, "typeVersion": 1 }, { "id": "774624c1-cb4d-4355-9ed7-448d393c5f3b", "name": "Set Date1", "type": "n8n-nodes-base.set", "position": [ -440, 6580 ], "parameters": { "values": { "string": [ { "name": "today", "value": "={{ new Date().toISOString().split('T')[0] }}" } ] }, "options": {} }, "typeVersion": 1 }, { "id": "951eb189-8143-48d7-88c9-3ce235de83f6", "name": "Sticky Note16", "type": "n8n-nodes-base.stickyNote", "position": [ -260, 6400 ], "parameters": { "content": "### 🔐 How to Get Your Product Hunt Token\n\nTo get your Product Hunt token, follow the official guide here: \n👉 [Product Hunt OAuth Token Guide](https://api.producthunt.com/v2/docs/oauth_user_authentication/oauth_authorize_ask_for_access_grant_code_on_behalf_of_the_user)\n" }, "typeVersion": 1 }, { "id": "ae83bb19-a981-4b28-8dcd-ecd9501bd3d0", "name": "Sticky Note17", "type": "n8n-nodes-base.stickyNote", "position": [ 820, 6280 ], "parameters": { "width": 360, "height": 280, "content": "### 📄 How to Connect Google Sheets in n8n\n\nTo connect your Google Sheets to n8n:\n\n1. Go to your n8n Credentials page.\n2. Select **Google Sheets** and add new credentials.\n3. Authenticate your Google account and give the required permissions.\n\nFollow the full guide here: \n👉 https://www.youtube.com/watch?v=pWGXlZBGu4k\n" }, "typeVersion": 1 }, { "id": "4a0c04d4-3ce2-4ebb-94a3-2a0441e25e23", "name": "Fetches today’s Product Hunt posts via API.", "type": "n8n-nodes-base.httpRequest", "notes": "### 🔐 How to Get Your Product Hunt Token\n\nTo get your Product Hunt token, follow the official guide here: \n👉 [Product Hunt OAuth Token Guide](https://api.producthunt.com/v2/docs/oauth_user_authentication/oauth_authorize_ask_for_access_grant_code_on_behalf_of_the_user)\n", "position": [ -220, 6580 ], "parameters": { "url": "https://api.producthunt.com/v2/api/graphql", "method": "POST", "options": {}, "sendBody": true, "sendHeaders": true, "bodyParameters": { "parameters": [ { "name": "query", "value": "query { posts(first: 10, postedAfter: \"{{ $node[\\\"Set Date1\\\"].json[\\\"today\\\"] }}T00:00:00Z\", postedBefore: \"{{ $node[\\\"Set Date1\\\"].json[\\\"today\\\"] }}T23:59:59Z\") { edges { node { name tagline description website } cursor } pageInfo { hasNextPage endCursor } } }" } ] }, "headerParameters": { "parameters": [ { "name": "Authorization", "value": "=Bearer YOUR_PRODUCT_HUNT_API_KEY" }, { "name": "User-Agent", "value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" } ] } }, "notesInFlow": false, "typeVersion": 4.2 }, { "id": "994c8a22-ce3a-42cf-95e1-9512f1525fd7", "name": "Extracts Product Info", "type": "n8n-nodes-base.code", "position": [ 0, 6580 ], "parameters": { "jsCode": "return $json.data.posts.edges.map(edge => {\n return {\n json: {\n name: edge.node.name,\n tagline: edge.node.tagline,\n description: edge.node.description,\n website: edge.node.website\n }\n };\n});\n" }, "typeVersion": 2 }, { "id": "f7846147-cd50-4b5e-bb79-0f17ff7d5900", "name": "Resolve Website Redirection", "type": "n8n-nodes-base.httpRequest", "position": [ 220, 6680 ], "parameters": { "url": "={{ $json.website }}\n", "options": { "fullResponse": true, "followRedirect": false, "followAllRedirects": false, "ignoreResponseCode": true }, "responseFormat": "string", "dataPropertyName": "body", "allowUnauthorizedCerts": true }, "typeVersion": 1 }, { "id": "11f5df7a-bc46-4ae6-b97d-0ce8c15d804d", "name": "Data 2 (website url)", "type": "n8n-nodes-base.set", "position": [ 440, 6680 ], "parameters": { "values": { "string": [ { "name": "next_url", "value": "={{$json[\"headers\"][\"location\"]}}" } ] }, "options": {}, "keepOnlySet": true }, "typeVersion": 1 }, { "id": "3fd9b50e-c30b-44dd-ac53-83b0a597db2e", "name": "Data 1 (product info)", "type": "n8n-nodes-base.set", "position": [ 440, 6480 ], "parameters": { "values": { "string": [ { "name": "name", "value": "={{ $json.name }}" }, { "name": "tagline", "value": "={{ $json.tagline }}" }, { "name": "description", "value": "={{ $json.description }}" } ] }, "options": {}, "keepOnlySet": true }, "typeVersion": 1 }, { "id": "68acc44b-10cd-4bae-bf01-b304cd753f15", "name": "Merge Data", "type": "n8n-nodes-base.function", "position": [ 660, 6580 ], "parameters": { "functionCode": "// Initialize empty arrays for both data sources\nlet productData = [];\nlet redirectData = [];\n\ntry {\n productData = $items(\"Data to Keep4\");\n} catch (error) {\n console.log(\"Error fetching product data:\", error.message);\n}\n\ntry {\n redirectData = $items(\"Data to Keep3\");\n} catch (error) {\n console.log(\"Error fetching redirect data:\", error.message);\n}\n\nconst mergedItems = [];\n\nfor (let i = 0; i < productData.length; i++) {\n const product = productData[i].json;\n \n const mergedItem = {\n name: product.name,\n tagline: product.tagline,\n description: product.description,\n next_url: null\n };\n \n if (i < redirectData.length && redirectData[i] && redirectData[i].json) {\n let url = redirectData[i].json.next_url;\n // Remove ?ref=producthunt from the URL\n if (url && url.includes('?ref=producthunt')) {\n url = url.replace('?ref=producthunt', '');\n }\n mergedItem.next_url = url;\n }\n \n mergedItems.push({ json: mergedItem });\n}\n\nconsole.log(`Product data items: ${productData.length}`);\nconsole.log(`Redirect data items: ${redirectData.length}`);\nconsole.log(`Merged items: ${mergedItems.length}`);\n\nreturn mergedItems;" }, "typeVersion": 1 }, { "id": "39429f34-19d1-488a-9603-7b25f6042fa6", "name": "Appends all details", "type": "n8n-nodes-base.googleSheets", "position": [ 880, 6580 ], "parameters": { "columns": { "value": { "name": "={{ $json.name }}", "tagline": "={{ $json.tagline }}", "description": "={{ $json.description }}" }, "schema": [ { "id": "name", "type": "string", "display": true, "removed": false, "required": false, "displayName": "name", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "tagline", "type": "string", "display": true, "required": false, "displayName": "tagline", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "description", "type": "string", "display": true, "required": false, "displayName": "description", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "next_url", "type": "string", "display": true, "removed": false, "required": false, "displayName": "next_url", "defaultMatch": false, "canBeUsedToMatch": true } ], "mappingMode": "autoMapInputData", "matchingColumns": [ "name" ], "attemptToConvertTypes": false, "convertFieldsToString": false }, "options": {}, "operation": "appendOrUpdate", "sheetName": { "__rl": true, "mode": "list", "value": "gid=0", "cachedResultUrl": "demo", "cachedResultName": "Sheet1" }, "documentId": { "__rl": true, "mode": "list", "value": "demo", "cachedResultUrl": "demo", "cachedResultName": "Get product hunt products" }, "authentication": "serviceAccount" }, "typeVersion": 4.5 }, { "id": "6be5f1a1-c6e9-4dea-9199-523cd7f4b659", "name": "Sticky Note18", "type": "n8n-nodes-base.stickyNote", "position": [ -980, 6380 ], "parameters": { "width": 280, "height": 260, "content": "### About Me \n\nHey there! I’m **Ajetomobi Ifeoluwa** – the brains (and vibe) behind this template. When I’m not crafting cool workflows, I’m busy making the web more beautiful and functional as a **UI/UX Designer** and **Vibe Coder**. Want your project to stand out? Let’s chat! Check out my [portfolio](https://ifeoluwaajetomobi.framer.website/) and my work on [Behance](https://www.behance.net/ajetomoifeoluw). Let’s create something awesome together! 🎨✨\n\n" }, "typeVersion": 1 } ], "pinData": {}, "connections": { "Set Date1": { "main": [ [ { "node": "Fetches today’s Product Hunt posts via API.", "type": "main", "index": 0 } ] ] }, "Merge Data": { "main": [ [ { "node": "Appends all details", "type": "main", "index": 0 } ] ] }, "Daily Trigger1": { "main": [ [ { "node": "Set Date1", "type": "main", "index": 0 } ] ] }, "Data 2 (website url)": { "main": [ [ { "node": "Merge Data", "type": "main", "index": 0 } ] ] }, "Data 1 (product info)": { "main": [ [ { "node": "Merge Data", "type": "main", "index": 0 } ] ] }, "Extracts Product Info": { "main": [ [ { "node": "Resolve Website Redirection", "type": "main", "index": 0 }, { "node": "Data 1 (product info)", "type": "main", "index": 0 } ] ] }, "Resolve Website Redirection": { "main": [ [ { "node": "Data 2 (website url)", "type": "main", "index": 0 } ] ] }, "Fetches today’s Product Hunt posts via API.": { "main": [ [ { "node": "Extracts Product Info", "type": "main", "index": 0 } ] ] } } }