AutomationFlowsData & Sheets › Content Pipeline: Web Capture Webhook

Content Pipeline: Web Capture Webhook

Content Pipeline: Web Capture Webhook. Uses notion, httpRequest. Webhook trigger; 11 nodes.

Webhook trigger★★★★☆ complexity11 nodesNotionHTTP Request
Data & Sheets Trigger: Webhook Nodes: 11 Complexity: ★★★★☆ Added:

This workflow follows the HTTP Request → Notion 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
{
  "name": "Content Pipeline: Web Capture Webhook",
  "nodes": [
    {
      "id": "aaaaaaaa-0000-4000-8000-000000000001",
      "name": "Web Capture Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        100,
        400
      ],
      "parameters": {
        "httpMethod": "POST",
        "path": "content-capture",
        "responseMode": "onReceived",
        "options": {}
      }
    },
    {
      "id": "aaaaaaaa-0000-4000-8000-000000000002",
      "name": "Unwrap Body",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        300,
        400
      ],
      "parameters": {
        "mode": "manual",
        "assignments": {
          "assignments": [
            {
              "id": "u1",
              "name": "title",
              "value": "={{ $json.body.title || \"Untitled\" }}",
              "type": "string"
            },
            {
              "id": "u2",
              "name": "url",
              "value": "={{ $json.body.url }}",
              "type": "string"
            },
            {
              "id": "u3",
              "name": "content",
              "value": "={{ $json.body.content || \"\" }}",
              "type": "string"
            },
            {
              "id": "u4",
              "name": "contentType",
              "value": "={{ $json.body.contentType || \"\" }}",
              "type": "string"
            },
            {
              "id": "u5",
              "name": "source",
              "value": "={{ $json.body.source || \"arcpush\" }}",
              "type": "string"
            },
            {
              "id": "u6",
              "name": "sourceType",
              "value": "={{ $json.body.sourceType || \"unknown\" }}",
              "type": "string"
            },
            {
              "id": "u7",
              "name": "capturedAt",
              "value": "={{ $json.body.capturedAt || $now.toISO() }}",
              "type": "string"
            },
            {
              "id": "u8",
              "name": "needsScrape",
              "value": "={{ $json.body.needsScrape === true || $json.body.needsScrape === \"true\" }}",
              "type": "boolean"
            },
            {
              "id": "u9",
              "name": "redditImages",
              "value": "={{ $json.body.redditImages || [] }}",
              "type": "array"
            }
          ]
        },
        "includeOtherFields": false,
        "options": {}
      }
    },
    {
      "id": "aaaaaaaa-0000-4000-8000-000000000003",
      "name": "Has Content?",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.4,
      "position": [
        520,
        400
      ],
      "parameters": {
        "mode": "rules",
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "id": "r1",
                    "leftValue": "={{ ($json.content || \"\") !== \"\" }}",
                    "rightValue": true,
                    "operator": {
                      "type": "boolean",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "hasContent"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "id": "r2",
                    "leftValue": "={{ $json.needsScrape }}",
                    "rightValue": true,
                    "operator": {
                      "type": "boolean",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "scrape"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "aaaaaaaa-0000-4000-8000-000000000004",
      "name": "Pass Through Content",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        740,
        300
      ],
      "parameters": {
        "mode": "manual",
        "assignments": {
          "assignments": []
        },
        "includeOtherFields": true,
        "options": {}
      }
    },
    {
      "id": "aaaaaaaa-0000-4000-8000-000000000005",
      "name": "Merge Branches",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.2,
      "position": [
        1560,
        400
      ],
      "parameters": {
        "mode": "append"
      }
    },
    {
      "id": "aaaaaaaa-0000-4000-8000-000000000006",
      "name": "Merge Scraped Fields",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1340,
        560
      ],
      "parameters": {
        "mode": "manual",
        "assignments": {
          "assignments": [
            {
              "id": "s1",
              "name": "title",
              "value": "={{ (typeof $json.data === \"object\" && $json.data !== null ? ($json.data.metadata && $json.data.metadata.title) : (($json.data || \"\").match(/^Title: (.+)$/m) || [])[1]) || $('Unwrap Body').first().json.title }}",
              "type": "string"
            },
            {
              "id": "s2",
              "name": "url",
              "value": "={{ $('Unwrap Body').first().json.url }}",
              "type": "string"
            },
            {
              "id": "s3",
              "name": "content",
              "value": "={{ typeof $json.data === \"string\" ? $json.data : (typeof $json.data === \"object\" && $json.data !== null ? ($json.data.markdown || \"\") : \"\") }}",
              "type": "string"
            },
            {
              "id": "s4",
              "name": "contentType",
              "value": "page-text",
              "type": "string"
            },
            {
              "id": "s5",
              "name": "source",
              "value": "={{ $('Unwrap Body').first().json.source }}",
              "type": "string"
            },
            {
              "id": "s6",
              "name": "sourceType",
              "value": "={{ $('Unwrap Body').first().json.sourceType }}",
              "type": "string"
            },
            {
              "id": "s7",
              "name": "redditImages",
              "value": "={{ [] }}",
              "type": "array"
            },
            {
              "id": "s8",
              "name": "scraper",
              "value": "={{ typeof $json.data === \"string\" && $json.data.length > 0 ? \"jina\" : (typeof $json.data === \"object\" && $json.data !== null && $json.data.markdown ? \"firecrawl\" : \"none\") }}",
              "type": "string"
            }
          ]
        },
        "includeOtherFields": false,
        "options": {}
      }
    },
    {
      "id": "aaaaaaaa-0000-4000-8000-000000000007",
      "name": "Normalize for Notion",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1780,
        400
      ],
      "parameters": {
        "mode": "manual",
        "assignments": {
          "assignments": [
            {
              "id": "n1",
              "name": "title",
              "value": "={{ $json.title || \"Untitled\" }}",
              "type": "string"
            },
            {
              "id": "n2",
              "name": "url",
              "value": "={{ $json.url }}",
              "type": "string"
            },
            {
              "id": "n3",
              "name": "source",
              "value": "web-capture",
              "type": "string"
            },
            {
              "id": "n4",
              "name": "source_type",
              "value": "manual",
              "type": "string"
            },
            {
              "id": "n5",
              "name": "summary",
              "value": "={{ ($json.content || \"\").substring(0, 500) }}",
              "type": "string"
            },
            {
              "id": "n6",
              "name": "comment",
              "value": "={{ [\"Scraped via \" + ($json.scraper || \"extension\"), ($json.redditImages && $json.redditImages.length > 0 ? \"Images: \" + $json.redditImages.join(\" | \") : \"\")].filter(Boolean).join(\" \u2014 \") }}",
              "type": "string"
            },
            {
              "id": "n7",
              "name": "scraper",
              "value": "={{ $json.scraper || \"extension\" }}",
              "type": "string"
            }
          ]
        },
        "includeOtherFields": false,
        "options": {}
      }
    },
    {
      "id": "aaaaaaaa-0000-4000-8000-000000000008",
      "name": "Save to Notion",
      "type": "n8n-nodes-base.notion",
      "typeVersion": 2.2,
      "position": [
        2000,
        400
      ],
      "parameters": {
        "resource": "databasePage",
        "operation": "create",
        "databaseId": {
          "__rl": true,
          "value": "REPLACE_WITH_DATABASE_ID",
          "mode": "id"
        },
        "title": "={{ $json.title }}",
        "simple": true,
        "propertiesUi": {
          "propertyValues": [
            {
              "key": "Source URL|url",
              "type": "url",
              "urlValue": "={{ $json.url }}"
            },
            {
              "key": "Source Type|select",
              "type": "select",
              "selectValue": "={{ $json.source_type }}"
            },
            {
              "key": "Summary|rich_text",
              "type": "rich_text",
              "textContent": "={{ $json.summary || \"\" }}"
            },
            {
              "key": "Comment|rich_text",
              "type": "rich_text",
              "textContent": "={{ $json.comment || \"\" }}"
            }
          ]
        },
        "options": {}
      },
      "credentials": {
        "notionApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "url": "=https://r.jina.ai/{{ $('Unwrap Body').first().json.url }}",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "response": {
            "response": {
              "responseFormat": "text"
            }
          },
          "timeout": 60000
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        740,
        540
      ],
      "id": "aaaaaaaa-0000-4000-8000-000000000009",
      "name": "Scrape via Jina Reader",
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "alwaysOutputData": true,
      "onError": "continueRegularOutput",
      "notesInFlow": true,
      "notes": "Default scraper. Free/cheap, returns markdown as text in $json.data."
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "jg1",
              "leftValue": "={{ typeof $json.data === \"string\" && $json.data.length > 200 && !$json.data.includes(\"Warning: Target URL returned error\") }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        940,
        540
      ],
      "id": "aaaaaaaa-0000-4000-8000-000000000010",
      "name": "Jina Returned Content?"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.firecrawl.dev/v2/scrape",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "contentType": "json",
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ url: $('Unwrap Body').first().json.url, formats: [\"markdown\"], onlyMainContent: true }) }}",
        "options": {
          "timeout": 120000
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        1140,
        680
      ],
      "id": "aaaaaaaa-0000-4000-8000-000000000011",
      "name": "Scrape via Firecrawl",
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "alwaysOutputData": true,
      "onError": "continueRegularOutput",
      "notesInFlow": true,
      "notes": "Fallback for JS-rendered / anti-bot pages. Returns $json.data.markdown."
    }
  ],
  "connections": {
    "Web Capture Webhook": {
      "main": [
        [
          {
            "node": "Unwrap Body",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Unwrap Body": {
      "main": [
        [
          {
            "node": "Has Content?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has Content?": {
      "main": [
        [
          {
            "node": "Pass Through Content",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Scrape via Jina Reader",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Pass Through Content": {
      "main": [
        [
          {
            "node": "Merge Branches",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Branches": {
      "main": [
        [
          {
            "node": "Normalize for Notion",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Scraped Fields": {
      "main": [
        [
          {
            "node": "Merge Branches",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Normalize for Notion": {
      "main": [
        [
          {
            "node": "Save to Notion",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Scrape via Jina Reader": {
      "main": [
        [
          {
            "node": "Jina Returned Content?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Jina Returned Content?": {
      "main": [
        [
          {
            "node": "Merge Scraped Fields",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Scrape via Firecrawl",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Scrape via Firecrawl": {
      "main": [
        [
          {
            "node": "Merge Scraped Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "callerPolicy": "workflowsFromSameOwner"
  }
}

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.

Pro

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

About this workflow

Content Pipeline: Web Capture Webhook. Uses notion, httpRequest. Webhook trigger; 11 nodes.

Source: https://github.com/alectivism/n8n-workflows/blob/main/web-capture-webhook/workflow.json — original creator credit. Request a take-down →

More Data & Sheets workflows → · Browse all categories →

Related workflows

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

Data & Sheets

Retrieves workflows directly from an n8n instance using the n8n API Dynamically generates a form to select which workflows to import Supports both fixed instance configuration and dynamic source/targe

Form Trigger, Form, Notion +2
Data & Sheets

Wait Splitout. Uses executeWorkflowTrigger, notion, stickyNote, splitOut. Event-driven trigger; 37 nodes.

Execute Workflow Trigger, Notion, HTTP Request
Data & Sheets

address validation. Uses httpRequest, splitOut, stickyNote. Webhook trigger; 31 nodes.

HTTP Request
Data & Sheets

Track Working Time and Pauses. Uses notion, stickyNote, respondToWebhook. Webhook trigger; 30 nodes.

Notion
Data & Sheets

Get all scaleway server info copy. Uses respondToWebhook, stickyNote, httpRequest, splitInBatches. Webhook trigger; 24 nodes.

HTTP Request