AutomationFlowsGeneral › Daily Product Hunt to Google Sheets

Daily Product Hunt to Google Sheets

Original n8n title: Code Schedule

Code Schedule. Uses scheduleTrigger, stickyNote, httpRequest, googleSheets. Scheduled trigger; 12 nodes.

Cron / scheduled trigger★★★★☆ complexity12 nodesHTTP RequestGoogle Sheets
General Trigger: Cron / scheduled Nodes: 12 Complexity: ★★★★☆ Added:

This workflow follows the Google Sheets → HTTP Request 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 →

Download .json
{
  "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": "### \ud83d\udd10 How to Get Your Product Hunt Token\n\nTo get your Product Hunt token, follow the official guide here:  \n\ud83d\udc49 [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": "### \ud83d\udcc4 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\ud83d\udc49 https://www.youtube.com/watch?v=pWGXlZBGu4k\n"
      },
      "typeVersion": 1
    },
    {
      "id": "4a0c04d4-3ce2-4ebb-94a3-2a0441e25e23",
      "name": "Fetches today\u2019s Product Hunt posts via API.",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "### \ud83d\udd10 How to Get Your Product Hunt Token\n\nTo get your Product Hunt token, follow the official guide here:  \n\ud83d\udc49 [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\u2019m **Ajetomobi Ifeoluwa** \u2013 the brains (and vibe) behind this template. When I\u2019m not crafting cool workflows, I\u2019m busy making the web more beautiful and functional as a **UI/UX Designer** and **Vibe Coder**. Want your project to stand out? Let\u2019s chat! Check out my [portfolio](https://ifeoluwaajetomobi.framer.website/) and my work on [Behance](https://www.behance.net/ajetomoifeoluw). Let\u2019s create something awesome together! \ud83c\udfa8\u2728\n\n"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Set Date1": {
      "main": [
        [
          {
            "node": "Fetches today\u2019s 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\u2019s Product Hunt posts via API.": {
      "main": [
        [
          {
            "node": "Extracts Product Info",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

How this works

Effortlessly track and analyse daily Product Hunt launches to identify emerging trends and opportunities without manual effort, saving hours of browsing and data entry. This workflow suits product managers, marketers, and developers keen on staying ahead in the tech landscape by automating the collection of fresh product insights. It begins with a scheduled trigger that fetches the day's top posts via the Product Hunt API, then extracts key details like descriptions and URLs before resolving any website redirects for accurate logging into Google Sheets.

Use this workflow for routine monitoring of Product Hunt activity, such as compiling weekly reports or feeding data into analytics tools, especially when handling high volumes of launches. Avoid it for real-time alerts, as the cron-based scheduling suits batch processing rather than instant notifications; opt for webhook triggers in those cases. Common variations include filtering posts by category in the code extraction step or appending data to Airtable instead of Google Sheets for more flexible storage.

About this workflow

Code Schedule. Uses scheduleTrigger, stickyNote, httpRequest, googleSheets. Scheduled trigger; 12 nodes.

Source: https://github.com/Zie619/n8n-workflows — original creator credit. Request a take-down →

More General workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

General

💥workflow n8n d'Auto-Post sur les réseaux sociaux - vide. Uses scheduleTrigger, googleSheets, httpRequest, stickyNote. Scheduled trigger; 15 nodes.

Google Sheets, HTTP Request
General

Blog Automation TEMPLATE. Uses scheduleTrigger, manualTrigger, googleSheets, lmChatOpenAi. Scheduled trigger; 35 nodes.

Google Sheets, OpenAI Chat, Chain Llm +1
General

Blog Automation TEMPLATE. Uses scheduleTrigger, manualTrigger, googleSheets, lmChatOpenAi. Scheduled trigger; 35 nodes.

Google Sheets, OpenAI Chat, Chain Llm +1
General

Wait Schedule. Uses googleDrive, lmChatGoogleGemini, outputParserStructured, stickyNote. Scheduled trigger; 34 nodes.

Google Drive, Google Gemini Chat, Output Parser Structured +4
General

Generate Leads with Google Maps - AlexK1919. Uses manualTrigger, scheduleTrigger, executeWorkflowTrigger, stopAndError. Event-driven trigger; 42 nodes.

Execute Workflow Trigger, Stop And Error, HTTP Request +1