# templates

name: Learn JSON Basics with an Interactive Step-by-Step Tutorial for Beginners
author_name: Lucas Peyrin
author_username: lucaspeyrin
nodes_used: []
categories: []
created_at: 2025-06-23T22:42:11.749Z
updated_at: 2025-06-23T22:42:11.749Z
url: https://n8n.io/workflows/5170
scraped_at: 2025-07-06 21:16:30
description:
  How it works

  This workflow is an interactive, hands-on tutorial designed to teach you the absolute basics of JSON (JavaScript Object Notation) and, more importantly, how to use it within n8n. It's perfect for beginners who are new to automation and data structures.

  The tutorial is structured as a series of simple steps. Each node introduces a new, fundamental concept of JSON:

  Key/Value Pairs: The basic building block of all JSON.
  Data Types: It then walks you through the most common data types one by one:
      String (text)
      Number (integers and decimals)
      Boolean (true or false)
      Null (representing "nothing")
      Array (an ordered list of items)
      Object (a collection of key/value pairs)
  Using JSON with Expressions: The most important step! It shows you how to dynamically pull data from a previous node into a new one using n8n's expressions ({{ }}).
  Final Exam: A final node puts everything together, building a complete JSON object by referencing data from all the previous steps.

  Each node has a detailed sticky note explaining the concept in simple terms.

  Set up steps

  Setup time: 0 minutes!

  This is a tutorial workflow, so there is no setup required.

  Simply click the "Execute Workflow" button to run it.
  Follow the instructions in the main sticky note: click on each node in order, from top to bottom.
  For each node, observe the output in the right-hand panel and read the sticky note next to it to understand what you're seeing.

  By the end, you'll have a solid understanding of what JSON is and how to work with it in your own n8n workflows.

workflow_json:
  {"meta":{"instanceId":"e409ea34548a2afe2dffba31130cd1cf2e98ebe2afaeed2a63caf2a0582d1da0"},"nodes":[{"id":"8edca697-2dc4-490e-9850-60a96284c299","name":"Execute to Start","type":"n8n-nodes-base.manualTrigger","position":[-2000,100],"parameters":{},"typeVersion":1},{"id":"cb671298-90c8-4c39-a91c-d993c8ecf1b2","name":"String","type":"n8n-nodes-base.set","position":[-1380,100],"parameters":{"options":{},"assignments":{"assignments":[{"id":"e87952cb-878e-4feb-8261-342eaf887838","name":"json_example_string","type":"string","value":"This is a simple string. In JSON, it's always enclosed in double quotes."}]}},"typeVersion":3.4},{"id":"a2331e78-a752-433f-a5e3-d95a373d202b","name":"Key & Value","type":"n8n-nodes-base.set","position":[-1660,100],"parameters":{"options":{},"assignments":{"assignments":[{"id":"e87952cb-878e-4feb-8261-342eaf887838","name":"key","type":"string","value":"value"},{"id":"b5f030f4-6650-4181-881f-de44790bb24b","name":"another_key","type":"string","value":"another_value"}]}},"typeVersion":3.4},{"id":"f6ffeffb-98c3-4278-8ec5-2aa39220924d","name":"Number","type":"n8n-nodes-base.set","position":[-1100,100],"parameters":{"options":{},"assignments":{"assignments":[{"id":"e87952cb-878e-4feb-8261-342eaf887838","name":"json_example_integer","type":"number","value":10},{"id":"12345","name":"json_example_float","type":"number","value":12.5}]}},"typeVersion":3.4},{"id":"410682bb-a744-4db6-b08b-a63f67741576","name":"Boolean","type":"n8n-nodes-base.set","position":[-820,100],"parameters":{"options":{},"assignments":{"assignments":[{"id":"e87952cb-878e-4feb-8261-342eaf887838","name":"json_example_boolean","type":"boolean","value":false}]}},"typeVersion":3.4},{"id":"5e2948b0-6d60-4f4a-a150-89d41e8c4ed7","name":"Array","type":"n8n-nodes-base.set","position":[-260,100],"parameters":{"options":{},"assignments":{"assignments":[{"id":"e87952cb-878e-4feb-8261-342eaf887838","name":"json_example_array","type":"array","value":"[\"first element\", 2, false, null]"}]}},"typeVersion":3.4},{"id":"8f7dc470-f140-4427-970d-738cef81b7fa","name":"Object","type":"n8n-nodes-base.set","position":[20,100],"parameters":{"options":{},"assignments":{"assignments":[{"id":"e87952cb-878e-4feb-8261-342eaf887838","name":"json_example_object","type":"object","value":"{\"key\":\"value\",\"array\":[1,2,3],\"boolean\":false,\"integer\":123,\"sub_object\":{\"sub_key\":\"Find me!\"}}"}]}},"typeVersion":3.4},{"id":"0622c22e-920c-4122-9143-15c310da3861","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-2220,-380],"parameters":{"width":460,"height":640,"content":"## Tutorial - WTF is JSON?\n\nWelcome! This workflow will teach you the basics of JSON, the language that apps and n8n nodes use to exchange information.\n\n**What is JSON?**\nImagine a contact card:\n- **Name:** John Doe\n- **Age:** 30\n- **Has Children:** Yes\n- **Phone Numbers:** [\"555-1234\", \"555-5678\"]\n\n\nJSON is just a way of writing this down so a computer can understand it perfectly.\n\n**How to use this tutorial:**\n1.  Click **\"Execute Workflow\"**.\n2.  Click on each node, one by one, in order.\n3.  Look at the node's output in the panel on the right and read the associated sticky note to understand what's happening."},"typeVersion":1},{"id":"9be83d5e-2a5f-4ae2-8480-520ba0f5fa6b","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-1740,-240],"parameters":{"color":7,"width":260,"height":500,"content":"#### The Heart of JSON: Key & Value\n\nEverything in JSON is built on this pair:\n- A **Key** (the name of the data, always in double quotes `\"`).\n- A **Value** (the data itself).\n\n\n`\"key\": \"value\"`\n\nIn this node's output, you see two key/value pairs. This is the basic building block for everything that follows."},"typeVersion":1},{"id":"a4855cf1-8d0d-4c2f-acaf-0f9127a58418","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-1460,-240],"parameters":{"color":7,"width":260,"height":500,"content":"#### Data Type: String\n\nA string is simply **text**.\n- **Syntax:** The text is always enclosed in double quotes `\" \"`.\n\n\nLook at the output: the value of `json_example_string` is the text we defined."},"typeVersion":1},{"id":"016132fc-2d78-4ef3-87ed-c4e91ccca2f4","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-1180,-240],"parameters":{"color":7,"width":260,"height":500,"content":"#### Data Type: Number\n\nThis is simply a number. It can be a whole number (integer) like 10, or a decimal (float) like 12.5.\n- **Syntax:** Just write the number directly, **WITHOUT quotes**.\n\n\n`\"age\": 30` (Correct)\n`\"age\": \"30\"` (Incorrect, this is a String!)\n\nThis distinction is crucial for doing math!"},"typeVersion":1},{"id":"b5122335-74de-4f59-b72d-898e9e0a0667","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-900,-240],"parameters":{"color":7,"width":260,"height":500,"content":"#### Data Type: Boolean\n\nThis is a value that can only be **TRUE** or **FALSE**.\n- **Syntax:** `true` or `false` (always lowercase and **WITHOUT quotes**).\n\n\nThink of it like a light switch: on (`true`) or off (`false`). It's very useful for conditions (If/Then logic)."},"typeVersion":1},{"id":"e697becb-8572-4ab5-b675-d7bb9015fc09","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-340,-240],"parameters":{"color":7,"width":260,"height":500,"content":"#### Data Type: Array\n\nAn array is an **ordered list** of items.\n- **Syntax:** Starts with `[` and ends with `]`. Items are separated by commas.\n\n\nAn array can hold anything: strings, numbers, booleans, and even other arrays or objects!"},"typeVersion":1},{"id":"7a5e09f8-3a36-43c3-8740-deb602c320ef","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-60,-240],"parameters":{"color":7,"width":280,"height":500,"content":"#### Data Type: Object (JSON Object)\n\nThis is the main concept! An object is a **collection of key/value pairs**.\n- **Syntax:** Starts with `{` and ends with `}`.\n\n\nThis is what allows us to structure complex data, like our contact card from the beginning. Notice how this object contains all the other data types we've seen!"},"typeVersion":1},{"id":"295696bd-cc6a-4812-aad3-9c0189166120","name":"Null","type":"n8n-nodes-base.set","position":[-540,100],"parameters":{"options":{},"assignments":{"assignments":[{"id":"e87952cb-878e-4feb-8261-342eaf887838","name":"json_example_null","type":"null","value":null}]}},"typeVersion":3.4},{"id":"9fd77ab6-99aa-4b1f-90df-ba2cfbd99410","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[-620,-240],"parameters":{"color":7,"width":260,"height":500,"content":"#### Data Type: Null\n\nThis special type means \"nothing,\" \"no value,\" or \"empty.\"\n- **Syntax:** `null` (lowercase and **WITHOUT quotes**).\n\n\nIt's different from `0` (which is a number) or `\"\"` (which is an empty string). `null` is the intentional absence of a value."},"typeVersion":1},{"id":"ffb386b3-73c9-48d5-8b85-31bcb20ad301","name":"Using JSON (Expressions)","type":"n8n-nodes-base.set","position":[360,100],"parameters":{"options":{},"assignments":{"assignments":[{"id":"e87952cb-878e-4feb-8261-342eaf887838","name":"message","type":"string","value":"=Hello, the number from the tutorial is: {{ $('Number').item.json.json_example_integer }}"},{"id":"61f385f4-b8e2-4c69-b873-9ffc3ab3fe94","name":"sub_key","type":"string","value":"={{ $json.json_example_object.sub_object.sub_key }}"},{"id":"bd752a0f-64bf-44b1-b39b-fca28e86aa5b","name":"array_second_item","type":"string","value":"={{ $json.json_example_object.array[1] }}"}]}},"typeVersion":3.4},{"id":"43dae41f-2bfc-4acb-a4b5-072d5bc1c20a","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[240,-240],"parameters":{"color":5,"width":340,"height":500,"content":"#### ⭐ THE KEY STEP: Using JSON in n8n!\n\nNow for the magic. How do you use data from a previous node? With **expressions** `{{ }}`.\n\nThis node creates a custom message. Look at the value of the `message` field:\n`Hello, the number from the tutorial is: {{ $('Number').item.json.json_example_integer }}`\n\nIt dynamically pulled the number `10` from the \"Number\" node! This is how you make your nodes talk to each other."},"typeVersion":1},{"id":"34aeec49-684c-4b49-9c64-9946d5554e4e","name":"Final Exam","type":"n8n-nodes-base.set","position":[720,100],"parameters":{"options":{},"assignments":{"assignments":[{"id":"e87952cb-878e-4feb-8261-342eaf887838","name":"summary_string","type":"string","value":"={{ $('String').item.json.json_example_string }}"},{"id":"12345","name":"summary_number","type":"number","value":"={{ $('Number').item.json.json_example_integer }}"},{"id":"67890","name":"summary_boolean","type":"boolean","value":"={{ $('Boolean').item.json.json_example_boolean }}"},{"id":"abcde","name":"summary_null","type":"null","value":"={{ $('Null').item.json.json_example_null }}"},{"id":"fghij","name":"summary_array","type":"array","value":"={{ $('Array').item.json.json_example_array }}"},{"id":"klmno","name":"summary_object","type":"object","value":"={{ $('Object').item.json.json_example_object }}"}]}},"typeVersion":3.4},{"id":"6f605bd8-20e4-4e0c-af7a-927e6e4ef854","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[600,-240],"parameters":{"color":6,"width":340,"height":500,"content":"#### 🎓 FINAL EXAM: Putting It All Together\n\nThis last node creates a final object by using expressions to pull data from **all the previous nodes**.\n\nClick on this node and look at the expressions in each field. It's a perfect summary of everything you've learned.\n\n**Congratulations! You now understand the basics of JSON and how to use it in n8n.**"},"typeVersion":1},{"id":"55f3d25b-46fc-4cfa-b50a-fd00160b99e1","name":"Sticky Note10","type":"n8n-nodes-base.stickyNote","position":[960,-540],"parameters":{"color":4,"width":540,"height":800,"content":"## Was this helpful? Let me know!\n\nI really hope this tutorial helped you understand JSON better. Your feedback is incredibly valuable and helps me create better resources for the n8n community.\n\n### **Share Your Thoughts & Ideas**\n\nWhether you have a suggestion, found a typo, or just want to say thanks, I'd love to hear from you!\nHere's a simple n8n form built for this purpose:\n\n#### ➡️ **[Click here to give feedback](https://api.ia2s.app/form/templates/feedback?template=JSON%20Tutorial)**\n\n### **Ready to Build Something Great?**\n\nIf you're looking to take your n8n skills or business automation to the next level, I can help.\n\n**🎓 n8n Coaching:** Want to become an n8n pro? I offer one-on-one coaching sessions to help you master workflows, tackle specific problems, and build with confidence.\n#### ➡️ **[Book a Coaching Session](https://api.ia2s.app/form/templates/coaching?template=JSON%20Tutorial)**\n\n**💼 n8n Consulting:** Have a complex project, an integration challenge, or need a custom workflow built for your business? Let's work together to create a powerful automation solution.\n#### ➡️ **[Inquire About Consulting Services](https://api.ia2s.app/form/templates/consulting?template=JSON%20Tutorial)**\n\n---\n\nHappy Automating!\nLucas Peyrin"},"typeVersion":1},{"id":"a51902b2-63f1-4e54-be03-a4e8a612d6d9","name":"Sticky Note11","type":"n8n-nodes-base.stickyNote","position":[-2220,-540],"parameters":{"color":2,"width":460,"height":140,"content":"## Video Tutorial\nhttps://youtu.be/PAmgrwYnzWs?si=yXG1oHIL3UiBcAPa"},"typeVersion":1}],"pinData":{},"connections":{"Null":{"main":[[{"node":"Array","type":"main","index":0}]]},"Array":{"main":[[{"node":"Object","type":"main","index":0}]]},"Number":{"main":[[{"node":"Boolean","type":"main","index":0}]]},"Object":{"main":[[{"node":"Using JSON (Expressions)","type":"main","index":0}]]},"String":{"main":[[{"node":"Number","type":"main","index":0}]]},"Boolean":{"main":[[{"node":"Null","type":"main","index":0}]]},"Key & Value":{"main":[[{"node":"String","type":"main","index":0}]]},"Execute to Start":{"main":[[{"node":"Key & Value","type":"main","index":0}]]},"Using JSON (Expressions)":{"main":[[{"node":"Final Exam","type":"main","index":0}]]}}}


name: Learn API Fundamentals with an Interactive Hands-On Tutorial Workflow
author_name: Lucas Peyrin
author_username: lucaspeyrin
nodes_used: ["n8n-nodes-base.httpRequest"]
categories: []
created_at: 2025-06-23T23:27:47.342Z
updated_at: 2025-06-23T23:27:47.342Z
url: https://n8n.io/workflows/5171
scraped_at: 2025-07-06 21:16:30
description:
  How it works

  This template is an interactive, hands-on tutorial designed to demystify what an API is and how it works, right inside your n8n canvas.

  It uses a simple restaurant analogy to explain the core concepts:
  You* are the "Client" (an *HTTP Request** node).
  The Kitchen is the "Server" (a Webhook node).
  The API is the Menu and the Waiter—the set of rules for how you can ask for things and get a response.

  The workflow is a series of self-contained lessons. Each lesson pairs an HTTP Request node (the customer placing an order) with a Webhook node (the kitchen receiving and responding to the order) to demonstrate a key concept:

  The Basics: Making a simple GET request to a URL.
  Customizing: Using Query Parameters to filter or modify your request.
  Sending Data: Using the POST method and a Body to send information to the server.
  Identification: Using Headers and simple Authentication to prove who you are.
  Handling Delays: Understanding how Timeouts prevent your workflow from getting stuck.

  Set up steps

  Setup time: &lt; 1 minute

  This workflow is a self-contained tutorial and requires no external services or credentials. You may want to check the Base URL.

  Click "Execute Workflow" to run the entire tutorial.
  Follow the flow from top to bottom, exploring each "Lesson".
  For each lesson, click on the HTTP Request node and its corresponding Webhook node to see how they are configured and what they do.
  Read the sticky notes next to each lesson—they contain the core explanations!

  That's it! Explore and have fun learning the fundamentals of APIs in an interactive way.

workflow_json:
  {"meta":{"instanceId":"e409ea34548a2afe2dffba31130cd1cf2e98ebe2afaeed2a63caf2a0582d1da0"},"nodes":[{"id":"500527a4-9764-4e12-92f5-cac0dcc6d10b","name":"Start Tutorial","type":"n8n-nodes-base.manualTrigger","position":[-900,360],"parameters":{},"typeVersion":1},{"id":"41f0f626-eb75-40c9-ae3c-2ad247731885","name":"1. The Kitchen (GET /menu)","type":"n8n-nodes-base.webhook","position":[120,360],"webhookId":"a1b2c3d4-e5f6-7890-1234-567890abcdef","parameters":{"path":"/tutorial/api/menu","options":{},"responseMode":"lastNode"},"typeVersion":2},{"id":"5d0c582c-9de2-4bbd-b514-cf8833c0078a","name":"Respond with Menu","type":"n8n-nodes-base.set","position":[340,360],"parameters":{"options":{},"assignments":{"assignments":[{"id":"12345","name":"item","type":"string","value":"Pizza"},{"id":"67890","name":"price","type":"number","value":12}]}},"typeVersion":3.4},{"id":"6b72ccb7-2a86-4853-b5c5-2e05063231a2","name":"1. The Customer (GET Menu Item)","type":"n8n-nodes-base.httpRequest","position":[-180,360],"parameters":{"url":"={{ $('Base URL').last().json.your_n8n_base_url }}/menu","options":{}},"typeVersion":4.1},{"id":"61453ac8-362c-4bf9-8c7f-3546a8f51bf6","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1180,-20],"parameters":{"width":880,"height":560,"content":"### Tutorial - WTF is an API?\n\nWelcome! This workflow will teach you the basics of APIs (Application Programming Interfaces).\n\n**What is an API?**\nThink of it like ordering food at a restaurant.\n- **You** are the \"Client\" (the **HTTP Request** node). You want something.\n- The **Kitchen** is the \"Server\" (the **Webhook** node). It has the data/service you want.\n- The **API** is the **Waiter and the Menu**. It's the set of rules and options you have for making a request and getting a response.\n\n\n**How to use this tutorial:**\n1.  Click **\"Execute Workflow\"**. The workflow will run from top to bottom.\n2.  Explore each \"Lesson\" by clicking on the **HTTP Request** node (the Customer) and its corresponding **Webhook** node (the Kitchen).\n3.  Read the sticky note for each lesson to understand the concept being demonstrated."},"typeVersion":1},{"id":"963b1dce-eb8b-460a-a332-85e690f9ebd1","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-260,60],"parameters":{"color":7,"width":880,"height":480,"content":"#### Lesson 1: The Basics (Method & URL)\n\nThis is the simplest possible request.\n\n- **URL (Uniform Resource Locator):** This is the **address of the restaurant's kitchen**. The HTTP Request node needs to know exactly where to send the order. We use a special n8n expression to get the Webhook's test address automatically.\n\n- **Method: `GET`**: This is **what you want to do**. `GET` means you simply want to **retrieve** or **get** information. It's like asking the waiter, \"What's on the menu today?\"\n\n\n**➡️ Look at the output of the HTTP Request node. It received exactly what the Webhook is configured to listen to!**"},"typeVersion":1},{"id":"067de22c-8dde-45b0-b12c-2581fe5ee82c","name":"2. The Customer (GET with Query Params)","type":"n8n-nodes-base.httpRequest","position":[-180,940],"parameters":{"url":"={{ $('Base URL').last().json.your_n8n_base_url }}/order","options":{},"sendQuery":true,"queryParameters":{"parameters":[{"name":"extra_cheese","value":"true"}]}},"typeVersion":4.1},{"id":"dfc50d7c-f4b4-41e6-9fde-1afd45bd740d","name":"2. The Kitchen (GET /order)","type":"n8n-nodes-base.webhook","position":[120,940],"webhookId":"b2c3d4e5-f6a7-8901-2345-67890abcdef1","parameters":{"path":"/tutorial/api/order","options":{},"responseMode":"lastNode"},"typeVersion":2},{"id":"4d2ec461-1ce8-4bb2-a816-5b5032c6376a","name":"Respond with Cheese","type":"n8n-nodes-base.set","position":[560,840],"parameters":{"options":{},"assignments":{"assignments":[{"id":"12345","name":"order","type":"string","value":"Pizza with extra cheese"}]}},"typeVersion":3.4},{"id":"f06d2605-3114-42a2-9678-d1c6fcc78e62","name":"Respond with Plain","type":"n8n-nodes-base.set","position":[560,1040],"parameters":{"options":{},"assignments":{"assignments":[{"id":"12345","name":"order","type":"string","value":"Plain Pizza"}]}},"typeVersion":3.4},{"id":"f0796062-a671-473e-8fa8-becf4df1ce1d","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-260,580],"parameters":{"color":7,"width":1120,"height":640,"content":"#### Lesson 2: Customizing a Request (Query Parameters)\n\nWhat if you want to customize your order? That's what Query Parameters are for.\n\n**Query Parameters:** These are simple options added to the end of the URL after a `?`. They are key-value pairs used to filter, sort, or specify what you want.\n\nIt's like telling the waiter, \"I'll have the pizza... **and can you add extra cheese?**\"\n\n`?extra_cheese=true` is the query parameter.\n\n**➡️ The Webhook node uses an IF node to check for this parameter and changes its response accordingly.\nTry setting the value to `false` in the HTTP Request node and run it again!**"},"typeVersion":1},{"id":"e789ea65-f365-4657-af7c-3cb48d5f2c52","name":"3. The Customer (POST with Body)","type":"n8n-nodes-base.httpRequest","position":[-180,1540],"parameters":{"url":"={{ $('Base URL').last().json.your_n8n_base_url }}/review","method":"POST","options":{},"sendBody":true,"bodyParameters":{"parameters":[{"name":"comment","value":"I'm so happy !!"}]}},"typeVersion":4.1},{"id":"66688c28-04cd-4c2e-8533-82aa2450becf","name":"3. The Kitchen (POST /review)","type":"n8n-nodes-base.webhook","position":[120,1540],"webhookId":"c3d4e5f6-a7b8-9012-3456-7890abcdef12","parameters":{"path":"/tutorial/api/review","options":{},"httpMethod":"POST","responseMode":"lastNode"},"typeVersion":2},{"id":"7f894c9c-d2b0-42dd-bc23-4f9475e0e5df","name":"Respond to Review","type":"n8n-nodes-base.set","position":[340,1540],"parameters":{"options":{},"assignments":{"assignments":[{"id":"12345","name":"status","type":"string","value":"review_received"},{"id":"67890","name":"your_comment","type":"string","value":"={{ $json.body.comment }}"}]}},"typeVersion":3.4},{"id":"d899505f-127b-4b21-9616-de10fe08b3e9","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-260,1260],"parameters":{"color":7,"width":880,"height":460,"content":"#### Lesson 3: Sending Data (POST & Body)\n\nSometimes, you don't want to *get* data, you want to *send* it.\n\n- **Method: `POST`**: This method is used to **send new data** to the server. It's like handing the waiter a completed customer feedback card.\n\n- **Body:** This is the **actual data you are sending**. Since you're sending more complex information than a simple query parameter, it goes in a separate \"package\" called the body.\n\n\n**➡️ The HTTP Request sends a JSON object in its body. The Webhook receives it and includes your comment in its response.**"},"typeVersion":1},{"id":"8b797af9-1ef7-4171-b1ef-f1d2bd19daf8","name":"4. The Customer (GET with Headers/Auth)","type":"n8n-nodes-base.httpRequest","position":[-180,2100],"parameters":{"url":"={{ $('Base URL').last().json.your_n8n_base_url }}/secret-dish","options":{},"sendHeaders":true,"headerParameters":{"parameters":[{"name":"x-api-key","value":"your-api-key-for-example"}]}},"typeVersion":4.1},{"id":"3d51cbcb-1bc4-4fb7-9356-1c4a92744026","name":"4. The Kitchen (GET /secret-dish)","type":"n8n-nodes-base.webhook","position":[120,2100],"webhookId":"d4e5f6a7-b8c9-0123-4567-890abcdef123","parameters":{"path":"/tutorial/api/secret-dish","options":{},"responseMode":"lastNode"},"typeVersion":2},{"id":"b54cfc3b-d778-473e-98f0-e44625112c52","name":"Respond with Secret","type":"n8n-nodes-base.set","position":[560,2000],"parameters":{"options":{},"assignments":{"assignments":[{"id":"12345","name":"dish","type":"string","value":"The Chef's Special Truffle Pasta"}]}},"typeVersion":3.4},{"id":"aa2fffb1-e28c-4b91-8b17-6784d0aaafb5","name":"Respond with Error","type":"n8n-nodes-base.set","position":[560,2200],"parameters":{"options":{},"assignments":{"assignments":[{"id":"12345","name":"error","type":"string","value":"You are not authorized"}]}},"typeVersion":3.4},{"id":"a8233025-dcc9-49e9-8e9c-3aeb993cd81d","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-260,1760],"parameters":{"color":7,"width":1120,"height":620,"content":"#### Lesson 4: Identification (Headers & Auth)\n\nHeaders contain meta-information *about* your request. They're not part of the data itself, but they provide important context. Authentication is a common use case.\n\n- **Headers:** Think of this as **showing your VIP membership card** or whispering a secret password to the waiter. It's information that proves who you are or what your request's properties are.\n\n- **Authentication (Auth):** This is the process of proving your identity. Here, we use a custom header (`x-auth-token`) as a \"secret key\".\n\n\n**➡️ The Webhook checks for the correct secret key in the headers. If it's wrong or missing, it denies the request!**"},"typeVersion":1},{"id":"f4329ae3-5b44-4d04-a18a-e5ad9475cdbe","name":"5. The Customer (Request with Timeout)","type":"n8n-nodes-base.httpRequest","onError":"continueRegularOutput","position":[-180,2740],"parameters":{"url":"={{ $('Base URL').last().json.your_n8n_base_url }}/slow-service","options":{"timeout":2000}},"typeVersion":4.1},{"id":"70657e1b-f8a8-443a-9d01-98d0dc073d96","name":"5. The Kitchen (GET /slow-service)","type":"n8n-nodes-base.webhook","position":[120,2740],"webhookId":"e5f6a7b8-c9d0-1234-5678-90abcdef1234","parameters":{"path":"/tutorial/api/slow-service","options":{},"responseMode":"lastNode"},"typeVersion":2},{"id":"ecb8a39c-88a0-4b6a-9f8b-5ac5e63cce3c","name":"Respond Slowly","type":"n8n-nodes-base.set","position":[560,2740],"parameters":{"options":{},"assignments":{"assignments":[{"id":"12345","name":"status","type":"string","value":"Finally, your food is here!"}]}},"typeVersion":3.4},{"id":"087db781-41f5-4de2-b4a3-e9f53ffb7ab5","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-260,2420],"parameters":{"color":7,"width":1120,"height":500,"content":"#### Lesson 5: Being Patient (Timeout)\n\nAn API request isn't instant. What if the kitchen is really busy?\n\n- **Timeout:** This is the **maximum amount of time (in milliseconds) you are willing to wait** for a response before you give up and walk away.\n\n\nIn this example:\n- The **Kitchen (Webhook)** has a 3-second delay.\n- The **Customer (HTTP Request)** is only willing to wait for 2 seconds (2000 ms).\n\n**➡️ This request is designed to FAIL! The customer gives up before the kitchen can finish the order. This is crucial for preventing your workflows from getting stuck forever waiting for a slow service.**"},"typeVersion":1},{"id":"10fa759b-3729-41d8-88c4-b06852261f12","name":"Wait 3 seconds","type":"n8n-nodes-base.wait","position":[340,2740],"webhookId":"9a79d11e-fb6d-4bc1-89a3-0276182bd9f9","parameters":{"amount":3},"typeVersion":1.1},{"id":"c0baeacb-f28f-47d6-be03-0886a4ef9d37","name":"Base URL","type":"n8n-nodes-base.set","position":[-680,360],"parameters":{"options":{},"assignments":{"assignments":[{"id":"7edededc-2f40-4b8e-b8db-ab4816f1a28e","name":"your_n8n_base_url","type":"string","value":"={{ $env.WEBHOOK_URL + ($env.N8N_ENDPOINT_WEBHOOK ?? \"webhook\") }}/tutorial/api"}]}},"typeVersion":3.4},{"id":"bd3288ba-e7cf-43b1-b918-ac37bd437788","name":"IF Authorized","type":"n8n-nodes-base.if","position":[340,2100],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"ca861c2d-78d9-403b-8bab-28d8e7dcf39c","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.headers['x-api-key'] }}","rightValue":"your-api-key-for-example"}]}},"typeVersion":2.2},{"id":"c0bbea62-d40a-4966-bf0a-c30970192686","name":"IF extra cheese","type":"n8n-nodes-base.if","position":[340,940],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"loose"},"combinator":"and","conditions":[{"id":"ca861c2d-78d9-403b-8bab-28d8e7dcf39c","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ $json.query.extra_cheese }}","rightValue":"your-api-key-for-example"}]},"looseTypeValidation":true},"typeVersion":2.2},{"id":"6703362c-a47a-4c4d-ba0e-7b9464376134","name":"Sticky Note12","type":"n8n-nodes-base.stickyNote","position":[900,2120],"parameters":{"color":4,"width":540,"height":800,"content":"## Was this helpful? Let me know!\n\nI really hope this tutorial helped you understand APIs better. Your feedback is incredibly valuable and helps me create better resources for the n8n community.\n\n### **Share Your Thoughts & Ideas**\n\nWhether you have a suggestion, found a typo, or just want to say thanks, I'd love to hear from you!\nHere's a simple n8n form built for this purpose:\n\n#### ➡️ **[Click here to give feedback](https://api.ia2s.app/form/templates/feedback?template=API%20Tutorial)**\n\n### **Ready to Build Something Great?**\n\nIf you're looking to take your n8n skills or business automation to the next level, I can help.\n\n**🎓 n8n Coaching:** Want to become an n8n pro? I offer one-on-one coaching sessions to help you master workflows, tackle specific problems, and build with confidence.\n#### ➡️ **[Book a Coaching Session](https://api.ia2s.app/form/templates/coaching?template=API%20Tutorial)**\n\n**💼 n8n Consulting:** Have a complex project, an integration challenge, or need a custom workflow built for your business? Let's work together to create a powerful automation solution.\n#### ➡️ **[Inquire About Consulting Services](https://api.ia2s.app/form/templates/consulting?template=API%20Tutorial)**\n\n---\n\nHappy Automating!\nLucas Peyrin"},"typeVersion":1}],"pinData":{"4. The Kitchen (GET /secret-dish)":[{"body":{},"query":{},"params":{},"headers":{"via":"1.1 Caddy","host":"api.ia2s.app","accept":"application/json,text/html,application/xhtml+xml,application/xml,text/*;q=0.9, image/*;q=0.8, */*;q=0.7","api-key":"your-api-key-for-example","user-agent":"axios/1.8.3","accept-encoding":"gzip, compress, deflate, br","x-forwarded-for":"192.168.80.1","x-forwarded-host":"api.ia2s.app","x-forwarded-proto":"https"},"webhookUrl":"https://api.ia2s.app/webhook/tutorial/api/secret-dish","executionMode":"production"}]},"connections":{"Base URL":{"main":[[{"node":"1. The Customer (GET Menu Item)","type":"main","index":0},{"node":"2. The Customer (GET with Query Params)","type":"main","index":0},{"node":"3. The Customer (POST with Body)","type":"main","index":0},{"node":"4. The Customer (GET with Headers/Auth)","type":"main","index":0},{"node":"5. The Customer (Request with Timeout)","type":"main","index":0}]]},"IF Authorized":{"main":[[{"node":"Respond with Secret","type":"main","index":0}],[{"node":"Respond with Error","type":"main","index":0}]]},"Start Tutorial":{"main":[[{"node":"Base URL","type":"main","index":0}]]},"Wait 3 seconds":{"main":[[{"node":"Respond Slowly","type":"main","index":0}]]},"IF extra cheese":{"main":[[{"node":"Respond with Cheese","type":"main","index":0}],[{"node":"Respond with Plain","type":"main","index":0}]]},"1. The Kitchen (GET /menu)":{"main":[[{"node":"Respond with Menu","type":"main","index":0}]]},"2. The Kitchen (GET /order)":{"main":[[{"node":"IF extra cheese","type":"main","index":0}]]},"3. The Kitchen (POST /review)":{"main":[[{"node":"Respond to Review","type":"main","index":0}]]},"1. The Customer (GET Menu Item)":{"main":[[]]},"3. The Customer (POST with Body)":{"main":[[]]},"4. The Kitchen (GET /secret-dish)":{"main":[[{"node":"IF Authorized","type":"main","index":0}]]},"5. The Kitchen (GET /slow-service)":{"main":[[{"node":"Wait 3 seconds","type":"main","index":0}]]},"2. The Customer (GET with Query Params)":{"main":[[]]},"4. The Customer (GET with Headers/Auth)":{"main":[[]]}}}


name: Serve Custom Websites (HTML Webpages) with Webhooks
author_name: Lucas Peyrin
author_username: lucaspeyrin
nodes_used: []
categories: []
created_at: 2025-06-23T23:51:48.249Z
updated_at: 2025-06-23T23:51:48.249Z
url: https://n8n.io/workflows/5173
scraped_at: 2025-07-06 21:16:30
description:
  How it works

  This workflow demonstrates how to use n8n to serve a complete, styled HTML webpage. It acts as a mini web server, responding to browser requests with your custom HTML content.

  Webhook Trigger: The workflow starts with a Webhook node configured to listen for GET requests on a specific path. When you visit this node's Production URL in a browser, it triggers the workflow.
  Respond with HTML: The Respond to Webhook node is configured to send a response back to the browser.
      Content-Type Header: It sets a crucial response header, Content-Type: text/html, which tells the browser to render the response as a webpage, not just plain text.
      HTML Body: The entire HTML, CSS, and JavaScript for the webpage is pasted directly into the Body field of this node.

  When activated, visiting the webhook URL will instantly display the custom webpage.

  Set up steps

  Setup time: &lt; 1 minute

  This workflow is ready to use out-of-the-box.

  Activate the workflow.
  Open the Your WebPage (Webhook) node and copy its Production URL.
  Paste the URL into your browser to see the live tutorial page.
  To use your own HTML, simply open the Site (Respond to Webhook) node and replace the content in the Body field with your own code.

workflow_json:
  {"meta":{"instanceId":"e409ea34548a2afe2dffba31130cd1cf2e98ebe2afaeed2a63caf2a0582d1da0"},"nodes":[{"id":"2b9d377c-853f-4ef1-92e2-1d4a324179a4","name":"Site","type":"n8n-nodes-base.respondToWebhook","position":[100,-40],"parameters":{"options":{"responseHeaders":{"entries":[{"name":"Content-Type","value":"text/html; charset=UTF-8"}]}},"respondWith":"text","responseBody":"=<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>n8n Workflow: Serving a Static HTML Page</title>\n    <style>\n        :root {\n            --n8n-bg: #131416;\n            --n8n-surface: #1b1c20;\n            --n8n-border: #2a2c31;\n            --n8n-text: #e1e1e1;\n            --n8n-text-muted: #9a9a9a;\n            --n8n-green: #37e2a3;\n            --n8n-purple: #a45fff;\n            --n8n-font: 'Inter', -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n        }\n\n        body {\n            font-family: var(--n8n-font);\n            background-color: var(--n8n-bg);\n            color: var(--n8n-text);\n            margin: 0;\n            padding: 2rem;\n            line-height: 1.6;\n        }\n\n        .container {\n            max-width: 900px;\n            margin: 0 auto;\n        }\n\n        .header {\n            text-align: center;\n            margin-bottom: 3rem;\n        }\n\n        .header h1 {\n            font-size: 2.8rem;\n            font-weight: 700;\n            background: -webkit-linear-gradient(45deg, var(--n8n-green), var(--n8n-purple));\n            -webkit-background-clip: text;\n            -webkit-text-fill-color: transparent;\n            margin-bottom: 0.5rem;\n        }\n\n        .header p {\n            font-size: 1.2rem;\n            color: var(--n8n-text-muted);\n            max-width: 650px;\n            margin: 0 auto;\n        }\n\n        .step {\n            background-color: var(--n8n-surface);\n            border: 1px solid var(--n8n-border);\n            border-radius: 12px;\n            padding: 2rem;\n            margin-bottom: 2rem;\n            display: flex;\n            gap: 2rem;\n            align-items: flex-start;\n        }\n\n        .step-number {\n            flex-shrink: 0;\n            width: 50px;\n            height: 50px;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            border-radius: 50%;\n            background-color: var(--n8n-border);\n            font-size: 1.5rem;\n            font-weight: 600;\n            color: var(--n8n-green);\n        }\n\n        .step-content h2 {\n            margin-top: 0;\n            font-size: 1.5rem;\n            color: var(--n8n-text);\n        }\n\n        .step-content p, .step-content ul {\n            color: var(--n8n-text-muted);\n        }\n        \n        .step-content ul {\n            padding-left: 20px;\n        }\n        \n        .step-content li {\n            margin-bottom: 0.5rem;\n        }\n\n        code {\n            font-family: 'Fira Code', 'Courier New', monospace;\n            background-color: var(--n8n-bg);\n            color: var(--n8n-green);\n            padding: 0.2em 0.4em;\n            border-radius: 4px;\n            font-size: 0.9em;\n        }\n\n        .code-block {\n            background-color: var(--n8n-bg);\n            border: 1px solid var(--n8n-border);\n            border-radius: 8px;\n            padding: 1.5rem;\n            margin-top: 1rem;\n            overflow-x: auto;\n        }\n\n        .code-block pre {\n            margin: 0;\n        }\n        \n        .code-block code {\n            padding: 0;\n            background: none;\n            color: var(--n8n-text-muted);\n        }\n        \n        .code-block .comment {\n            color: #6a6a6a;\n        }\n\n        .final-note {\n            text-align: center;\n            padding: 2rem;\n            background-color: var(--n8n-surface);\n            border: 1px solid var(--n8n-border);\n            border-radius: 12px;\n        }\n        \n        .final-note h2 {\n            color: var(--n8n-green);\n        }\n\n        a {\n            color: var(--n8n-green);\n            text-decoration: none;\n            font-weight: 500;\n        }\n\n        a:hover {\n            text-decoration: underline;\n        }\n\n        @media (max-width: 768px) {\n            body { padding: 1rem; }\n            .header h1 { font-size: 2.2rem; }\n            .step { flex-direction: column; }\n            .step-number { margin-bottom: 1rem; }\n        }\n    </style>\n    <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n    <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n    <link href=\"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Fira+Code&display=swap\" rel=\"stylesheet\">\n</head>\n<body>\n\n    <div class=\"container\">\n\n        <header class=\"header\">\n            <h1>Serve a Full Webpage with n8n</h1>\n            <p>Learn how to use a simple n8n workflow to act as a web server, returning a complete HTML page to anyone who visits your webhook URL.</p>\n        </header>\n\n        <div class=\"step\">\n            <div class=\"step-number\">1</div>\n            <div class=\"step-content\">\n                <h2>The Trigger: Webhook Node</h2>\n                <p>Every workflow that responds to a web request starts with the <strong>Webhook</strong> node. This is your entry point.</p>\n                <ul>\n                    <li>Add a new Webhook node to an empty canvas.</li>\n                    <li>Set the <strong>HTTP Method</strong> to <code>GET</code>. This means it will respond when someone visits the URL in their browser.</li>\n                    <li>Copy the <strong>Production URL</strong>. You'll use this to see your workflow in action. Once you activate the workflow, you'll be able to see your webpage in the browser.</li>\n                </ul>\n            </div>\n        </div>\n\n        <div class=\"step\">\n            <div class=\"step-number\">2</div>\n            <div class=\"step-content\">\n                <h2>The Response: Respond to Webhook Node</h2>\n                <p>This is where the magic happens. This node sends your data back to the browser that triggered the webhook.</p>\n                <p>Connect a <strong>Respond to Webhook</strong> node to your Webhook node. To make it serve a webpage, you need to configure two things:</p>\n                \n                <p><strong>1. Set the Content-Type Header:</strong></p>\n                <p>You must tell the browser it's receiving an HTML document. Under <strong>Options</strong>, add a Response Header:</p>\n                <ul>\n                    <li><strong>Name:</strong> <code>Content-Type</code></li>\n                    <li><strong>Value:</strong> <code>text/html</code></li>\n                </ul>\n\n                <p><strong>2. Add your HTML to the Body:</strong></p>\n                <p>In the <strong>Body</strong> field of the node, paste your entire HTML code. The workflow will send this exact content as the response.</p>\n\n                <div class=\"code-block\">\n                    <pre><code><span class=\"comment\">&lt;!-- Paste your entire HTML file here --&gt;</span>\n&lt;!DOCTYPE html&gt;\n&lt;html lang=\"fr\"&gt;\n&lt;head&gt;\n    &lt;meta charset=\"UTF-8\"&gt;\n    &lt;title&gt;Your Very Own WebPage (AI can build it);/title&gt;\n    &lt;style&gt;\n        :root {\n            --bg-color: #2e2e30;\n            /* ... all your other CSS styles ... */\n        }\n        body {\n            font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto;\n            /* ... etc ... */\n        }\n    &lt;/style&gt;\n&lt;/head&gt;\n&lt;body&gt;\n    &lt;div class=\"container\"&gt;\n        &lt;h1&gt;🚀 Your Very Own WebPage (AI can build it)&lt;/h1&gt;\n        &lt;p&gt;You can put any html here !!&lt;/p&gt;\n        \n        &lt;!-- ... The rest of your HTML content ... --&gt;\n\n    &lt;/div&gt;\n&lt;/body&gt;\n&lt;/html&gt;\n</code></pre>\n                </div>\n            </div>\n        </div>\n\n        <div class=\"final-note\">\n            <h2>That's It!</h2>\n            <p>Activate your workflow. Now, when you visit your <strong>Production URL</strong>, n8n will serve your custom webpage. You've successfully turned a simple workflow into a mini web server.</p>\n            <p>This method is perfect for creating landing pages, dashboards, or dynamic pages where n8n fetches data before rendering the HTML.</p>\n        </div>\n\n    </div>\n\n</body>\n</html>"},"typeVersion":1.1},{"id":"ec1325bb-c440-46f2-90e5-3288a0683dda","name":"Your WebPage","type":"n8n-nodes-base.webhook","position":[-280,-40],"webhookId":"99651075-3d83-4d67-963f-06c7a5e6a3d3","parameters":{"path":"tutorial/your-webpage","options":{},"responseMode":"responseNode"},"typeVersion":2},{"id":"37f044be-f4b8-4404-bd69-f4f2ce233774","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-400,-340],"parameters":{"color":6,"width":360,"height":460,"content":"### ▶️ START HERE: The Webhook\n\nThis node is the entry point for your webpage.\n\n1.  **Activate** the workflow.\n2.  Copy the **Production URL** from this node.\n3.  Paste the URL into your browser to see the result.\n\n\nThe `Path` is set to `tutorial/your-webpage`, but you can change it to whatever you like."},"typeVersion":1},{"id":"6ae79d50-faa3-42d0-ba1d-65de358f0748","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-20,-340],"parameters":{"color":7,"width":360,"height":460,"content":"#### 🎨 CUSTOMIZE YOUR WEBPAGE HERE\n\nThis node sends the HTML content back to the browser.\n\n**To use your own design:**\n1.  **Replace the HTML in the `Body` field** with your own code. You can put anything here: HTML, CSS, and even `<script>` tags.\n2.  Ensure the `Content-Type` header under **Options → Response Headers** is set to `text/html`. This is crucial for the browser to render the page correctly."},"typeVersion":1},{"id":"ba181803-be34-457e-939d-e84d258f2411","name":"Sticky Note12","type":"n8n-nodes-base.stickyNote","position":[400,-340],"parameters":{"color":4,"width":540,"height":800,"content":"## Was this helpful? Let me know!\n\nI really hope this tutorial helped you understand how to serve a website with a webhook better. Your feedback is incredibly valuable and helps me create better resources for the n8n community.\n\n### **Share Your Thoughts & Ideas**\n\nWhether you have a suggestion, found a typo, or just want to say thanks, I'd love to hear from you!\nHere's a simple n8n form built for this purpose:\n\n#### ➡️ **[Click here to give feedback](https://api.ia2s.app/form/templates/feedback?template=Webhook%20Website%20Tutorial)**\n\n### **Ready to Build Something Great?**\n\nIf you're looking to take your n8n skills or business automation to the next level, I can help.\n\n**🎓 n8n Coaching:** Want to become an n8n pro? I offer one-on-one coaching sessions to help you master workflows, tackle specific problems, and build with confidence.\n#### ➡️ **[Book a Coaching Session](https://api.ia2s.app/form/templates/coaching?template=Webhook%20Website%20Tutorial)**\n\n**💼 n8n Consulting:** Have a complex project, an integration challenge, or need a custom workflow built for your business? Let's work together to create a powerful automation solution.\n#### ➡️ **[Inquire About Consulting Services](https://api.ia2s.app/form/templates/consulting?template=Webhook%20Website%20Tutorial)**\n\n---\n\nHappy Automating!\nLucas Peyrin"},"typeVersion":1}],"pinData":{},"connections":{"Your WebPage":{"main":[[{"node":"Site","type":"main","index":0}]]}}}


name: Creating a Secure Webhook - MUST HAVE
author_name: Lucas Peyrin
author_username: lucaspeyrin
nodes_used: ["n8n-nodes-base.httpRequest"]
categories: []
created_at: 2025-06-24T00:39:28.426Z
updated_at: 2025-06-24T00:39:28.426Z
url: https://n8n.io/workflows/5174
scraped_at: 2025-07-06 21:16:30
description:
  How it works

  This workflow demonstrates a fundamental pattern for securing a webhook by requiring an API key. It acts as a gatekeeper, checking for a valid key in the request header before allowing the request to proceed.

  Incoming Request: The Secured Webhook node receives an incoming POST request. It expects an API key to be sent in the x-api-key header.
  API Key Verification:
      The Check API Key node takes the key from the incoming request's header.
      It then makes an internal HTTP request to a second webhook (Get API Key) which acts as a mock database.
      This second webhook retrieves a list of registered API keys (from the Registered API Keys node) and filters it to find a match for the key that was provided.
  Conditional Response:
      If a match is found, the API Key Identified node routes the execution to the "success" path, returning a 200 OK response with the identified user's ID.
      If no match is found, it routes to the "unauthorized" path, returning a 401 Unauthorized error.

  This pattern separates the public-facing endpoint from the data source, which is a good security practice.

  Set up steps

  Setup time: ~2 minutes

  This workflow is designed to be a self-contained example.

  Set up Credentials: This workflow uses "Header Auth" for its internal communication. Go to Credentials and create a new Header Auth credential. You can use any name and value (e.g., Name: X-N8N-Auth, Value: my-secret-password). Select this credential in all four webhook/HTTP Request nodes.
  Add Your API Keys: Open the Registered API Keys node. This is your mock database. Edit the array to include the user_id and api_key pairs you want to authorize.
  Activate the workflow.
  Test it: Use the Test Secure Webhook node to send a request.
      Try it with a valid key from your list to see the success response.
      Change the x-api-key header to an invalid key to see the 401 Unauthorized error.

  For Production: Replace the mock database part of this workflow (the Get API Key webhook and Registered API Keys node) with a real database node like Supabase, Postgres, or Baserow to look up keys.

workflow_json:
  {"meta":{"instanceId":"e409ea34548a2afe2dffba31130cd1cf2e98ebe2afaeed2a63caf2a0582d1da0"},"nodes":[{"id":"d776b55a-65fe-4e12-9071-58911fa9c5cc","name":"Registered API Keys","type":"n8n-nodes-base.set","position":[160,520],"parameters":{"options":{},"assignments":{"assignments":[{"id":"2ab01b9f-473f-4f1b-8ddf-8d5a7b706323","name":"registered_api_keys","type":"array","value":"[\n   {\n      \"user_id\":\"user_1\",\n      \"api_key\":\"test\"\n   },\n   {\n      \"user_id\":\"user_2\",\n      \"api_key\":\"sk-YOUR_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE\"\n   }\n]"}]}},"typeVersion":3.4},{"id":"d20bdc9b-3020-4fa3-88c3-b6c3d5a585b2","name":"API Key Identified","type":"n8n-nodes-base.if","position":[480,0],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"0e476976-504d-4d21-a5d1-849fe54d322f","operator":{"type":"string","operation":"exists","singleValue":true},"leftValue":"={{ $json.user_id }}","rightValue":"={{ $('Secured Webhook').item.json.headers['x-api-key'] }}"}]}},"typeVersion":2.2},{"id":"73ee78a3-9e0c-4f24-a05f-f860dc8fda88","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[120,-260],"parameters":{"color":3,"width":300,"height":420,"content":"### ⚙️ Key Verification Logic\n\nThis node takes the API key from the incoming request and asks our \"database\" (the second webhook) if it's valid.\n\n**In a real-world scenario, you would replace this and the nodes below with a single Database node (e.g., Supabase, Postgres) to perform the lookup.**"},"typeVersion":1},{"id":"b34ad49e-351a-4f42-8336-d4300d442c50","name":"Respond to Webhook (success)","type":"n8n-nodes-base.respondToWebhook","position":[700,-100],"parameters":{"options":{},"respondWith":"json","responseBody":"={\n  \"status\": \"success\",\n  \"user_id\": \"{{ $json.user_id }}\"\n}"},"typeVersion":1.4},{"id":"2da5855a-d54a-43f1-b4c5-3ff510a10bd3","name":"Respond to Webhook (unauthorized)","type":"n8n-nodes-base.respondToWebhook","position":[700,100],"parameters":{"options":{"responseCode":401},"respondWith":"json","responseBody":"{\n  \"error\": \"Please provide a valid x-api-key header.\"\n}"},"typeVersion":1.4},{"id":"0b56b704-4dd6-490a-9998-f8eb2ef0a00e","name":"Secured Webhook","type":"n8n-nodes-base.webhook","position":[-60,0],"webhookId":"bf0be3b1-f140-4bc5-9040-a0e71dd78661","parameters":{"path":"tutorial/secure-webhook","options":{},"httpMethod":"POST","responseMode":"responseNode","authentication":"headerAuth"},"credentials":{"httpHeaderAuth":{"id":"pDp6BhprTE7kfSQy","name":"n8n Templates"}},"typeVersion":2},{"id":"7308010d-5050-4e5e-8c8b-c57194b88516","name":"Check API Key","type":"n8n-nodes-base.httpRequest","onError":"continueRegularOutput","position":[220,0],"parameters":{"url":"={{ $env.WEBHOOK_URL + ($env.N8N_ENDPOINT_WEBHOOK ?? \"webhook\") }}/tutorial/secure-webhook/api-keys","options":{},"sendBody":true,"authentication":"genericCredentialType","bodyParameters":{"parameters":[{"name":"api_key","value":"={{ $json.headers['x-api-key'] }}"}]},"genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"pDp6BhprTE7kfSQy","name":"n8n Templates"}},"typeVersion":4.2,"alwaysOutputData":true},{"id":"88070916-27b2-42fb-8005-970b6d5a08fc","name":"Find API Key","type":"n8n-nodes-base.filter","position":[600,520],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"526ec1b1-4f6d-41ea-b35a-1347c01aa03a","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.api_key }}","rightValue":"={{ $('Get API Key').last().json.body.api_key }}"}]}},"typeVersion":2.2,"alwaysOutputData":true},{"id":"2a06aaa0-1ac3-4750-9770-6eec7e9310a9","name":"Get API Key","type":"n8n-nodes-base.webhook","position":[-60,520],"webhookId":"bf0be3b1-f140-4bc5-9040-a0e71dd78661","parameters":{"path":"tutorial/secure-webhook/api-keys","options":{},"responseMode":"lastNode","authentication":"headerAuth"},"credentials":{"httpHeaderAuth":{"id":"pDp6BhprTE7kfSQy","name":"n8n Templates"}},"typeVersion":2},{"id":"3803f9b8-deec-4262-a76b-bfd72d572493","name":"Split Out Users","type":"n8n-nodes-base.splitOut","position":[380,520],"parameters":{"options":{},"fieldToSplitOut":"registered_api_keys"},"typeVersion":1},{"id":"d81a0dd5-9c90-4fee-a7ec-46e9aabb53a3","name":"Test Secure Webhook","type":"n8n-nodes-base.httpRequest","position":[-420,0],"parameters":{"url":"={{ $env.WEBHOOK_URL + ($env.N8N_ENDPOINT_WEBHOOK ?? \"webhook\") }}/tutorial/secure-webhook","method":"POST","options":{},"sendHeaders":true,"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","headerParameters":{"parameters":[{"name":"x-api-key","value":"test"}]}},"credentials":{"httpHeaderAuth":{"id":"pDp6BhprTE7kfSQy","name":"n8n Templates"}},"typeVersion":4.2},{"id":"ca63d58d-4683-4dbc-bd1e-6fd2724152f7","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-500,-180],"parameters":{"color":6,"width":600,"height":340,"content":"### ▶️ Public Endpoint & Tester\n\n*   **`Secured Webhook`**: This is your public-facing endpoint. It listens for requests containing an `x-api-key` header.\n*   **`Test Secure Webhook`**: Use this node to test the endpoint. Change the `x-api-key` header value to test valid and invalid keys."},"typeVersion":1},{"id":"14afef1c-6a99-46f5-96e1-c536a9afde69","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-140,320],"parameters":{"color":7,"width":1020,"height":380,"content":"### 📦 Mock Database\n\nThese nodes simulate a database of users and their API keys.\n\n*   **`Get API Key`**: A private webhook that receives a key and checks it against the list.\n*   **`Registered API Keys`**: **EDIT THIS NODE** to add or remove the API keys you want to be considered valid. Each key should be unique to a user."},"typeVersion":1},{"id":"12074ea9-65a9-4696-8c87-c77842f44467","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[440,-300],"parameters":{"color":7,"width":440,"height":580,"content":"#### ✅ Gatekeeper\n\nThis IF node checks the result from our \"database\".\n\n*   If a user was found for the given API key, it proceeds to the **success** response.\n*   If not, it sends a **401 Unauthorized** error."},"typeVersion":1},{"id":"5a0e2e8a-74df-403d-94ef-d5b8b5a0bd13","name":"Sticky Note12","type":"n8n-nodes-base.stickyNote","position":[920,-100],"parameters":{"color":4,"width":540,"height":800,"content":"## Was this helpful? Let me know!\n\nI really hope this tutorial helped you understand how to build secured webhooks better. Your feedback is incredibly valuable and helps me create better resources for the n8n community.\n\n### **Share Your Thoughts & Ideas**\n\nWhether you have a suggestion, found a typo, or just want to say thanks, I'd love to hear from you!\nHere's a simple n8n form built for this purpose:\n\n#### ➡️ **[Click here to give feedback](https://api.ia2s.app/form/templates/feedback?template=Secure%20Webhook%20Tutorial)**\n\n### **Ready to Build Something Great?**\n\nIf you're looking to take your n8n skills or business automation to the next level, I can help.\n\n**🎓 n8n Coaching:** Want to become an n8n pro? I offer one-on-one coaching sessions to help you master workflows, tackle specific problems, and build with confidence.\n#### ➡️ **[Book a Coaching Session](https://api.ia2s.app/form/templates/coaching?template=Secure%20Webhook%20Tutorial)**\n\n**💼 n8n Consulting:** Have a complex project, an integration challenge, or need a custom workflow built for your business? Let's work together to create a powerful automation solution.\n#### ➡️ **[Inquire About Consulting Services](https://api.ia2s.app/form/templates/consulting?template=Secure%20Webhook%20Tutorial)**\n\n---\n\nHappy Automating!\nLucas Peyrin"},"typeVersion":1}],"pinData":{},"connections":{"Get API Key":{"main":[[{"node":"Registered API Keys","type":"main","index":0}]]},"Check API Key":{"main":[[{"node":"API Key Identified","type":"main","index":0}]]},"Secured Webhook":{"main":[[{"node":"Check API Key","type":"main","index":0}]]},"Split Out Users":{"main":[[{"node":"Find API Key","type":"main","index":0}]]},"API Key Identified":{"main":[[{"node":"Respond to Webhook (success)","type":"main","index":0}],[{"node":"Respond to Webhook (unauthorized)","type":"main","index":0}]]},"Registered API Keys":{"main":[[{"node":"Split Out Users","type":"main","index":0}]]}}}


name: OTX & OpenAI Web Security Check
author_name: Sean Birmingham
author_username: knute
categories: []
created_at: 2025-06-24T00:51:22.681Z
updated_at: 2025-06-24T00:51:22.681Z
url: https://n8n.io/workflows/5175
scraped_at: 2025-07-06 21:16:30
description:
  This n8n workflow automates website security audits. It combines direct website scanning, threat intelligence from AlienVault OTX, and advanced analysis from an OpenAI large language model (LLM) to generate and email a comprehensive security report.

  How it Works (Workflow Flow):

  Input: A user provides a website URL via a simple web form.
  Data Collection:
  An HTTP Request node visits the provided URL to gather initial data (status code, headers).
  An AlienVault HTTP Request node queries AlienVault OTX for known threats associated with the website's hostname.
  Data Preparation (Prepare Data for AI): A custom code node consolidates the collected website data and AlienVault intelligence, performing initial checks for common issues (e.g., error codes, missing security headers, AlienVault warnings).
  AI Analysis (Security Configuration Audit): The prepared data is sent to an OpenAI Chat Model, which acts as a cybersecurity expert. The AI analyzes the data to identify vulnerabilities, explain their impact, suggest exploitation methods, and outline mitigation steps.
  Report Formatting (Format Report for Email): Another custom code node takes the AI's plain-text report and converts it into a structured HTML format suitable for email.
  Delivery (Send Security Report): The final HTML report is sent via Gmail to a specified email address.

  Setup Steps:

  To use this workflow, you'll need an n8n instance and the following credentials:

  n8n Instance: Ensure your n8n environment is running.
  OpenAI API Key:
  Generate a key from OpenAI.
  Add an "OpenAI API" credential in n8n (e.g., "OpenAI account").
  AlienVault OTX API Key:
  Obtain a key from your AlienVault OTX profile.
  Add an "AlienVault OTX API" credential in n8n (e.g., "AlienVault account").
  Gmail Account:
  Set up a "Gmail OAuth2" credential in n8n for sending emails (recommended for security; involves Google Cloud setup).
  Import Workflow:
  Copy the workflow's JSON code.
  In n8n, import the workflow via "Workflows" &gt; "New" &gt; "Import from JSON".
  Configure Recipient:
  In the "Send Security Report" node, specify the email address where reports should be sent.
  Activate: Enable the workflow to start processing submissions.

  Once activated, access the "On form submission" webhook URL to input a URL and trigger an audit.

nodes_used:
  ["n8n-nodes-base.httpRequest","n8n-nodes-base.gmail","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatOpenAi"]

workflow_json:
  {"meta":{"instanceId":"","templateCredsSetupCompleted":true},"nodes":[{"id":"","name":"HTTP Request","type":"n8n-nodes-base.httpRequest","position":[-800,240],"parameters":{"url":"={{ $json['Landing Page'] }}","options":{"redirect":{"redirect":{}},"response":{"response":{"fullResponse":true,"responseFormat":"text"}}}},"typeVersion":4.2},{"id":"","name":"On form submission","type":"n8n-nodes-base.formTrigger","position":[-1020,240],"webhookId":"","parameters":{"options":{},"formTitle":"URL Test","formFields":{"values":[{"fieldLabel":"Landing Page","placeholder":"https://example.com","requiredField":true}]},"formDescription":"Enter URL for testing"},"typeVersion":2.2},{"id":"","name":"AlienVault HTTP Request","type":"n8n-nodes-base.httpRequest","position":[-580,240],"parameters":{"":"","url":"=https://otx.alienvault.com/api/v1/indicators/hostname/{{ $('On form submission').item.json['Landing Page'].replace(\"https://\", \"\").replace(\"http://\", \"\") }}/general","method":"POST","options":{},"sendBody":false,"sendQuery":false,"curlImport":"","infoMessage":"","sendHeaders":false,"authentication":"predefinedCredentialType","httpVariantWarning":"","nodeCredentialType":"alienVaultApi","provideSslCertificates":false},"credentials":{"alienVaultApi":{"id":"","name":"AlienVault account"}},"typeVersion":4.2,"extendsCredential":"alienVaultApi"},{"id":"","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-52,460],"parameters":{"model":{"__rl":true,"mode":"list","value":"chatgpt-4o-latest","cachedResultName":"chatgpt-4o-latest"},"options":{"maxTokens":1500,"frequencyPenalty":0.5}},"credentials":{"openAiApi":{"id":"","name":"OpenAi account"}},"typeVersion":1.2},{"id":"","name":"Security Configuration Audit","type":"@n8n/n8n-nodes-langchain.agent","position":[-140,240],"parameters":{"text":"=[\n  {\n    \"role\": \"system\",\n    \"content\": \"You are a cybersecurity expert. Analyze the provided website data, including HTTP response details and AlienVault threat intelligence, to identify vulnerabilities or misconfigurations. For each issue, explain its nature, potential impact, a possible exploitation method (e.g., payload), and mitigation steps. Generate a concise report. Do not repeat the prompt or instructions.\"\n  },\n  {\n    \"role\": \"user\",\n    \"content\": \"URL: {{ $node['Prepare Data for AI'].json.url }}\\nStatus Code: {{ $node['Prepare Data for AI'].json.statusCode }}\\nSecurity Headers: {{ JSON.stringify($node['Prepare Data for AI'].json.securityHeaders) }}\\nPotential Issues: {{ JSON.stringify($node['Prepare Data for AI'].json.potentialIssues) }}\\nAlienVault Data: {{ JSON.stringify($node['Prepare Data for AI'].json.alienVaultInfo) }}\"\n  }\n]","options":{},"promptType":"define"},"typeVersion":1.7},{"id":"","name":"Send Security Report","type":"n8n-nodes-base.gmail","position":[456,240],"webhookId":"","parameters":{"sendTo":"=","message":"={{ $json.htmlReport }}","options":{},"subject":"=Website Security Audit - {{ $('On form submission').item.json['Landing Page'] }}"},"credentials":{"gmailOAuth2":{"id":"","name":"Gmail account"}},"typeVersion":2.1},{"id":"","name":"Prepare Data for AI","type":"n8n-nodes-base.code","position":[-360,240],"parameters":{"jsCode":"// Access inputs: HTTP data (first input) and potential AlienVault data (second input)\nconst httpData = $input.first()?.json || {}; // Assuming HTTP Request is the first input\nconst alienVaultInput = $input.all().length > 1 ? $input.all()[1] : null; // Check if a second input exists\nconst alienVaultData = alienVaultInput?.json || {};\n\n// Initialize the consolidated data object. This will be the input for the \"Security Configuration Audit\" node.\nconst consolidatedInputData = {\n  url: httpData.url || alienVaultData.indicator || 'URL not provided',\n  statusCode: httpData.statusCode || null,\n  securityHeaders: httpData.headers || {}, // Keep original headers\n  potentialIssues: [], // This will be augmented by the AI/Security Audit node\n  alienVaultInfo: {\n    domain: alienVaultData.domain || null,\n    sections: alienVaultData.sections || [],\n    whois: alienVaultData.whois || null,\n    pulseCount: alienVaultData.pulse_info?.count || 0\n  },\n  timestamp: new Date().toISOString(), // Add a timestamp for the report generation time\n  // Add raw inputs for debugging/reference (useful if you need to debug data flow)\n  _rawHttpInput: httpData,\n  _rawAlienVaultInput: alienVaultData\n};\n\n// Check for potential issues based on AlienVault data\nif (consolidatedInputData.alienVaultInfo.sections && consolidatedInputData.alienVaultInfo.sections.includes('malware')) {\n  consolidatedInputData.potentialIssues.push('Malware section detected in AlienVault data; further analysis recommended');\n}\nif (consolidatedInputData.alienVaultInfo.pulseCount > 0) {\n  consolidatedInputData.potentialIssues.push('Referenced in AlienVault pulses, indicating potential threats');\n}\n\n// Check for potential issues based on HTTP data\nif (consolidatedInputData.statusCode && consolidatedInputData.statusCode >= 400) {\n  consolidatedInputData.potentialIssues.push(`Server returned error status: ${consolidatedInputData.statusCode}`);\n}\n// Check if securityHeaders is an object and if it's empty\nif (consolidatedInputData.securityHeaders && typeof consolidatedInputData.securityHeaders === 'object' && Object.keys(consolidatedInputData.securityHeaders).length === 0) {\n  consolidatedInputData.potentialIssues.push('No security headers detected');\n}\n\n// Return a single item with the consolidated input data for the next node (Security Configuration Audit)\nreturn [\n  {\n    json: consolidatedInputData\n  }\n];"},"typeVersion":2,"alwaysOutputData":false},{"id":"","name":"Format Report for Email","type":"n8n-nodes-base.code","position":[236,240],"parameters":{"jsCode":"const aiReport = $input.first()?.json?.output; // Assuming AI output is under 'output' property in the first input item\n\nif (!aiReport) {\n  return [{ json: { htmlReport: \"<p>No AI report generated.</p>\" } }];\n}\n\n// Basic HTML formatting. You can make this much more sophisticated.\n// The AI's output is likely plain text, so we'll wrap it in <pre> or simple <p> tags.\n// If the AI is instructed to output Markdown, you could use a Markdown-to-HTML library here\n// (though n8n's Code node doesn't easily support external libraries).\n// For simplicity, let's assume plain text and wrap it.\n\nlet htmlContent = `\n<html>\n<head>\n  <style>\n    body { font-family: sans-serif; line-height: 1.6; color: #333; }\n    h1, h2 { color: #0056b3; }\n    pre { background-color: #f4f4f4; border: 1px solid #ddd; padding: 10px; border-radius: 4px; overflow-x: auto; }\n    .issue { color: #cc0000; font-weight: bold; }\n    .section-title { font-size: 1.2em; margin-top: 20px; border-bottom: 1px solid #eee; padding-bottom: 5px; }\n  </style>\n</head>\n<body>\n  <h1>Website Security Audit Report</h1>\n  <div class=\"section-title\">AI-Generated Analysis:</div>\n  <pre>${aiReport}</pre>\n  <div class=\"section-title\">Raw Data for Reference:</div>\n  <p>This is placeholder for raw data. You can expand on this section.</p>\n  </body>\n</html>\n`;\n\nreturn [{\n  json: {\n    htmlReport: htmlContent\n  }\n}];"},"typeVersion":2}],"pinData":{},"connections":{"HTTP Request":{"main":[[{"node":"AlienVault HTTP Request","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"Security Configuration Audit","type":"ai_languageModel","index":0}]]},"On form submission":{"main":[[{"node":"HTTP Request","type":"main","index":0}]]},"Prepare Data for AI":{"main":[[{"node":"Security Configuration Audit","type":"main","index":0}]]},"AlienVault HTTP Request":{"main":[[{"node":"Prepare Data for AI","type":"main","index":0}]]},"Format Report for Email":{"main":[[{"node":"Send Security Report","type":"main","index":0}]]},"Security Configuration Audit":{"main":[[{"node":"Format Report for Email","type":"main","index":0}]]}}}


name: 🛠️ Microsoft SharePoint Tool MCP Server 💪 all 11 operations
author_name: David Ashby
author_username: cfomodz
nodes_used: []
categories: []
created_at: 2025-06-24T03:52:04.362Z
updated_at: 2025-06-24T03:52:04.362Z
url: https://n8n.io/workflows/5178
scraped_at: 2025-07-06 21:16:30
description:
  🛠️ Microsoft SharePoint Tool MCP Server

  Complete MCP server exposing all Microsoft SharePoint Tool operations to AI agents. Zero configuration needed - all 11 operations pre-built.

  ⚡ Quick Setup

  Import this workflow into your n8n instance
  Activate the workflow to start your MCP server
  Copy the webhook URL from the MCP trigger node
  Connect AI agents using the MCP URL

  🔧 How it Works

  • MCP Trigger: Serves as your server endpoint for AI agent requests
  • Tool Nodes: Pre-configured for every Microsoft SharePoint Tool operation
  • AI Expressions: Automatically populate parameters via $fromAI() placeholders
  • Native Integration: Uses official n8n Microsoft SharePoint Tool tool with full error handling

  📋 Available Operations (11 total)

  Every possible Microsoft SharePoint Tool operation is included:

  📄 File (3 operations)

  • Download file
  • Update file
  • Upload file

  🔧 Item (6 operations)

  • Create item in a list
  • Create or update item (upsert)
  • Delete an item
  • Get an item
  • Get many items
  • Update item in a list

  📝 List (2 operations)

  • Get list
  • Get many lists

  🤖 AI Integration

  Parameter Handling: AI agents automatically provide values for:
  • Resource IDs and identifiers
  • Search queries and filters
  • Content and data payloads
  • Configuration options

  Response Format: Native Microsoft SharePoint Tool API responses with full data structure

  Error Handling: Built-in n8n error management and retry logic

  💡 Usage Examples

  Connect this MCP server to any AI agent or workflow:

  • Claude Desktop: Add MCP server URL to configuration
  • Custom AI Apps: Use MCP URL as tool endpoint
  • Other n8n Workflows: Call MCP tools from any workflow
  • API Integration: Direct HTTP calls to MCP endpoints

  ✨ Benefits

  • Complete Coverage: Every Microsoft SharePoint Tool operation available
  • Zero Setup: No parameter mapping or configuration needed
  • AI-Ready: Built-in $fromAI() expressions for all parameters
  • Production Ready: Native n8n error handling and logging
  • Extensible: Easily modify or add custom logic

  &gt; 🆓 Free for community use! Ready to deploy in under 2 minutes.

workflow_json:
  {"meta":{"instanceId":"cd59eaaeb7b34d06e24511380db94cdb7fbce6037cc4de22e539c5158ab9cdfc"},"nodes":[{"id":"16e0af5a-7eb7-4339-ad14-dc4e1c31e916","name":"Workflow Overview 0","type":"n8n-nodes-base.stickyNote","position":[-1460,-100],"parameters":{"content":""},"typeVersion":1},{"id":"76978095-e0cc-4d77-aa8a-0eb1482d0815","name":"Microsoft SharePoint Tool MCP Server","type":"@n8n/n8n-nodes-langchain.mcpTrigger","position":[-420,-160],"webhookId":"6385e017-4f6f-4200-a9f1-73ea33b86466","parameters":{},"typeVersion":1},{"id":"369bee00-93c1-4edc-8259-656372b99ec6","name":"Download file","type":"n8n-nodes-base.microsoftSharePointTool","position":[-800,140],"parameters":{},"typeVersion":1},{"id":"e6b5ee6a-a90d-42f5-a02d-69c5061a9626","name":"Update file","type":"n8n-nodes-base.microsoftSharePointTool","position":[-580,140],"parameters":{},"typeVersion":1},{"id":"83da4a4c-5859-4a91-b119-5a7b1d4107e6","name":"Upload file","type":"n8n-nodes-base.microsoftSharePointTool","position":[-360,140],"parameters":{},"typeVersion":1},{"id":"2949b159-3d82-421d-a4a9-6c22f40b2986","name":"Sticky Note 1","type":"n8n-nodes-base.stickyNote","position":[-1000,120],"parameters":{"content":""},"typeVersion":1},{"id":"4f9f1114-f7cb-4c73-be0a-514fa662eb68","name":"Create item in a list","type":"n8n-nodes-base.microsoftSharePointTool","position":[-800,380],"parameters":{},"typeVersion":1},{"id":"83d460e5-5664-4857-afc7-8765d85cd546","name":"Create or update item (upsert)","type":"n8n-nodes-base.microsoftSharePointTool","position":[-580,380],"parameters":{},"typeVersion":1},{"id":"05e3f248-fe8d-49d7-acbd-167d2833e055","name":"Delete an item","type":"n8n-nodes-base.microsoftSharePointTool","position":[-360,380],"parameters":{},"typeVersion":1},{"id":"26b60fa7-db7f-4971-984e-493dd532c91a","name":"Get an item","type":"n8n-nodes-base.microsoftSharePointTool","position":[-140,380],"parameters":{},"typeVersion":1},{"id":"1d971e7d-3d51-4789-b16d-f181e9ff61f3","name":"Get many items","type":"n8n-nodes-base.microsoftSharePointTool","position":[80,380],"parameters":{},"typeVersion":1},{"id":"b107fd3a-53aa-448a-a401-4ed107948d69","name":"Update item in a list","type":"n8n-nodes-base.microsoftSharePointTool","position":[300,380],"parameters":{},"typeVersion":1},{"id":"4ee4e3ce-b8a8-4d3b-ab82-ab79a14b7fb1","name":"Sticky Note 2","type":"n8n-nodes-base.stickyNote","position":[-1000,360],"parameters":{"content":""},"typeVersion":1},{"id":"cc1dc767-984a-4a1c-b244-f7be9ac660ae","name":"Get list","type":"n8n-nodes-base.microsoftSharePointTool","position":[-800,620],"parameters":{},"typeVersion":1},{"id":"f69905aa-26d4-4905-90e3-89ebd06c49d8","name":"Get many lists","type":"n8n-nodes-base.microsoftSharePointTool","position":[-580,620],"parameters":{},"typeVersion":1},{"id":"5395d23f-b6da-4273-b859-454035375c96","name":"Sticky Note 3","type":"n8n-nodes-base.stickyNote","position":[-1000,600],"parameters":{"content":""},"typeVersion":1}],"pinData":{},"connections":{"Get list":{"ai_tool":[[{"node":"Microsoft SharePoint Tool MCP Server","type":"ai_tool","index":0}]]},"Get an item":{"ai_tool":[[{"node":"Microsoft SharePoint Tool MCP Server","type":"ai_tool","index":0}]]},"Update file":{"ai_tool":[[{"node":"Microsoft SharePoint Tool MCP Server","type":"ai_tool","index":0}]]},"Upload file":{"ai_tool":[[{"node":"Microsoft SharePoint Tool MCP Server","type":"ai_tool","index":0}]]},"Download file":{"ai_tool":[[{"node":"Microsoft SharePoint Tool MCP Server","type":"ai_tool","index":0}]]},"Delete an item":{"ai_tool":[[{"node":"Microsoft SharePoint Tool MCP Server","type":"ai_tool","index":0}]]},"Get many items":{"ai_tool":[[{"node":"Microsoft SharePoint Tool MCP Server","type":"ai_tool","index":0}]]},"Get many lists":{"ai_tool":[[{"node":"Microsoft SharePoint Tool MCP Server","type":"ai_tool","index":0}]]},"Create item in a list":{"ai_tool":[[{"node":"Microsoft SharePoint Tool MCP Server","type":"ai_tool","index":0}]]},"Update item in a list":{"ai_tool":[[{"node":"Microsoft SharePoint Tool MCP Server","type":"ai_tool","index":0}]]},"Create or update item (upsert)":{"ai_tool":[[{"node":"Microsoft SharePoint Tool MCP Server","type":"ai_tool","index":0}]]}}}


name: 🛠️ Microsoft OneDrive Tool MCP Server 💪 all 14 operations
author_name: David Ashby
author_username: cfomodz
nodes_used: []
categories: []
created_at: 2025-06-24T04:04:16.104Z
updated_at: 2025-06-24T04:04:16.104Z
url: https://n8n.io/workflows/5179
scraped_at: 2025-07-06 21:16:30
description:
  🛠️ Microsoft OneDrive Tool MCP Server

  Complete MCP server exposing all Microsoft OneDrive Tool operations to AI agents. Zero configuration needed - all 14 operations pre-built.

  ⚡ Quick Setup

  Import this workflow into your n8n instance
  Activate the workflow to start your MCP server
  Copy the webhook URL from the MCP trigger node
  Connect AI agents using the MCP URL

  🔧 How it Works

  • MCP Trigger: Serves as your server endpoint for AI agent requests
  • Tool Nodes: Pre-configured for every Microsoft OneDrive Tool operation
  • AI Expressions: Automatically populate parameters via $fromAI() placeholders
  • Native Integration: Uses official n8n Microsoft OneDrive Tool tool with full error handling

  📋 Available Operations (14 total)

  Every possible Microsoft OneDrive Tool operation is included:

  📄 File (8 operations)

  • Copy a file
  • Delete a file
  • Download a file
  • Get a file
  • Rename a file
  • Search a file
  • Share a file
  • Upload a file

  📁 Folder (6 operations)

  • Create a folder
  • Delete a folder
  • Get items in a folder
  • Rename a folder
  • Search a folder
  • Share a folder

  🤖 AI Integration

  Parameter Handling: AI agents automatically provide values for:
  • Resource IDs and identifiers
  • Search queries and filters
  • Content and data payloads
  • Configuration options

  Response Format: Native Microsoft OneDrive Tool API responses with full data structure

  Error Handling: Built-in n8n error management and retry logic

  💡 Usage Examples

  Connect this MCP server to any AI agent or workflow:

  • Claude Desktop: Add MCP server URL to configuration
  • Custom AI Apps: Use MCP URL as tool endpoint
  • Other n8n Workflows: Call MCP tools from any workflow
  • API Integration: Direct HTTP calls to MCP endpoints

  ✨ Benefits

  • Complete Coverage: Every Microsoft OneDrive Tool operation available
  • Zero Setup: No parameter mapping or configuration needed
  • AI-Ready: Built-in $fromAI() expressions for all parameters
  • Production Ready: Native n8n error handling and logging
  • Extensible: Easily modify or add custom logic

  &gt; 🆓 Free for community use! Ready to deploy in under 2 minutes.

workflow_json:
  {"meta":{"instanceId":"cd59eaaeb7b34d06e24511380db94cdb7fbce6037cc4de22e539c5158ab9cdfc"},"nodes":[{"id":"c60186c4-3202-4814-adf7-208415bff3ef","name":"Workflow Overview 0","type":"n8n-nodes-base.stickyNote","position":[-1480,-340],"parameters":{"content":""},"typeVersion":1},{"id":"0bb7957e-368b-4444-8d34-437a1e10630b","name":"Microsoft OneDrive Tool MCP Server","type":"@n8n/n8n-nodes-langchain.mcpTrigger","position":[-420,-240],"webhookId":"9c6b4eee-cfab-4bbe-8988-aa28e02eb269","parameters":{},"typeVersion":1},{"id":"a676714c-9044-4117-8f0b-41777c21400f","name":"Copy a file","type":"n8n-nodes-base.microsoftOneDriveTool","position":[-800,140],"parameters":{},"typeVersion":1},{"id":"aa490f48-1d4a-4332-bb50-735d0381e6ee","name":"Delete a file","type":"n8n-nodes-base.microsoftOneDriveTool","position":[-580,140],"parameters":{},"typeVersion":1},{"id":"2a8a3002-c290-4c48-81a2-e03dd66ef7de","name":"Download a file","type":"n8n-nodes-base.microsoftOneDriveTool","position":[-360,140],"parameters":{},"typeVersion":1},{"id":"2284155a-b121-4330-a2b7-ccb396bad4ae","name":"Get a file","type":"n8n-nodes-base.microsoftOneDriveTool","position":[-140,140],"parameters":{},"typeVersion":1},{"id":"b60f4e12-ef71-45f1-8ab8-45239415eea8","name":"Rename a file","type":"n8n-nodes-base.microsoftOneDriveTool","position":[80,140],"parameters":{},"typeVersion":1},{"id":"963d944b-fcda-4b9e-b0a8-39c815e6d77f","name":"Search a file","type":"n8n-nodes-base.microsoftOneDriveTool","position":[300,140],"parameters":{},"typeVersion":1},{"id":"175a4f9c-5a2a-4ac9-bab9-927a90e16b08","name":"Share a file","type":"n8n-nodes-base.microsoftOneDriveTool","position":[520,140],"parameters":{},"typeVersion":1},{"id":"ecd3ed8d-5579-4343-ba21-7b17074daeaf","name":"Upload a file","type":"n8n-nodes-base.microsoftOneDriveTool","position":[740,140],"parameters":{},"typeVersion":1},{"id":"367802d6-a9a0-437f-a0b8-02eb7aa5abfe","name":"Sticky Note 1","type":"n8n-nodes-base.stickyNote","position":[-1000,120],"parameters":{"content":""},"typeVersion":1},{"id":"7c8daa19-e2ea-4f18-a9eb-db45e5987826","name":"Create a folder","type":"n8n-nodes-base.microsoftOneDriveTool","position":[-800,380],"parameters":{},"typeVersion":1},{"id":"f570f11d-114a-420a-8155-e71ee7a82aa3","name":"Delete a folder","type":"n8n-nodes-base.microsoftOneDriveTool","position":[-580,380],"parameters":{},"typeVersion":1},{"id":"c8ebcc49-9686-4bc4-8855-3f0d924aed95","name":"Get items in a folder","type":"n8n-nodes-base.microsoftOneDriveTool","position":[-360,380],"parameters":{},"typeVersion":1},{"id":"3e0388a0-4dfe-4922-89d2-85ef71bf34fb","name":"Rename a folder","type":"n8n-nodes-base.microsoftOneDriveTool","position":[-140,380],"parameters":{},"typeVersion":1},{"id":"8c2b8ee3-a60a-49f1-8c4a-2396c41c4dfd","name":"Search a folder","type":"n8n-nodes-base.microsoftOneDriveTool","position":[80,380],"parameters":{},"typeVersion":1},{"id":"ace5985b-5378-4a25-b2c5-cae49898e792","name":"Share a folder","type":"n8n-nodes-base.microsoftOneDriveTool","position":[300,380],"parameters":{},"typeVersion":1},{"id":"0739d440-f01d-432e-90ee-366f82eeaa21","name":"Sticky Note 2","type":"n8n-nodes-base.stickyNote","position":[-1000,360],"parameters":{"content":""},"typeVersion":1}],"pinData":{},"connections":{"Get a file":{"ai_tool":[[{"node":"Microsoft OneDrive Tool MCP Server","type":"ai_tool","index":0}]]},"Copy a file":{"ai_tool":[[{"node":"Microsoft OneDrive Tool MCP Server","type":"ai_tool","index":0}]]},"Share a file":{"ai_tool":[[{"node":"Microsoft OneDrive Tool MCP Server","type":"ai_tool","index":0}]]},"Delete a file":{"ai_tool":[[{"node":"Microsoft OneDrive Tool MCP Server","type":"ai_tool","index":0}]]},"Rename a file":{"ai_tool":[[{"node":"Microsoft OneDrive Tool MCP Server","type":"ai_tool","index":0}]]},"Search a file":{"ai_tool":[[{"node":"Microsoft OneDrive Tool MCP Server","type":"ai_tool","index":0}]]},"Upload a file":{"ai_tool":[[{"node":"Microsoft OneDrive Tool MCP Server","type":"ai_tool","index":0}]]},"Share a folder":{"ai_tool":[[{"node":"Microsoft OneDrive Tool MCP Server","type":"ai_tool","index":0}]]},"Create a folder":{"ai_tool":[[{"node":"Microsoft OneDrive Tool MCP Server","type":"ai_tool","index":0}]]},"Delete a folder":{"ai_tool":[[{"node":"Microsoft OneDrive Tool MCP Server","type":"ai_tool","index":0}]]},"Download a file":{"ai_tool":[[{"node":"Microsoft OneDrive Tool MCP Server","type":"ai_tool","index":0}]]},"Rename a folder":{"ai_tool":[[{"node":"Microsoft OneDrive Tool MCP Server","type":"ai_tool","index":0}]]},"Search a folder":{"ai_tool":[[{"node":"Microsoft OneDrive Tool MCP Server","type":"ai_tool","index":0}]]},"Get items in a folder":{"ai_tool":[[{"node":"Microsoft OneDrive Tool MCP Server","type":"ai_tool","index":0}]]}}}


name: 🛠️ Microsoft Graph Security Tool MCP Server 💪 all 5 operations
author_name: David Ashby
author_username: cfomodz
nodes_used: []
categories: []
created_at: 2025-06-24T04:07:11.669Z
updated_at: 2025-06-24T04:07:11.669Z
url: https://n8n.io/workflows/5180
scraped_at: 2025-07-06 21:16:30
description:
  🛠️ Microsoft Graph Security Tool MCP Server

  Complete MCP server exposing all Microsoft Graph Security Tool operations to AI agents. Zero configuration needed - all 5 operations pre-built.

  ⚡ Quick Setup

  Import this workflow into your n8n instance
  Activate the workflow to start your MCP server
  Copy the webhook URL from the MCP trigger node
  Connect AI agents using the MCP URL

  🔧 How it Works

  • MCP Trigger: Serves as your server endpoint for AI agent requests
  • Tool Nodes: Pre-configured for every Microsoft Graph Security Tool operation
  • AI Expressions: Automatically populate parameters via $fromAI() placeholders
  • Native Integration: Uses official n8n Microsoft Graph Security Tool tool with full error handling

  📋 Available Operations (5 total)

  Every possible Microsoft Graph Security Tool operation is included:

  🔧 Securescore (2 operations)

  • Get a secure score
  • Get many secure scores

  🔧 Securescorecontrolprofile (3 operations)

  • Get a secure score control profile
  • Get many secure score control profiles
  • Update a secure score control profile

  🤖 AI Integration

  Parameter Handling: AI agents automatically provide values for:
  • Resource IDs and identifiers
  • Search queries and filters
  • Content and data payloads
  • Configuration options

  Response Format: Native Microsoft Graph Security Tool API responses with full data structure

  Error Handling: Built-in n8n error management and retry logic

  💡 Usage Examples

  Connect this MCP server to any AI agent or workflow:

  • Claude Desktop: Add MCP server URL to configuration
  • Custom AI Apps: Use MCP URL as tool endpoint
  • Other n8n Workflows: Call MCP tools from any workflow
  • API Integration: Direct HTTP calls to MCP endpoints

  ✨ Benefits

  • Complete Coverage: Every Microsoft Graph Security Tool operation available
  • Zero Setup: No parameter mapping or configuration needed
  • AI-Ready: Built-in $fromAI() expressions for all parameters
  • Production Ready: Native n8n error handling and logging
  • Extensible: Easily modify or add custom logic

  &gt; 🆓 Free for community use! Ready to deploy in under 2 minutes.

workflow_json:
  {"meta":{"instanceId":"cd59eaaeb7b34d06e24511380db94cdb7fbce6037cc4de22e539c5158ab9cdfc"},"nodes":[{"id":"b370c04c-67ec-4ca6-9e9a-a163378faaa7","name":"Workflow Overview 0","type":"n8n-nodes-base.stickyNote","position":[-1460,-140],"parameters":{"content":""},"typeVersion":1},{"id":"bf280b14-1e9c-4b9d-9ec0-27099d66a5a1","name":"Microsoft Graph Security Tool MCP Server","type":"@n8n/n8n-nodes-langchain.mcpTrigger","position":[-440,-120],"webhookId":"71997e2b-ea25-4220-987b-b42d4200bd21","parameters":{},"typeVersion":1},{"id":"b14ce778-7b83-4e8d-8bc3-2fbd6d970a8d","name":"Get a secure score","type":"n8n-nodes-base.microsoftGraphSecurityTool","position":[-800,140],"parameters":{},"typeVersion":1},{"id":"21ffbbf4-4844-450a-8c55-ce9b62ab4edd","name":"Get many secure scores","type":"n8n-nodes-base.microsoftGraphSecurityTool","position":[-580,140],"parameters":{},"typeVersion":1},{"id":"789efee9-e02e-497c-9692-e36c800e7ce2","name":"Sticky Note 1","type":"n8n-nodes-base.stickyNote","position":[-1000,100],"parameters":{"content":""},"typeVersion":1},{"id":"f964cb70-7898-4075-8807-0c84ed6683bb","name":"Get a secure score control profile","type":"n8n-nodes-base.microsoftGraphSecurityTool","position":[-800,380],"parameters":{},"typeVersion":1},{"id":"d90c1d4d-da36-4ede-b332-606e0c8e38ef","name":"Get many secure score control profiles","type":"n8n-nodes-base.microsoftGraphSecurityTool","position":[-580,380],"parameters":{},"typeVersion":1},{"id":"588887d8-618b-47d6-bf89-99744b5a7de4","name":"Update a secure score control profile","type":"n8n-nodes-base.microsoftGraphSecurityTool","position":[-360,380],"parameters":{},"typeVersion":1},{"id":"20ae2973-642b-4d53-997b-58449bcb7ac7","name":"Sticky Note 2","type":"n8n-nodes-base.stickyNote","position":[-1000,340],"parameters":{"content":""},"typeVersion":1}],"pinData":{},"connections":{"Get a secure score":{"ai_tool":[[{"node":"Microsoft Graph Security Tool MCP Server","type":"ai_tool","index":0}]]},"Get many secure scores":{"ai_tool":[[{"node":"Microsoft Graph Security Tool MCP Server","type":"ai_tool","index":0}]]},"Get a secure score control profile":{"ai_tool":[[{"node":"Microsoft Graph Security Tool MCP Server","type":"ai_tool","index":0}]]},"Update a secure score control profile":{"ai_tool":[[{"node":"Microsoft Graph Security Tool MCP Server","type":"ai_tool","index":0}]]},"Get many secure score control profiles":{"ai_tool":[[{"node":"Microsoft Graph Security Tool MCP Server","type":"ai_tool","index":0}]]}}}


name: Pinterest Keyword-Based Content Scraper with AI Agent & BrightData Automation
author_name: Shiv Gupta
author_username: shivgupta
categories: []
created_at: 2025-06-24T08:38:03.685Z
updated_at: 2025-06-24T08:38:03.685Z
url: https://n8n.io/workflows/5193
scraped_at: 2025-07-06 21:16:30
description:
  Pinterest Keyword-Based Content Scraper with AI Agent & BrightData Automation

  Overview

  This n8n workflow automates Pinterest content scraping based on user-provided keywords using BrightData's API and Claude Sonnet 4 AI agent. The system intelligently processes keywords, initiates scraping jobs, monitors progress, and formats the extracted data into structured outputs.

  Architecture Components

  🧠 AI-Powered Controller
  Claude Sonnet 4 Model**: Processes and understands keywords before initiating scrape
  AI Agent**: Acts as the intelligent controller coordinating all scraping steps

  📥 Data Input
  Form Trigger**: User-friendly keyword input interface
  Keywords Field**: Required input field for Pinterest search terms

  🚀 Scraping Pipeline
  Launch Scraping Job: Sends keywords to BrightData API
  Status Monitoring: Continuously checks scraping progress
  Data Retrieval: Downloads completed scraped content
  Data Processing: Formats and structures the raw data
  Storage: Saves results to Google Sheets

  Workflow Nodes

  1. Pinterest Keyword Input
  Type**: Form Trigger
  Purpose**: Entry point for user keyword submission
  Configuration**: 
    Form title: "Pinterest"
    Required field: "Keywords"

  2. Anthropic Chat Model
  Type**: Language Model (Claude Sonnet 4)
  Model**: claude-sonnet-4-20250514
  Purpose**: AI-powered keyword processing and workflow orchestration

  3. Keyword-based Scraping Agent
  Type**: AI Agent
  Purpose**: Orchestrates the entire scraping process
  Instructions**:
    Initiates Pinterest scraping with provided keywords
    Monitors scraping status until completion
    Downloads final scraped data
    Presents raw scraped data as output

  4. BrightData Pinterest Scraping
  Type**: HTTP Request Tool
  Method**: POST
  Endpoint**: https://api.brightdata.com/datasets/v3/trigger
  Parameters**:
    dataset_id: gd_lk0sjs4d21kdr7cnlv
    include_errors: true
    type: discover_new
    discover_by: keyword
    limit_per_input: 2
  Purpose**: Creates new scraping snapshot based on keywords

  5. Check Scraping Status
  Type**: HTTP Request Tool
  Method**: GET
  Endpoint**: https://api.brightdata.com/datasets/v3/progress/{snapshot_id}
  Purpose**: Monitors scraping job progress
  Returns**: Status values like "running" or "ready"

  6. Fetch Pinterest Snapshot Data
  Type**: HTTP Request Tool
  Method**: GET
  Endpoint**: https://api.brightdata.com/datasets/v3/snapshot/{snapshot_id}
  Purpose**: Downloads completed scraped data
  Trigger**: Executes when status is "ready"

  7. Format & Extract Pinterest Content
  Type**: Code Node (JavaScript)
  Purpose**: Parses and structures raw scraped data
  Extracted Fields**:
    URL
    Post ID
    Title
    Content
    Date Posted
    User
    Likes & Comments
    Media
    Image URL
    Categories
    Hashtags

  8. Save Pinterest Data to Google Sheets
  Type**: Google Sheets Node
  Operation**: Append
  Mapped Columns**:
    Post URL
    Title
    Content
    Image URL

  9. Wait for 1 Minute (Disabled)
  Type**: Code Tool
  Purpose**: Adds delay between status checks (currently disabled)
  Duration**: 60 seconds

  Setup Requirements

  Required Credentials

  Anthropic API
     Credential ID: ANTHROPIC_CREDENTIAL_ID
     Required for Claude Sonnet 4 access

  BrightData API
     API Key: BRIGHT_DATA_API_KEY
     Required for Pinterest scraping service

  Google Sheets OAuth2
     Credential ID: GOOGLE_SHEETS_CREDENTIAL_ID
     Required for data storage

  Configuration Placeholders

  Replace the following placeholders with actual values:

  WEBHOOK_ID_PLACEHOLDER: Form trigger webhook ID
  GOOGLE_SHEET_ID_PLACEHOLDER: Target Google Sheets document ID
  WORKFLOW_VERSION_ID: n8n workflow version
  INSTANCE_ID_PLACEHOLDER: n8n instance identifier
  WORKFLOW_ID_PLACEHOLDER: Unique workflow identifier

  Data Flow

  User Input (Keywords) 
      ↓
  AI Agent Processing (Claude)
      ↓
  BrightData Scraping Job Creation
      ↓
  Status Monitoring Loop
      ↓
  Data Retrieval (when ready)
      ↓
  Content Formatting & Extraction
      ↓
  Google Sheets Storage

  Output Data Structure

  Each scraped Pinterest pin contains:

  URL**: Direct link to Pinterest pin
  Post ID**: Unique Pinterest identifier
  Title**: Pin title/heading
  Content**: Pin description text
  Date Posted**: Publication timestamp
  User**: Pinterest username
  Engagement**: Likes and comments count
  Media**: Media type information
  Image URL**: Direct image link
  Categories**: Pin categorization tags
  Hashtags**: Associated hashtags
  Comments**: User comments text

  Usage Instructions

  Initial Setup:
     Configure all required API credentials
     Replace placeholder values with actual IDs
     Create target Google Sheets document

  Running the Workflow:
     Access the form trigger URL
     Enter desired Pinterest keywords
     Submit the form to initiate scraping

  Monitoring Progress:
     The AI agent will automatically handle status monitoring
     No manual intervention required during scraping

  Accessing Results:
     Structured data will be automatically saved to Google Sheets
     Each run appends new data to existing sheet

  Technical Notes

  Rate Limiting**: BrightData API has built-in rate limiting
  Data Limits**: Current configuration limits 2 pins per keyword
  Status Polling**: Automatic status checking until completion
  Error Handling**: Includes error capture in scraping requests
  Async Processing**: Supports long-running scraping jobs

  Customization Options

  Adjust Data Limits**: Modify limit_per_input parameter
  Enable Wait Timer**: Activate the disabled wait node for longer jobs
  Custom Data Fields**: Modify the formatting code for additional fields
  Alternative Storage**: Replace Google Sheets with other storage options

  Sample Google Sheets Template

  Create a copy of the sample sheet structure:
  https://docs.google.com/spreadsheets/d/SAMPLE_SHEET_ID/edit

  Required columns:
  Post URL
  Title  
  Content
  Image URL

  Troubleshooting

  Authentication Errors**: Verify all API credentials are correctly configured
  Scraping Failures**: Check BrightData API status and rate limits
  Data Formatting Issues**: Review the JavaScript formatting code for parsing errors
  Google Sheets Errors**: Ensure proper OAuth2 permissions and sheet access


  For any questions or support, please contact: Email or
  fill out this form

nodes_used:
  ["n8n-nodes-base.googleSheets","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatAnthropic","@n8n/n8n-nodes-langchain.toolCode"]

workflow_json:
  {"id":"WORKFLOW_ID_PLACEHOLDER","meta":{"instanceId":"INSTANCE_ID_PLACEHOLDER","templateCredsSetupCompleted":true},"name":"MCP: Pinterest Keyword-Based Content Scraper with AI Agent & BrightData Automation","tags":[],"nodes":[{"id":"5234018f-d12c-439f-9713-2a7cd9cb239f","name":"Anthropic Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatAnthropic","position":[-240,320],"parameters":{"model":{"__rl":true,"mode":"list","value":"claude-sonnet-4-20250514","cachedResultName":"Claude 4 Sonnet"},"options":{}},"credentials":{"anthropicApi":{"id":"ANTHROPIC_CREDENTIAL_ID","name":"Anthropic API"}},"typeVersion":1.3},{"id":"e3ebf96d-a8d9-41cf-b5bc-d7eda3776aa2","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[280,-200],"parameters":{"color":2,"width":500,"height":260,"content":"🤖 AI Agent  \nProcesses input keyword via language model (Claude). Acts as controller for all scraping-related steps.\n"},"typeVersion":1},{"id":"b47df625-4d67-4d9c-b94c-dc32a09077be","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[1080,260],"parameters":{"color":6,"width":320,"height":260,"content":"⏱️ Wait Timer (Disabled)  \nWaits 1 minute before retrying scraping status. Currently disabled but useful for longer jobs.\n"},"typeVersion":1},{"id":"a674d3dc-ff9f-42fc-8bc4-737a64ef0bd1","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[700,360],"parameters":{"color":5,"width":320,"height":260,"content":"📦 Download Scraped Data  \nFetches scraped Pinterest data once the snapshot status is \"ready\". This returns actual content data.\n"},"typeVersion":1},{"id":"966c2317-199b-439a-9651-37fde866eae2","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[380,360],"parameters":{"color":4,"width":280,"height":260,"content":"🔄 Check Snapshot Progress  \nContinuously checks scraping status (like \"running\", \"ready\") using `snapshot_id`. Loops until data is ready.\n"},"typeVersion":1},{"id":"28aaa784-5cb2-42db-b170-284cbf3bfcdb","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[40,280],"parameters":{"color":3,"width":280,"height":280,"content":"🚀 Launch Scraping Job  \nSends the keyword to BrightData API using POST request to create a scraping snapshot. Returns a `snapshot_id`.\n"},"typeVersion":1},{"id":"38c7467d-cc5f-4e7e-acfc-339e9700ff49","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-320,200],"parameters":{"width":280,"height":260,"content":"🧠 Claude Sonnet 4 Model  \nUsed to intelligently process, understand, or enrich keywords before initiating scrape via the AI agent.\n"},"typeVersion":1},{"id":"5fc7d5ee-83a4-4f5f-b41b-270af43f6f2c","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-40,-240],"parameters":{"color":6,"width":260,"height":280,"content":"📥 Keyword Input Form  \nUser submits keywords here to initiate scraping. This is the entry trigger for the Pinterest automation.\n"},"typeVersion":1},{"id":"dcdb9696-579f-49fc-bab0-3f81a4f87595","name":"BrightData Pinterest Scraping","type":"n8n-nodes-base.httpRequestTool","position":[140,400],"parameters":{"url":"https://api.brightdata.com/datasets/v3/trigger","method":"POST","options":{},"jsonBody":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('JSON', `This HTTP POST request sends the user's chat input (like \"Food\") to the BrightData Pinterest collector. The collector uses this input to create a new scraping snapshot based on the keyword. The request body includes a sessionId, action, and chatInput, and the response will return a snapshot_id which will be used in the next steps to fetch the scraped data.\n[{\"keyword\":\"food\"}]`, 'json') }}","sendBody":true,"sendQuery":true,"sendHeaders":true,"specifyBody":"json","queryParameters":{"parameters":[{"name":"dataset_id","value":"gd_lk0sjs4d21kdr7cnlv"},{"name":"include_errors","value":"true"},{"name":"type","value":"discover_new"},{"name":"discover_by","value":"keyword"},{"name":"limit_per_input","value":"2"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2},{"id":"9657f18e-62d4-44d4-8537-39175b983f17","name":"Check Scraping Status","type":"n8n-nodes-base.httpRequestTool","position":[460,480],"parameters":{"url":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('URL', `use snapshot id to create http request url \nfor example:\nhttps://api.brightdata.com/datasets/v3/progress/your_snapshot_id`, 'string') }}","options":{},"sendQuery":true,"sendHeaders":true,"queryParameters":{"parameters":[{"name":"format","value":"json"}]},"toolDescription":"Makes an HTTP request to check the status of snapshot_id and returns the status like \"ready\" or \"running\". If the status received is \"running\", then make another HTTP request.","headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2},{"id":"d2af5353-509f-4a82-b861-f66c5add7abb","name":"Fetch Pinterest Snapshot Data","type":"n8n-nodes-base.httpRequestTool","position":[800,460],"parameters":{"url":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('URL', `make http request URL with snapshot_id \nfor example:\nhttps://api.brightdata.com/datasets/v3/snapshot/your_snapshot_id`, 'string') }}","options":{},"sendQuery":true,"sendHeaders":true,"queryParameters":{"parameters":[{"name":"format","value":"json"}]},"toolDescription":"Makes an HTTP request if when you snapshot_id in ready status and returns the response data","headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2},{"id":"72be1274-d741-46b1-8fb9-edfd4dc44e69","name":"Pinterest Keyword Input","type":"n8n-nodes-base.formTrigger","position":[40,-120],"webhookId":"WEBHOOK_ID_PLACEHOLDER","parameters":{"options":{},"formTitle":"Pinterest","formFields":{"values":[{"fieldLabel":"Keywords","requiredField":true}]}},"typeVersion":2.2},{"id":"ea43cb15-38f9-46c7-b1da-320a2687d65a","name":"Wait for 1 Minute","type":"@n8n/n8n-nodes-langchain.toolCode","disabled":true,"position":[1180,360],"parameters":{"jsCode":"async function sleep(ms) {\n  return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n// ⏱️ 1 Minute = 60000 ms\nawait sleep(60000);\n\nreturn [\n  {\n    json: {\n      message: \"1 minute wait done\",\n      originalInput: $json[\"message\"] || \"No input\"\n    }\n  }\n];\n"},"typeVersion":1.2},{"id":"834ca6f4-0f62-4de3-a321-20455864df1f","name":"Keyword-based Scraping Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[360,-120],"parameters":{"text":"=\nYou are an AI-powered Pinterest content scraping agent. Your goal is to find relevant content based on user-provided keywords.\n\n**Instructions:**\n1. The user will provide a keyword {{ $json.Keywords }}.\n2. Your primary task is to initiate a Pinterest content scraping job using the provided `BrightData Pinterest Scraping` tool with the given keyword.\n3. Once the scraping job is launched, you must use the `Check Scraping Status` tool to monitor its progress. You need to keep checking the status until it reports \"ready\". If the status is \"running\", you should indicate that you are waiting and will check again.\n4. Once the status is \"ready\", use the `Fetch Pinterest Snapshot Data` tool to download the scraped content.\n5. After successfully fetching the data, present the raw scraped data as your final output.","options":{},"promptType":"define"},"typeVersion":2},{"id":"29790c94-25fc-4bb3-89ec-1bc64bf0558d","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[-440,-480],"parameters":{"color":7,"width":660,"height":140,"content":"📌 Notes Placeholder  \nCurrently unused — ideal for adding documentation, reminders, or tips related to this automation.\n"},"typeVersion":1},{"id":"65d06d4d-4ff4-4db6-a8fa-3ffb4cc144e6","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[1120,-200],"parameters":{"color":3,"width":380,"height":280,"content":"\"This is the final output step where formatted Pinterest content is saved for future use, reporting, or distribution.\""},"typeVersion":1},{"id":"7bad4070-9b30-4929-89c0-7130a6021349","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[800,-220],"parameters":{"width":260,"height":280,"content":"Extracts and structures scraped Pinterest data into clean fields like Title, URL, Content, Image URL, Hashtags, etc."},"typeVersion":1},{"id":"e5e34ef4-5344-4aff-9dc9-3094362c35f0","name":"Format & Extract Pinterest Content","type":"n8n-nodes-base.code","position":[880,-120],"parameters":{"jsCode":"const results = [];\n\nfor (const item of $input.all()) {\n  const rawOutput = item.json.output;\n\n  if (!rawOutput) continue;\n\n  const records = rawOutput.split(/\\*\\*Pin \\d+:\\*\\*/g);\n\n  for (let i = 1; i < records.length; i++) {\n    const recordText = records[i];\n    if (recordText.trim() === '') continue;\n\n    const extractedItem = {};\n\n    // Extract fields using updated regex\n    const urlMatch = recordText.match(/- \\*\\*URL:\\*\\* (.*)/);\n    if (urlMatch) extractedItem.URL = urlMatch[1].trim();\n\n    const postIdMatch = recordText.match(/- \\*\\*Post ID:\\*\\* (.*)/);\n    if (postIdMatch) extractedItem.PostID = postIdMatch[1].trim();\n\n    const titleMatch = recordText.match(/- \\*\\*Title:\\*\\* (.*)/);\n    if (titleMatch) extractedItem.Title = titleMatch[1].trim();\n\n    const contentMatch = recordText.match(/- \\*\\*Content:\\*\\* (.*)/);\n    if (contentMatch) extractedItem.Content = contentMatch[1].trim();\n\n    const datePostedMatch = recordText.match(/- \\*\\*Date Posted:\\*\\* (.*)/);\n    if (datePostedMatch) extractedItem.DatePosted = datePostedMatch[1].trim();\n\n    const userMatch = recordText.match(/- \\*\\*User:\\*\\* (.*)/);\n    if (userMatch) extractedItem.User = userMatch[1].trim();\n\n    const engagementMatch = recordText.match(/- \\*\\*Engagement:\\*\\* (\\d+) likes, (\\d+) comment/);\n    if (engagementMatch) {\n      extractedItem.Likes = parseInt(engagementMatch[1], 10);\n      extractedItem.Comments = parseInt(engagementMatch[2], 10);\n    }\n\n    const mediaMatch = recordText.match(/- \\*\\*Media:\\*\\* (.*)/);\n    if (mediaMatch) extractedItem.Media = mediaMatch[1].trim();\n\n    const imageUrlMatch = recordText.match(/- \\*\\*Image URL:\\*\\* (.*)/);\n    if (imageUrlMatch) extractedItem.ImageURL = imageUrlMatch[1].trim();\n\n    const categoriesMatch = recordText.match(/- \\*\\*Categories:\\*\\* (.*)/);\n    if (categoriesMatch) {\n      extractedItem.Categories = categoriesMatch[1].split(',').map(s => s.trim());\n    }\n\n    const hashtagsMatch = recordText.match(/- \\*\\*Hashtags:\\*\\* (.*)/);\n    if (hashtagsMatch) {\n      extractedItem.Hashtags = hashtagsMatch[1].split(',').map(s => s.trim());\n    }\n\n    const commentMatch = recordText.match(/- \\*\\*Comment:\\*\\* (.*)/);\n    if (commentMatch) extractedItem.Comment = commentMatch[1].trim();\n\n    const commentsSectionMatch = recordText.match(/- \\*\\*Comments:\\*\\* (.*)/);\n    if (commentsSectionMatch) {\n      extractedItem.CommentsText = commentsSectionMatch[1].split(',').map(s => s.trim());\n    }\n\n    if (Object.keys(extractedItem).length > 0) {\n      results.push({ json: extractedItem });\n    }\n  }\n}\n\nreturn results;\n"},"typeVersion":2},{"id":"7528da1f-032c-49f6-b088-997119a72b36","name":"Save Pinterest Data to Google Sheets","type":"n8n-nodes-base.googleSheets","position":[1260,-120],"parameters":{"columns":{"value":{"Title":"={{ $json.Title }}","Content":"={{ $json.Content }}","Post URL":"={{ $json.URL }}","Image URL":"={{ $json.ImageURL }}"},"schema":[{"id":"Post URL","type":"string","display":true,"required":false,"displayName":"Post URL","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Title","type":"string","display":true,"required":false,"displayName":"Title","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Content","type":"string","display":true,"removed":false,"required":false,"displayName":"Content","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Image URL","type":"string","display":true,"removed":false,"required":false,"displayName":"Image URL","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"append","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"url","value":"GOOGLE_SHEET_ID_PLACEHOLDER"}},"credentials":{"googleSheetsOAuth2Api":{"id":"GOOGLE_SHEETS_CREDENTIAL_ID","name":"Google Sheets OAuth2"}},"typeVersion":4.6},{"id":"1ed9bda3-86ca-4699-b5a5-c90672a7dc9f","name":"Sticky Note11","type":"n8n-nodes-base.stickyNote","position":[700,-520],"parameters":{"color":7,"content":"Create a copy of this sample sheet:\n\nhttps://docs.google.com/spreadsheets/d/SAMPLE_SHEET_ID/edit"},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"WORKFLOW_VERSION_ID","connections":{"Wait for 1 Minute":{"ai_tool":[[{"node":"Keyword-based Scraping Agent","type":"ai_tool","index":0}]]},"Anthropic Chat Model":{"ai_languageModel":[[{"node":"Keyword-based Scraping Agent","type":"ai_languageModel","index":0}]]},"Check Scraping Status":{"ai_tool":[[{"node":"Keyword-based Scraping Agent","type":"ai_tool","index":0}]]},"Pinterest Keyword Input":{"main":[[{"node":"Keyword-based Scraping Agent","type":"main","index":0}]]},"Keyword-based Scraping Agent":{"main":[[{"node":"Format & Extract Pinterest Content","type":"main","index":0}]]},"BrightData Pinterest Scraping":{"ai_tool":[[{"node":"Keyword-based Scraping Agent","type":"ai_tool","index":0}]]},"Fetch Pinterest Snapshot Data":{"ai_tool":[[{"node":"Keyword-based Scraping Agent","type":"ai_tool","index":0}]]},"Format & Extract Pinterest Content":{"main":[[{"node":"Save Pinterest Data to Google Sheets","type":"main","index":0}]]}}}


name: AI-Powered Product Research & SEO Content Automation
author_name: Evoort Solutions
author_username: evoortsolutions
categories: []
created_at: 2025-06-24T09:43:17.079Z
updated_at: 2025-06-24T09:43:17.079Z
url: https://n8n.io/workflows/5195
scraped_at: 2025-07-06 21:16:30
description:
  AI-Powered Product Research & SEO Content Automation

  Skip the guesswork and manual effort — this n8n flow automates the entire process of researching your product's online competition and generating high-quality SEO content. Whether you're launching a new product or optimizing existing listings, this workflow leverages real-time web data and AI-driven copywriting to deliver:

  📈 Search-optimized metadata (Title, Description, Keywords)  
  🛍️ Engaging product descriptions tailored for marketing  
  📊 Auto-organized output ready for use in your content or e-commerce platform

  All of this happens with just one product title input!

  🧠 How It Works
  • User submits a product title via a form.  
  • The workflow uses Google Custom Search to gather real-time competitor content based on that title.  
  • Titles, snippets, and keywords are extracted from the search results.  
  • This information is sent to a language model (Google Gemini via LangChain) to generate:  
     SEO-optimized metadata (Title, Description, Keywords)  
     A compelling product description tailored for marketing  
  • The AI-generated content is then parsed and organized into two categories: SEO data and product content.  
  • The structured output is saved automatically into a connected Google Sheet for easy access or further automation.

  🛠️ What Problems Does This Solve?
  Manual competitor research and writing SEO content from scratch can be:
  Time-consuming**
  Inconsistent in quality**
  Not optimized for search engines**
  Hard to scale for multiple products**

  This workflow automates the entire research + writing + structuring process.

  ✅ Key Benefits
  Instant Content Creation**: Generate polished SEO content in seconds.  
  Competitor-Aware**: Pulls in real-time data from the web for relevant, market-aligned content.  
  Scalable**: Easily repeat the process for multiple product titles with minimal effort.  
  Data Centralization**: Stores everything in Google Sheets—great for collaboration or syncing with other tools.  
  Customizable**: Easily extend or modify the workflow to include translations, publishing, or social media automation.

  ⚙️ Set-Up Steps
  • Connect Google Custom Search API with a valid API key and search engine ID (CX).  
  • Connect and configure Google Gemini or LangChain with access credentials.  
  • Provide access to a Google Sheet with columns for storing SEO and product data.  
  • Estimated setup time: ~15–25 minutes depending on API access and sheet setup.  

  🚀 Let’s Get You Started with Automating Your LinkedIn Posts!

  Create your free n8n account and set up the workflow in just a few minutes using the link below:

  👉 Start Automating with n8n

  Save time, stay consistent, and grow your LinkedIn presence effortlessly!

nodes_used:
  ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.chainLlm","@n8n/n8n-nodes-langchain.lmChatGoogleGemini"]

workflow_json:
  {"id":"icW2uoM7g7pFZhsR","meta":{"instanceId":"60c025075753afcab9f803964b4caaca9402f435deb4efafbb8e3b93b54d8752","templateCredsSetupCompleted":true},"name":"AI-Powered Product Research & SEO Content Automation","tags":[{"id":"QXtLNWbsCSABOTNm","name":"Digital Marketing","createdAt":"2025-05-29T11:14:57.099Z","updatedAt":"2025-05-29T11:14:57.099Z"}],"nodes":[{"id":"f3824049-9114-447c-8c3f-e3a08af34d12","name":"Google Search","type":"n8n-nodes-base.httpRequest","position":[400,-120],"parameters":{"url":"https://www.googleapis.com/customsearch/v1","options":{},"queryParametersUi":{"parameter":[{"name":"key","value":"your key"},{"name":"cx","value":"your cx"},{"name":"q","value":"=intitle:\"{{ $json.title }}\" (pricing OR features OR buy OR software) -medium.com -quora.com -youtube.com -linkedin.com "}]}},"typeVersion":1},{"id":"840baf66-d14c-4d2c-90f5-05ba174bcc15","name":"Extract Competitor Data","type":"n8n-nodes-base.function","position":[680,-100],"parameters":{"functionCode":"let allTitles = [];\nlet allDescriptions = [];\nlet allKeywords = [];\n\nfor (const item of $json.items) {\n  allTitles.push(item.title);\n  allDescriptions.push(item.snippet);\n\n  const keywords = item.title\n    .toLowerCase()\n    .replace(/[^a-zA-Z0-9 ]/g, '')\n    .split(' ')\n    .filter(w => w.length > 3);\n\n  allKeywords.push(...keywords);\n}\n\n// Create unique keywords\nconst uniqueKeywords = [...new Set(allKeywords)];\n\nreturn [\n  {\n    json: {\n      chatInput: `\nTitle List:\n${allTitles.join('\\n')}\n\nDescription List:\n${allDescriptions.join('\\n')}\n\nKeywords:\n${uniqueKeywords.join(', ')}\n      `.trim()\n    }\n  }\n];\n"},"typeVersion":1},{"id":"0a2929a1-d6fc-4a37-b142-54b0e2135652","name":"Basic LLM Chain","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[920,-100],"parameters":{"messages":{"messageValues":[{"message":"You are an expert SEO content writer and product copywriter.  generate the following in one output:  1. SEO Meta Data: - Title: (exact product title, must be the same as product title below) - Description: A concise, persuasive meta description optimized for Google SEO best practices. Make sure it is between 120-160 characters, includes main keywords naturally, and encourages clicks. - Keywords: A list of relevant, highly ranked keywords related to the product.  2. Product Content: - Product Title: (exact same title as SEO Meta Data Title) - Product Description: A detailed, engaging product description of minimum 150 words that highlights the product’s key features, benefits, and usage. Use natural language with relevant keywords but avoid keyword stuffing.  Format the output exactly like this:  --- SEO Meta Data: Title: ... Description: ... Keywords: ...  Product Content: Product Title: ... Product Description: ...  ---  Ensure that the SEO Meta Data Title and Product Title are exactly the same string. Follow SEO best practices for titles, descriptions, and keyword usage to maximize Google ranking potential."}]}},"typeVersion":1.5},{"id":"797456cf-d4a2-49b7-8134-d5ebbf062cc7","name":"Google Gemini Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[940,360],"parameters":{"options":{},"modelName":"models/gemini-2.0-flash"},"credentials":{"googlePalmApi":{"id":"Xpxt71RcelLLFyE3","name":"Google Gemini(PaLM) Api account"}},"typeVersion":1},{"id":"44d6ebd9-ad12-4838-aee0-9b8a4a847a6b","name":"Google Sheets","type":"n8n-nodes-base.googleSheets","position":[1660,-140],"parameters":{"columns":{"value":{},"schema":[{"id":"type","type":"string","display":true,"removed":false,"required":false,"displayName":"type","defaultMatch":false,"canBeUsedToMatch":true},{"id":"title","type":"string","display":true,"removed":false,"required":false,"displayName":"title","defaultMatch":false,"canBeUsedToMatch":true},{"id":"description","type":"string","display":true,"removed":false,"required":false,"displayName":"description","defaultMatch":false,"canBeUsedToMatch":true},{"id":"keywords","type":"string","display":true,"removed":false,"required":false,"displayName":"keywords","defaultMatch":false,"canBeUsedToMatch":true},{"id":"product_title","type":"string","display":true,"removed":false,"required":false,"displayName":"product_title","defaultMatch":false,"canBeUsedToMatch":true},{"id":"product_description","type":"string","display":true,"removed":false,"required":false,"displayName":"product_description","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"autoMapInputData","matchingColumns":["text"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"appendOrUpdate","sheetName":{"__rl":true,"mode":"url","value":""},"documentId":{"__rl":true,"mode":"url","value":""},"authentication":"serviceAccount"},"credentials":{"googleApi":{"id":"Rt0RWApx8PL9t0RF","name":"Google Docs account"}},"typeVersion":4.5},{"id":"571bb379-f061-42ae-b633-3e80467a0a3d","name":"On form submission","type":"n8n-nodes-base.formTrigger","position":[-180,-140],"webhookId":"f7e2c20d-4cd1-45f1-b6f7-54eb48c2ad91","parameters":{"options":{},"formTitle":"Product Research ","formFields":{"values":[{"fieldLabel":"title","placeholder":"Enter product title","requiredField":true}]}},"typeVersion":2.2},{"id":"0a4b670a-50b3-4a60-ae51-e3bb958f573a","name":"Edit Fields","type":"n8n-nodes-base.set","position":[120,-140],"parameters":{"options":{},"assignments":{"assignments":[{"id":"39f794ce-8c11-4f72-b8d9-4ad0894d1e05","name":"title","type":"string","value":"={{ $json.title }}"}]}},"typeVersion":3.4},{"id":"85ecfcba-215a-4dbc-8bcf-4fe32b95687a","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1160,-500],"parameters":{"width":640,"height":1340,"content":"# 🚀 AI-Powered Product Research & SEO Content Automation\n\nAn **AI-powered automation** that performs product research, extracts competitor insights, and generates SEO-optimized product content using Google Search and a large language model (LLM) like Google Gemini or OpenAI. The output is cleanly structured and saved into Google Sheets—ready for publishing.\n### Workflow Steps:\n1. **On form submission**  \n   *The user provides the product title via a form.*\n\n2. **Edit Fields**  \n   *The product title is prepared for the Google search query.*\n\n3. **Google Search**  \n   *A search is made on Google for competitor products and relevant information.*\n\n4. **Extract Competitor Data**  \n   *Competitor data, such as titles, descriptions, and keywords, is extracted from the search results.*\n\n5. **Basic LLM Chain**  \n   *SEO metadata and product content are generated using LangChain’s language model.*\n\n6. **Google Gemini Chat Model**  \n   *Google Gemini (PaLM) refines the generated content for quality and engagement.*\n\n7. **Code**  \n   *The content is split into SEO Meta Data and Product Content sections.*\n\n8. **Google Sheets**  \n   *All the generated content is stored in Google Sheets for easy access.*\n\n---\n\n## How This Flow Resolves Challenges:\n\n- **Automates Time-Consuming Tasks:**  \n  This workflow eliminates manual research and content writing by automating the gathering of competitor data and SEO content generation.\n  \n- **Improves SEO Outcomes:**  \n  By leveraging AI models like LangChain and Google Gemini, the workflow ensures that SEO metadata and product content are optimized for search engines.\n\n- **Efficient Organization:**  \n  The workflow splits content into clear sections and stores everything in Google Sheets, making it easy to access and manage data.\n\n- **Reduces Human Error:**  \n  Automation reduces the chances of missing important steps in content generation, ensuring consistency and accuracy.\n\n- **Centralized Data Management:**  \n  Storing everything in Google Sheets makes tracking, updating, and managing generated content straightforward and efficient.\n"},"typeVersion":1},{"id":"7f656ef7-50ce-40bd-a38b-74f3b4556311","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-240,-300],"parameters":{"height":340,"content":"### 1. **On form submission**\n- *Trigger*: Collects the product title entered by the user via the form. This is the starting point of the workflow, where the process is initiated.\n\n"},"typeVersion":1},{"id":"e6567de3-ed0d-4bcd-9f10-1e8abc374539","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[60,-300],"parameters":{"height":340,"content":"### 2. **Edit Fields**\n- *Action*: Formats the product title to fit the required query parameters for the Google search. This ensures the title is ready for the next step.\n"},"typeVersion":1},{"id":"2d75a14d-8d4b-4ea0-aad9-a3626e0caa1c","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[340,-300],"parameters":{"height":340,"content":"### 3. **Google Search**\n- *Action*: Executes a Google Custom Search API query to retrieve competitor data based on the product title. This helps in gathering insights from similar products or competitors.\n"},"typeVersion":1},{"id":"e3f73de9-6b55-45ee-aa31-b9ee4268d6fe","name":"Code Formatting","type":"n8n-nodes-base.code","position":[1340,-100],"parameters":{"jsCode":"const inputText = $json.text; // Your combined text input\n\nfunction getFieldValue(text, field) {\n  const regex = new RegExp(field + ':\\\\s*([\\\\s\\\\S]*?)(?=\\\\n\\\\S|$)', 'i');\n  const match = text.match(regex);\n  return match ? match[1].trim() : '';\n}\n\nfunction splitSections(text) {\n  // Extract sections by titles\n  const seoMetaMatch = text.match(/SEO Meta Data:\\n([\\s\\S]*?)\\n\\nProduct Content:/i);\n  const productContentMatch = text.match(/Product Content:\\n([\\s\\S]*)/i);\n\n  const seoMeta = seoMetaMatch ? seoMetaMatch[1].trim() : '';\n  const productContent = productContentMatch ? productContentMatch[1].trim() : '';\n\n  return [\n    {\n      json: {\n        type: 'seo_meta_data',\n        title: getFieldValue(seoMeta, 'Title'),\n        description: getFieldValue(seoMeta, 'Description'),\n        keywords: getFieldValue(seoMeta, 'Keywords'),\n        product_title: '',          // empty for SEO row\n        product_description: ''     // empty for SEO row\n      }\n    },\n    {\n      json: {\n        type: 'product_content',\n        title: '',                  // empty for Product row\n        description: '',\n        keywords: '',\n        product_title: getFieldValue(productContent, 'Product Title'),\n        product_description: getFieldValue(productContent, 'Product Description')\n      }\n    }\n  ];\n}\n\nreturn splitSections($input.first().json.text);\n"},"typeVersion":2},{"id":"4811155c-a560-430c-b284-0730fc10b0c7","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[620,-300],"parameters":{"height":340,"content":"### 4. **Extract Competitor Data**\n- *Action*: Extracts key information (titles, descriptions, and keywords) from the search results. This data provides valuable insights into competitor strategies and product offerings.\n"},"typeVersion":1},{"id":"1f0f8a48-2d72-4695-85c0-9e4d260da954","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[900,-300],"parameters":{"width":320,"height":340,"content":"### 5. **Basic LLM Chain**\n- *Action*: Uses LangChain’s language model to generate SEO metadata (title, description, keywords) and product content (description, title). The content is optimized for search engines.\n"},"typeVersion":1},{"id":"74c7341e-281e-4ec2-a24e-f4ea9d0df3a6","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[900,160],"parameters":{"width":260,"height":320,"content":"### 6. **Google Gemini Chat Model**\n- *Action*: Refines and improves the content generated in the previous step by using Google Gemini (PaLM) to enhance its quality and engagement.\n"},"typeVersion":1},{"id":"1dd0fee3-9c48-4748-b707-00abf0cd6475","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[1280,-300],"parameters":{"height":340,"content":"### 7. **Code Formating **\n- *Action*: Splits the generated content into two sections: SEO Meta Data and Product Content, organizing the output into clearly defined sections for easy use.\n\n"},"typeVersion":1},{"id":"7360db3c-7c8a-4a00-9bd3-a462df36df05","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[1600,-300],"parameters":{"height":340,"content":"### 8. **Google Sheets**\n- *Action*: Appends the final SEO metadata and product content into a Google Sheets document, making it easy to store, access, and track the generated information."},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"b27669ea-0c40-4b53-b972-ed79aedf17a7","connections":{"Edit Fields":{"main":[[{"node":"Google Search","type":"main","index":0}]]},"Google Search":{"main":[[{"node":"Extract Competitor Data","type":"main","index":0}]]},"Basic LLM Chain":{"main":[[{"node":"Code Formatting","type":"main","index":0}]]},"Code Formatting":{"main":[[{"node":"Google Sheets","type":"main","index":0}]]},"On form submission":{"main":[[{"node":"Edit Fields","type":"main","index":0}]]},"Extract Competitor Data":{"main":[[{"node":"Basic LLM Chain","type":"main","index":0}]]},"Google Gemini Chat Model":{"ai_languageModel":[[{"node":"Basic LLM Chain","type":"ai_languageModel","index":0}]]}}}


name: Smart Email Draft Generator
author_name: Oneclick AI Squad
author_username: oneclick-ai
nodes_used: ["n8n-nodes-base.gmail","@n8n/n8n-nodes-langchain.chainLlm","@n8n/n8n-nodes-langchain.lmOllama"]
categories: []
created_at: 2025-06-24T09:54:28.274Z
updated_at: 2025-06-24T09:54:28.274Z
url: https://n8n.io/workflows/5196
scraped_at: 2025-07-06 21:16:30
description:
  AI-Powered Email Draft Automation Workflow

  In this guide, we’ll walk you through setting up an AI-driven workflow that automatically processes incoming emails using a custom AI model (e.g., Llama), prepares email content, and saves it as a Gmail draft. Ready to automate your email drafting process? Let’s dive in!

  What’s the Goal?
  Automatically detect and process new emails via IMAP.
  Use a custom AI model to analyze and generate email content.
  Prepare structured and relevant email responses.
  Save the generated content as a Gmail draft for review or sending.
  Enable 24/7 email automation with seamless integration.

  By the end, you’ll have a self-running email assistant that drafts responses effortlessly.

  Why Does It Matter?
  Manual email drafting is time-consuming and prone to delays. Here’s why this workflow is a game changer:
  Zero Human Error:** AI ensures consistent and accurate drafts.
  Time-Saving Automation:** Instantly process and draft emails, boosting efficiency.
  24/7 Availability:** Handle emails anytime without manual intervention.
  Focus on Strategy:** Free your team from repetitive drafting tasks.

  Think of it as your tireless email drafting assistant that never misses a beat.

  How It Works
  Here’s the step-by-step magic behind the automation:

  Step 1: Trigger the Workflow
  Detect new emails using IMAP via the Check New Email (IMAP) node.
  Capture incoming email content for processing.

  Step 2: Process Email with AI
  Send the email text to a custom AI model (e.g., Llama) for analysis.
  Use the Custom AI Model node to generate a context-aware response or draft content.

  Step 3: Prepare Email Content
  Format the AI-generated content into a polished email structure using the Prepare Email Content node.
  Ensure the content is ready for drafting with proper salutations and structure.

  Step 4: Save as Gmail Draft
  Route the prepared email content to the Save as Gmail Draft node.
  Save the draft in Gmail for review or manual sending.

  Step 5: Log & Optimize
  Log all processed emails and drafts in a database (e.g., Airtable, Google Sheets).
  Continuously improve the AI model based on feedback or new email patterns.

  How to Use the Workflow?
  Importing a workflow in n8n is a straightforward process that allows you to use pre-built or shared workflows to save time. Below is a step-by-step guide to importing the Smart Email Draft Generator workflow in n8n, based on the official documentation and community resources.

  Steps to Import a Workflow in n8n

  1. Obtain the Workflow JSON
  Source the Workflow:**
    Workflows are typically shared as JSON files or code snippets. You might receive them from:
      The n8n community (e.g., n8n.io workflows page).
      A colleague or tutorial (e.g., a .json file or copied JSON code).
      Exported from another n8n instance.
  Format:** Ensure you have the workflow in JSON format, either as a file (e.g., workflow.json) or as text copied to your clipboard.

  2. Access the n8n Workflow Editor
  Log in to n8n:**
    Open your n8n instance (via n8n Cloud or your self-hosted instance).
    Navigate to the Workflows tab in the n8n dashboard.
  Open a New Workflow:**
    Click Add Workflow to create a blank workflow, or open an existing workflow if you want to merge the imported workflow.

  3. Import the Workflow
  Option 1: Import via JSON Code (Clipboard):
  In the n8n editor, click the three dots (⋯) in the top-right corner to open the menu.
  Select Import from Clipboard.
  Paste the JSON code of the workflow into the provided text box.
  Click Import to load the workflow into the editor.

  Option 2: Import via JSON File:
  In the n8n editor, click the three dots (⋯) in the top-right corner.
  Select Import from File.
  Choose the .json file from your computer.
  Click Open to import the workflow.

  Setup Notes:
  IMAP Credentials:** Configure IMAP settings in the Check New Email (IMAP) node with your email account credentials (e.g., Gmail IMAP settings).
  Custom AI Model:** Set up the Custom AI Model node with your AI model credentials (e.g., Llama API key or endpoint).
  Gmail Integration:** Authorize the Save as Gmail Draft node with Gmail API credentials to save drafts.
  Content Customization:** Adjust the Prepare Email Content node to tailor the email structure or tone as needed.

workflow_json:
  {"id":"TXzwSeIj2lNw8Pr7","meta":{"instanceId":"dd69efaf8212c74ad206700d104739d3329588a6f3f8381a46a481f34c9cc281","templateCredsSetupCompleted":true},"name":"Smart Email Draft Generator","tags":[],"nodes":[{"id":"2f4d2db0-f825-4064-b9c4-059570ca28e8","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[840,-20],"parameters":{"content":"This workflow triggers from Mail (IMAP), processes text with Basic LLM or Ollama Model, sets up an email field, and saves it as a draft."},"typeVersion":1},{"id":"8cc89e3d-ab69-4c3e-8753-ef79a105fd62","name":"Check New Email (IMAP)","type":"n8n-nodes-base.emailReadImap","position":[500,220],"parameters":{"options":{}},"credentials":{"imap":{"id":"D3nLrSlP1dHWcIDE","name":"IMAP account"}},"typeVersion":2},{"id":"d4098fe8-b946-441a-8f7d-1aada1cb6625","name":"Process Email with AI","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[700,220],"parameters":{"text":"={{ $json.textPlain }}","messages":{"messageValues":[{"message":"=this is email\n\n{{ $json.textPlain }}\n\ni need reply of this "}]},"promptType":"define"},"typeVersion":1.6},{"id":"1bb72900-6d50-449a-bf8a-49cbeb0cfc86","name":"Custom AI Model","type":"@n8n/n8n-nodes-langchain.lmOllama","position":[700,420],"parameters":{"model":"llama3.2-16000:latest","options":{}},"credentials":{"ollamaApi":{"id":"h9CEBFmYALm3FvZf","name":"Ollama account"}},"typeVersion":1},{"id":"2308c0c8-c232-4560-b120-598addd7e4c5","name":"Prepare Email Content","type":"n8n-nodes-base.set","position":[1100,220],"parameters":{"options":{},"assignments":{"assignments":[{"id":"7d428c48-4809-45d8-ba1e-c96d68c02c07","name":"from","type":"string","value":"={{ $('Check New Email (IMAP)').first().json.from }}"},{"id":"63b99545-3d2d-4563-b9d7-078cbc20dbcc","name":"subject","type":"string","value":"=Re: {{ $('Check New Email (IMAP)').first().json.subject }}"},{"id":"11d94d3f-2170-4b54-b5f9-b85bb95ad472","name":"text","type":"string","value":"={{ $json.text }} "}]}},"typeVersion":3.4},{"id":"f2c81d97-0b15-4fbb-a050-4f2750b1af9c","name":"Save as Gmail Draft","type":"n8n-nodes-base.gmail","position":[1320,220],"webhookId":"18c29d10-9bf5-4678-b6ba-c93ed6865317","parameters":{"message":"={{ $json.text }}","options":{},"subject":"={{ $json.subject }}","resource":"draft"},"credentials":{"gmailOAuth2":{"id":"by23DyfIoJ8iWfSI","name":"Gmail account"}},"typeVersion":2.1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"66359f5c-1ada-4470-bc27-4796360c2fe8","connections":{"Custom AI Model":{"ai_languageModel":[[{"node":"Process Email with AI","type":"ai_languageModel","index":0}]]},"Save as Gmail Draft":{"main":[[]]},"Prepare Email Content":{"main":[[{"node":"Save as Gmail Draft","type":"main","index":0}]]},"Process Email with AI":{"main":[[{"node":"Prepare Email Content","type":"main","index":0}]]},"Check New Email (IMAP)":{"main":[[{"node":"Process Email with AI","type":"main","index":0}]]}}}


name: Auto n8n Updater (Docker)
author_name: Lucas Peyrin
author_username: lucaspeyrin
categories: []
created_at: 2025-06-24T11:26:31.858Z
updated_at: 2025-06-24T11:26:31.858Z
url: https://n8n.io/workflows/5198
scraped_at: 2025-07-06 21:16:30
description:
  How it works

  This workflow automates the process of checking for and applying updates to a self-hosted n8n instance running on Docker. It runs on a schedule, checks for new versions, summarizes the release notes with AI, and asks for your approval via Telegram before updating.

  Scheduled Check: The workflow runs hourly, triggered by a Schedule node.
  Version Discovery:
      It first confirms it's running in a Docker environment.
      It uses SSH to connect to the host machine and inspects the running n8n container to find its current version tag (e.g., latest or next).
      It then queries the Docker Hub API to compare the image digest (a unique ID for an image version) of the running version against the latest available version for that tag.
  Update Detection: If the digests do not match, it means a new image has been pushed for your version tag (e.g., a new latest image is available), and an update is needed.
  AI-Powered Release Notes:
      It fetches the official release notes for the new version from the GitHub API.
      An AI model (LLM) summarizes these technical notes into a concise, human-readable overview of the key features and fixes.
  Manual Approval: It sends a message to a Telegram chat with the AI-generated summary and two buttons: "✅ Update" and "❌ Ignore". The workflow then pauses and waits for your response.
  Execute Update: If you approve the update, the workflow uses SSH to run a docker compose command on your server, which pulls the new image, stops the old containers, and starts the new ones.

  Set up steps

  Setup time: ~5-10 minutes

  SSH Credentials:
      Go to Credentials and create a new SSH credential with the username, host, and password/private key for the server where your n8n Docker instance is running.
      Select this credential in the Get n8n Current Version and Update Docker nodes.
  Telegram Bot Credentials:
      Create a Telegram Bot and get its API token.
      Go to Credentials and create a new Telegram credential with your bot's token.
      Select this credential in the Send a text message node.
  AI Model Credentials:
      Ensure you have credentials for an AI provider (like Google AI, OpenAI, etc.) set up.
      Select your desired credential in the Google Gemini Chat Model node (or replace it with your preferred LLM node).
  Configure Paths and Commands:
      Open the Docker Path node. Set the docker_path to the absolute path of your docker-compose.yml file on the server (e.g., /root/n8n).
      If you use workers, adjust the worker_command to include the correct --scale argument for your setup. If not, you can leave it blank.
  Set Your Chat ID:
      Open the Approve Update Telegram node and enter your personal Telegram Chat ID in the Chat ID field. This ensures the approval message is sent to you.
  Activate the workflow. It will now check for updates every hour.

  To enable fully automatic updates (without manual approval): Delete the nodes from Get n8n Releases to Approved ? and connect the Needs Update ? node directly to the Update Docker node.

nodes_used:
  ["n8n-nodes-base.httpRequest","n8n-nodes-base.telegram","@n8n/n8n-nodes-langchain.chainLlm","@n8n/n8n-nodes-langchain.lmChatGoogleGemini"]

workflow_json:
  {"meta":{"instanceId":"e409ea34548a2afe2dffba31130cd1cf2e98ebe2afaeed2a63caf2a0582d1da0","templateCredsSetupCompleted":true},"nodes":[{"id":"d4839dc7-7814-45ed-8afe-9605f212c451","name":"Docker Path","type":"n8n-nodes-base.set","position":[-1560,820],"parameters":{"options":{},"assignments":{"assignments":[{"id":"9027cc7c-e73f-4e9b-9cfc-537e038f735c","name":"docker_path","type":"string","value":"./n8n-docker-caddy"},{"id":"8ddad746-f3c9-40fa-86f9-b62c5616317b","name":"worker_command","type":"string","value":""}]}},"typeVersion":3.4},{"id":"2d99535e-e0be-42ba-a0cf-f4bb94ea2532","name":"Update Docker","type":"n8n-nodes-base.ssh","position":[1520,680],"parameters":{"cwd":"={{ $('Docker Path').last().json.docker_path }}","command":"=nohup sh -c \"docker compose pull && docker compose down && docker compose up -d {{ $('Docker Path').last().json.worker_command }}\" > update.log 2>&1 &"},"typeVersion":1},{"id":"8d113bfe-843d-4109-b6d0-c26c104e6ed9","name":"Get n8n Current Version","type":"n8n-nodes-base.ssh","position":[-1260,820],"parameters":{"cwd":"={{ $('Docker Path').last().json.docker_path }}","command":"=docker inspect $(docker ps -q --filter \"name=n8n\")"},"typeVersion":1},{"id":"dc0f16e4-5623-4dd5-84f3-8d778f75dbb4","name":"Get Instance's Settings","type":"n8n-nodes-base.httpRequest","position":[-2060,820],"parameters":{"url":"={{ $env.WEBHOOK_URL }}rest/settings","options":{}},"typeVersion":4.2},{"id":"22aedea8-ba64-430b-8eb0-77f52e43eabb","name":"Is Docker","type":"n8n-nodes-base.if","position":[-1840,820],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"loose"},"combinator":"and","conditions":[{"id":"4021cef9-daa5-448e-9df3-d38e2cafe2ed","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ $json.data.isDocker }}","rightValue":""}]},"looseTypeValidation":true},"typeVersion":2.2},{"id":"fff24986-c8bc-4766-bd42-2f565790d5db","name":"Get Version's Last Update","type":"n8n-nodes-base.httpRequest","position":[-820,820],"parameters":{"url":"=https://registry.hub.docker.com/v2/repositories/n8nio/n8n/tags/{{ $json.n8n_target_version }}","options":{}},"typeVersion":4.2},{"id":"e8f5842c-7f1e-4780-8063-36152c393a0e","name":"Target Version","type":"n8n-nodes-base.set","position":[-1040,820],"parameters":{"options":{},"assignments":{"assignments":[{"id":"3eb04423-6d04-4371-8dfe-a092996a9235","name":"n8n_target_version","type":"string","value":"={{ $json.stdout.parseJson()[0].Config.Image.replaceAll(\"docker.n8n.io/n8nio/n8n:\", \"\").trim() }}"}]}},"typeVersion":3.4},{"id":"c8134924-96ee-4cfc-ad82-2549ddd7ee63","name":"Get Current Version","type":"n8n-nodes-base.httpRequest","position":[-600,820],"parameters":{"url":"=https://registry.hub.docker.com/v2/repositories/n8nio/n8n/tags/{{ $('Get Instance\\'s Settings').last().json.data.versionCli }}","options":{}},"typeVersion":4.2},{"id":"8da1ce03-6931-4c83-b58f-676705543f92","name":"Needs Update ?","type":"n8n-nodes-base.if","position":[-380,820],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"79ba3ace-f894-438f-a8da-0616419ffff7","operator":{"type":"string","operation":"notEquals"},"leftValue":"={{ $json.digest }}","rightValue":"={{ $('Get Version\\'s Last Update').item.json.digest }}"}]}},"typeVersion":2.2},{"id":"faebf9a0-5ee2-44b4-9bd1-ab789a434cde","name":"Google Gemini Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[580,800],"parameters":{"options":{"temperature":0},"modelName":"models/gemma-3n-e4b-it"},"typeVersion":1},{"id":"a186f1fa-ac56-49fb-a302-c2895deefd3b","name":"Approved ?","type":"n8n-nodes-base.if","position":[1100,700],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"7590024e-2f4d-491f-a6c1-aa906e7aa755","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ $json.data.approved }}","rightValue":""}]}},"typeVersion":2.2},{"id":"1d03dffa-7127-4d43-9114-a1cc4cf6fa3b","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-160,160],"parameters":{"color":6,"width":1460,"height":820,"content":"## ⚠️ MANUAL APPROVAL SECTION\n\nThis entire block handles fetching release notes and waiting for your approval on Telegram.\n\n**To enable fully automatic updates**, delete all nodes in this section and connect the `Needs Update ?` node's \"true\" output directly to the `Update Docker` node."},"typeVersion":1},{"id":"a8fcb64e-bfd2-4ce7-ad05-55b0750660ed","name":"Every Hour","type":"n8n-nodes-base.scheduleTrigger","position":[-2280,820],"parameters":{"rule":{"interval":[{"field":"hours"}]}},"typeVersion":1.2},{"id":"5b886eb4-39b9-49f2-9f46-32a09638e490","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[800,500],"parameters":{"color":3,"width":260,"height":360,"content":"### 💬 APPROVAL NOTIFICATION\n\n1.  Select your **Telegram Bot** credential.\n2.  Set the **Chat ID** to your personal Telegram chat ID to receive the update notifications."},"typeVersion":1},{"id":"038321ee-1b56-4130-9cde-b2ed699a8470","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[440,340],"parameters":{"color":7,"width":340,"height":620,"content":"### 🤖 AI Release Summary\n\nThese nodes fetch the official release notes and use an AI model to create a simple, easy-to-read summary.\n\nYou can replace the Google Gemini node with any other LLM node (OpenAI, Anthropic, etc.). The prompt is designed to be robust so feel free to use a small and cheap LLM."},"typeVersion":1},{"id":"ddf276d3-fb7c-4cc9-9b38-6e054ead91ab","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[120,360],"parameters":{"color":7,"width":300,"height":380,"content":"### 🕒 Version Check\n\nThis node checks if the new version was published after the last published version checked. This prevents sending duplicate notifications for the same update, as is will only proceed if there is a later publication date."},"typeVersion":1},{"id":"bf4e80ad-ada2-4733-a6e7-7719d26c9dd0","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-140,380],"parameters":{"color":7,"height":480,"content":"### 📝 Fetch Release Notes\n\nThis node retrieves the official release notes for the new version directly from the n8n GitHub repository API.\n\nThis provides the raw content for the AI to summarize. If this node fails (e.g., due to a GitHub API issue), the workflow will still send an update notification but without the detailed summary."},"typeVersion":1},{"id":"548f86b7-b358-4bbf-b7b9-c172638be963","name":"Release Overview","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[480,580],"parameters":{"text":"=<role>\nYou are an expert technical writer and software release analyst specializing in the n8n automation platform. You have a deep understanding of the n8n user base, which ranges from non-technical business users to experienced developers. Your expertise lies in quickly parsing technical changelogs and identifying the changes that have the most significant impact on users.\n</rol>\n\n<instructions>\n<goal>\nYour goal is to analyze raw n8n release notes and extract a concise, human-readable summary of the most important changes. The summary should be easily digestible for n8n users and developers, highlighting only the key new features, critical fixes, and major enhancements.\n</goal>\n\n<context>\nThe n8n release notes are provided in a markdown-like format, typically generated from GitHub. They are structured with headings like `### Features`, `### Bug Fixes`, and `### Enhancements`.\n\nYour task is to prioritize the information based on its impact:\n1.  **Highest Priority:** New Features (especially new nodes or major core functionalities) and Breaking Changes.\n2.  **High Priority:** Significant Enhancements to existing popular nodes or core platform capabilities.\n3.  **Medium Priority:** Critical Bug Fixes, especially those related to security (XSS, authorization), data integrity, or core execution failures.\n4.  **Low Priority (to be ignored):** Minor bug fixes, documentation updates, internal refactoring, dependency updates, or changes to very niche nodes.\n\nYou must filter out the noise and focus only on what a user *needs* to know about the new version.\n</context>\n\n<examples>\n<example_1>\n<inputs>\n<release_notes>\n### [1.99.1](https://github.com/n8n-io/n8n/compare/n8n@1.99.0...n8n@1.99.1) (2025-06-19)\n\n\n### Bug Fixes\n\n* **core:** Fix pdf extract not working ([#16463](https://github.com/n8n-io/n8n/issues/16463)) ([0d69ea4](https://github.com/n8n-io/n8n/commit/0d69ea4f5bdd1216bd06ad5ae4e60eec6cc948b3))\n* **core:** Prevent unauthorised workflow termination ([#16405](https://github.com/n8n-io/n8n/issues/16405)) ([e5edc60](https://github.com/n8n-io/n8n/commit/e5edc60e344924230baafb11fa1f0af788e9ca9a))\n* **n8n Form Node:** Prevent XSS with video and source tags ([#16329](https://github.com/n8n-io/n8n/issues/16329)) ([7940384](https://github.com/n8n-io/n8n/commit/7940384a85041a1890b1203d69c092c887312500))\n</release_notes>\n</inputs>\n<output>\nThis release focuses on important security and stability fixes:\n- A critical security vulnerability (XSS) in the n8n Form Node has been patched.\n- An issue that could allow unauthorized workflow termination has been resolved.\n- The PDF extraction functionality in the core has been fixed.\n</output>\n</example_1>\n\n<example_2>\n<inputs>\n<release_notes>\n## [1.98.0](https://github.com/n8n-io/n8n/compare/n8n@1.97.2...n8n@1.98.0) (2025-06-12)\n\n\n### Features\n\n* **Airtable Trigger Node:** Add new trigger node ([#16201](https://github.com/n8n-io/n8n/issues/16201)) ([a1b2c3d](https://github.com/n8n-io/n8n/commit/a1b2c3d...))\n\n### Enhancements\n\n* **Google Sheets Node:** Add 'overwrite' option for writing data ([#16115](https://github.com/n8n-io/n8n/issues/16115)) ([e4f5g6h](https://github.com/n8n-io/n8n/commit/e4f5g6h...))\n\n### Bug Fixes\n\n* **UI:** Corrected typo in settings panel ([#16300](https://github.com/n8n-io/n8n/issues/16300)) ([i7j8k9l](https://github.com/n8n-io/n8n/commit/i7j8k9l...))\n</release_notes>\n</inputs>\n<output>\nKey highlights for this version:\n- **New Node:** A new Airtable Trigger node has been introduced, allowing workflows to start based on Airtable record changes.\n- **Google Sheets Node:** The node has been enhanced with a new 'overwrite' option when writing data to a sheet.\n</output>\n</example_2>\n\n<example_3>\n<inputs>\n<release_notes>\n## [1.97.3](https://github.com/n8n-io/n8n/compare/n8n@1.97.2...n8n@1.97.3) (2025-06-10)\n\n\n### Chores\n\n* **deps:** update dependency `some-package` to v2.5.1\n* **docs:** clarify wording in credentials page\n</release_notes>\n</inputs>\n<output>\nThis release contains minor maintenance and documentation updates.\n</output>\n</example_3>\n</examples>\n\n<output_format>\n- A short, unordered bulleted list (using `-`) or a brief paragraph.\n- Use clear, benefit-oriented language. (e.g., \"You can now...\" or \"Resolved an issue that caused...\").\n- Rephrase the technical commit messages into plain English.\n- Do not include the version number, date, GitHub issue numbers, or commit hashes in your output.\n- If there are no significant changes (e.g., only chores, docs, or minor dependency updates), you MUST output the exact phrase: `This release contains minor maintenance and documentation updates.`\n</output_format>\n</instructions>\n\n<inputs>\n<release_notes>\n{{ $json.body }}\n</release_notes>\n</inputs","batching":{},"promptType":"define"},"typeVersion":1.7},{"id":"98b2c58c-7b57-43c2-87fb-c568bcfb3dfa","name":"Approve Update","type":"n8n-nodes-base.telegram","position":[880,700],"webhookId":"d7023716-c968-44bb-b888-d20a7c6d544a","parameters":{"message":"=New n8n Version {{ $('Get n8n Github Release').item.json.name || \"\"}}\n\n{{ $('Release Overview').last().json.text }}","options":{"limitWaitTime":{"values":{"resumeUnit":"days"}},"appendAttribution":true},"operation":"sendAndWait","approvalOptions":{"values":{"approvalType":"double","approveLabel":"✅ Update","disapproveLabel":"❌ Ignore"}}},"typeVersion":1.2},{"id":"66e039dc-4338-462a-82df-07d1b1f41c1c","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-1660,540],"parameters":{"color":5,"width":300,"height":440,"content":"### ⚙️ CONFIGURE YOUR SERVER PATHS HERE\n\n*   **`docker_path`**: Set this to the **absolute path** on your server where your `docker-compose.yml` file is located.\n    *   Example: `/home/user/n8n-docker`\n*   **`worker_command`**: If you use n8n workers, set the scale command here (e.g., `--scale n8n-worker=4`). Leave blank if you don't use workers."},"typeVersion":1},{"id":"41c811b8-0b76-4937-a4e7-5c7e3f47c849","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-1340,660],"parameters":{"color":3,"width":260,"height":320,"content":"### 🔒 SSH Connection\n\nSelect your SSH credential for the server hosting your n8n instance in **both** of these nodes."},"typeVersion":1},{"id":"d9c70db1-39dc-4b62-b55e-8228a0cec23b","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[-880,640],"parameters":{"color":7,"width":660,"height":340,"content":"### 💡 How Update Detection Works\n\nThis workflow compares the unique `digest` of your running Docker image with the latest `digest` on Docker Hub for your tag (e.g., `latest`).\n\nIf they are different, an update is available."},"typeVersion":1},{"id":"5f33f467-1daa-4eef-9db1-f5dbd2d9b121","name":"Get n8n Github Release","type":"n8n-nodes-base.httpRequest","onError":"continueErrorOutput","position":[-80,700],"parameters":{"url":"=https://api.github.com/repos/n8n-io/n8n/releases/{{ $('Target Version').last().json.n8n_target_version }}","options":{}},"typeVersion":4.2},{"id":"7b066460-0897-47ea-9c45-2d7a0d3e910d","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[-2140,580],"parameters":{"color":7,"width":260,"height":400,"content":"### 🔎 Get Instance Info\n\nThis node fetches local instance settings, like the current version and whether it's running on Docker.\n\nThis step ensures the workflow only proceeds if it's on a compatible (Docker) setup. No configuration is needed here."},"typeVersion":1},{"id":"03e102d7-6c8c-4c97-86ae-4240d2b1bd3b","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[1320,240],"parameters":{"color":4,"width":520,"height":600,"content":"### 🚀 Final Step: Execute Update\n\nThis is the final action node. It connects to your server via SSH and runs the command to update your n8n Docker instance.\n\n**How it works:**\nThe command performs three key actions:\n1.  `docker compose pull`: Downloads the newest n8n image.\n2.  `docker compose down`: Safely stops your current n8n containers.\n3.  `docker compose up -d`: Starts the new containers in the background.\n\n**Important Details:**\n*   **Background Process:** It uses `nohup ... &` to run the update in the background. This is critical because it allows this workflow to finish immediately without waiting for the Docker update to complete, preventing a crash when the docker instance is stopped.\n*   **Log File:** Any output or errors from the update process are saved to a file named `update.log` in your n8n Docker directory on the server. **Check this file if you encounter issues after an update.**"},"typeVersion":1},{"id":"407c5a62-26dc-4f3c-ab4d-8ac42b89fd97","name":"New Version ?","type":"n8n-nodes-base.removeDuplicates","position":[220,580],"parameters":{"logic":"removeItemsUpToStoredDate","options":{},"operation":"removeItemsSeenInPreviousExecutions","dateDedupeValue":"={{ $json.published_at }}"},"typeVersion":2}],"pinData":{},"connections":{"Is Docker":{"main":[[{"node":"Docker Path","type":"main","index":0}]]},"Approved ?":{"main":[[{"node":"Update Docker","type":"main","index":0}]]},"Every Hour":{"main":[[{"node":"Get Instance's Settings","type":"main","index":0}]]},"Docker Path":{"main":[[{"node":"Get n8n Current Version","type":"main","index":0}]]},"New Version ?":{"main":[[{"node":"Release Overview","type":"main","index":0}]]},"Approve Update":{"main":[[{"node":"Approved ?","type":"main","index":0}]]},"Needs Update ?":{"main":[[{"node":"Get n8n Github Release","type":"main","index":0}]]},"Target Version":{"main":[[{"node":"Get Version's Last Update","type":"main","index":0}]]},"Release Overview":{"main":[[{"node":"Approve Update","type":"main","index":0}]]},"Get Current Version":{"main":[[{"node":"Needs Update ?","type":"main","index":0}]]},"Get n8n Github Release":{"main":[[{"node":"New Version ?","type":"main","index":0}],[{"node":"Approve Update","type":"main","index":0}]]},"Get Instance's Settings":{"main":[[{"node":"Is Docker","type":"main","index":0}]]},"Get n8n Current Version":{"main":[[{"node":"Target Version","type":"main","index":0}]]},"Google Gemini Chat Model":{"ai_languageModel":[[{"node":"Release Overview","type":"ai_languageModel","index":0}]]},"Get Version's Last Update":{"main":[[{"node":"Get Current Version","type":"main","index":0}]]}}}


name: E-commerce Product Fine-Tuning With Bright Data and OpenAI
author_name: Daniel Shashko
author_username: tomax
categories: []
created_at: 2025-06-24T12:51:08.885Z
updated_at: 2025-06-24T12:51:08.885Z
url: https://n8n.io/workflows/5199
scraped_at: 2025-07-06 21:16:30
description:
  This workflow contains community nodes that are only compatible with the self-hosted version of n8n. 

  This workflow automates the process of scraping product data from e-commerce websites and using it to fine-tune a custom OpenAI GPT model for generating high-quality marketing copy and product descriptions.

  Main Use Cases

  Fine-tune OpenAI models with real product data from hundreds of supported e-commerce websites for marketing content generation.
  Create custom AI models specialized in writing compelling product descriptions across different industries and platforms.
  Automate the entire pipeline from data collection to model training using Bright Data's extensive scraper library.
  Generate marketing copy using your custom-trained model via an interactive chat interface.

  How it works

  The workflow operates in two main phases: model training and model usage, organized into these stages:

  Data Collection & Processing
     Manually triggered to start the fine-tuning process.
     Uses Bright Data's web scraper to extract product information from any supported e-commerce platform (Amazon, eBay, Shopify stores, Walmart, Target, and hundreds of other websites).
     Collects product titles, brands, features, descriptions, ratings, and availability status from your chosen platform.
     Easily customizable to scrape from different websites by simply changing the dataset configuration and product URLs.

  Training Data Preparation
     A Code node processes the scraped product data to create training examples in OpenAI's required JSONL format.
     For each product, generates a complete training example with:
       System message defining the AI's role as a marketing assistant.
       User prompt containing specific product details (title, brand, features, original description snippet).
       Assistant response providing an ideal marketing description template.
     Compiles all training examples into a single JSONL file ready for OpenAI fine-tuning.

  Model Fine-Tuning
     Uploads the training file to OpenAI using the OpenAI File Upload node.
     Initiates a fine-tuning job via HTTP Request to OpenAI's fine-tuning API using the GPT-4o-mini model as the base.
     The fine-tuning process runs on OpenAI's servers to create your custom model.

  Interactive Chat Interface
     Provides a chat trigger that allows real-time interaction with your fine-tuned model.
     An AI Agent node connects to your custom-trained OpenAI model.
     Users can chat with the model to generate product descriptions, marketing copy, or other content based on the training.

  Custom Model Integration
     The OpenAI Chat Model node is configured to use your specific fine-tuned model ID.
     Delivers responses trained on your product data for consistent, high-quality marketing content.

  Summary Flow:

  Manual Trigger → Scrape E-commerce Products (Bright Data) → Process & Format Training Data (Code) → Upload Training File (OpenAI) → Start Fine-Tuning Job (HTTP Request) | Parallel: Chat Trigger → AI Agent → Custom Fine-Tuned Model Response

  Benefits:

  Fully automated pipeline from raw product data to trained AI model.
  Works with hundreds of different e-commerce websites through Bright Data's extensive scraper library.
  Creates specialized models trained on real e-commerce data for authentic marketing copy across various industries.
  Scalable solution that can be adapted to different product categories, niches, or websites.
  Interactive chat interface for immediate access to your custom-trained model.
  Cost-effective fine-tuning using OpenAI's most efficient model (GPT-4o-mini).
  Easily customizable with different websites, product URLs, training prompts, and model configurations.

  Setup Requirements:

  Bright Data API credentials for web scraping (supports hundreds of e-commerce websites).
  OpenAI API key with fine-tuning access.
  Replace placeholder credential IDs and model IDs with your actual values.
  Customize the product URLs list and Bright Data dataset for your specific website and use case.
  The workflow can be adapted for any e-commerce platform supported by Bright Data's scraping infrastructure.

nodes_used:
  ["n8n-nodes-base.httpRequest","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.openAi"]

workflow_json:
  {"meta":{"instanceId":"8212eef3ce503a3ff3b5a20b8326474820fb627fc1c3dc8486795debd39d8d25","templateCredsSetupCompleted":true},"nodes":[{"id":"93bc29f2-3004-4daa-8def-89cf9b4ad46a","name":"When clicking 'Execute workflow'","type":"n8n-nodes-base.manualTrigger","position":[0,0],"parameters":{},"typeVersion":1},{"id":"8a6e68ec-ff87-4c6b-b629-34021258a582","name":"BrightData","type":"@brightdata/n8n-nodes-brightdata.brightData","position":[220,0],"parameters":{"urls":"[\n  {\"url\":\"https://www.amazon.com/AmazonBasics-Multipurpose-Copy-Printer-Paper/dp/B01FV0F8H8/ref=zg_bs_g_office-products_d_sccl_1/142-6608713-4877828?psc=1\"},\n  {\"url\":\"https://www.amazon.com/Scotch-Shipping-Packaging-Dispenser-142-6/dp/B000J07BRQ/ref=zg_bs_g_office-products_d_sccl_2/142-6608713-4877828?psc=1\"},\n  {\"url\":\"https://www.amazon.com/Amazon-Basics-Premium-Colored-Multicolor/dp/B07D93R5HV/ref=zg_bs_g_office-products_d_sccl_3/142-6608713-4877828?psc=1\"},\n  {\"url\":\"https://www.amazon.com/HP-Cartridge-Black-3YM57AN-Tri-Color/dp/B08412PTS8/ref=zg_bs_g_office-products_d_sccl_4/142-6608713-4877828?psc=1\"},\n  {\"url\":\"https://www.amazon.com/HP-Printer-Paper-Print20-200060R/dp/B001AFL8GY/ref=zg_bs_g_office-products_d_sccl_5/142-6608713-4877828?psc=1\"},\n  {\"url\":\"https://www.amazon.com/Scotch-Shipping-Packaging-Dispenser-142L/dp/B000MVV6AA/ref=zg_bs_g_office-products_d_sccl_6/142-6608713-4877828?psc=1\"},\n  {\"url\":\"https://www.amazon.com/Amazon-Basics-50-Sheet-Legal-Inches/dp/B00QSR9URI/ref=zg_bs_g_office-products_d_sccl_7/142-6608713-4877828?psc=1\"},\n  {\"url\":\"https://www.amazon.com/Sharpie-Permanent-Markers-Resistant-Coloring/dp/B00006IFHD/ref=zg_bs_g_office-products_d_sccl_8/142-6608713-4877828?psc=1\"},\n  {\"url\":\"https://www.amazon.com/AmazonBasics-Thermal-Laminating-Plastic-Laminator/dp/B079KL4C91/ref=zg_bs_g_office-products_d_sccl_9/142-6608713-4877828?psc=1\"},\n  {\"url\":\"https://www.amazon.com/YSAGi-Leather-Protector-Non-Slip-Waterproof/dp/B0BMTPC44X/ref=zg_bs_g_office-products_d_sccl_10/142-6608713-4877828?psc=1\"},\n  {\"url\":\"https://www.amazon.com/EZlifego-Multipurpose-Removable-Transparent-Household/dp/B07VNSXY31/ref=zg_bs_g_office-products_d_sccl_11/142-6608713-4877828?psc=1\"},\n  {\"url\":\"https://www.amazon.com/BIC-Highlighter-Chisel-Assorted-5-Count/dp/B000Q5ZGIA/ref=zg_bs_g_office-products_d_sccl_12/142-6608713-4877828?psc=1\"},\n  {\"url\":\"https://www.amazon.com/Academic-Planner-2025-2026-Monthly-Calendar/dp/B0DXPSZDP9/ref=zg_bs_g_office-products_d_sccl_22/142-6608713-4877828?psc=1\"}\n]\n","resource":"webScrapper","dataset_id":{"__rl":true,"mode":"list","value":"gd_l1vijixj9g2vp7563","cachedResultName":"Amazon best seller products"},"requestOptions":{}},"credentials":{"brightdataApi":{"id":"YOUR_BRIGHTDATA_CREDENTIAL_ID","name":"BrightData account"}},"typeVersion":1},{"id":"7a817929-aa8a-4813-9fd0-e778c46ad173","name":"Code","type":"n8n-nodes-base.code","position":[440,0],"parameters":{"jsCode":"// get all incoming items\nconst allInputItems = $input.all(); \n\nlet jsonlString = \"\";\n// define the training prompt\nconst systemMessage = \"You are an expert marketing assistant specializing in writing compelling and informative product descriptions.\";\n\n// loop through each item retrieved from the input\nfor (const item of allInputItems) {\n  const product = item.json; \n\n  // validate if the product data exists and is an object\n  if (!product || typeof product !== 'object') {\n    console.warn('Skipping an item because product data is missing or not an object:', item);\n    continue;\n  }\n\n  // extract product data\n  const title = product.title || \"N/A\";\n  const brand = product.brand || \"N/A\";\n  let featuresString = \"Not specified\";\n  if (product.features && Array.isArray(product.features) && product.features.length > 0) {\n    featuresString = product.features.slice(0, 5).join(', '); \n  }\n  // create a snippet of the original product description for training\n  const originalDescSnippet = (product.description || \"No original description available.\").substring(0, 250) + \"...\";\n  // create prompt with specific details about the product\n  const userPrompt = `Generate a product description for the following item. Title: ${title}. Brand: ${brand}. Key Features: ${featuresString}. Original Description Snippet: ${originalDescSnippet}.`;\n\n  // create template for the kind of description the AI should generate\n  let idealDescription = `Discover the ${title} from ${brand}, a top-choice for discerning customers. `;\n  idealDescription += `Key highlights include: ${featuresString}. `;\n  if (product.rating) {\n    idealDescription += `Boasting an impressive customer rating of ${product.rating} out of 5 stars! `;\n  }\n  idealDescription += `This product, originally described as \"${originalDescSnippet}\", is perfect for anyone seeking quality and reliability. `;\n  idealDescription += `Don't miss out on the ${product.availability === \"In Stock\" ? \"readily available\" : \"upcoming\"} ${title} – enhance your collection today!`;\n\n  // create a training example object in the format expected by OpenAI\n  const trainingExample = {\n    messages: [\n      { role: \"system\", content: systemMessage },\n      { role: \"user\", content: userPrompt },\n      { role: \"assistant\", content: idealDescription }\n    ]\n  };\n  jsonlString += JSON.stringify(trainingExample) + \"\\n\";\n}\n\n// remove any leading or trailing whitespace\nconst fileContentString = jsonlString.trim();\n\n// check if any product data was actually processed\nif (fileContentString.length === 0) {\n  console.warn(\"No product data was processed, outputting empty file content.\");\n  return [{ \n    json: { error: \"No products processed\", fileNameToUse: \"data.jsonl\" },\n    binary: {} \n  }];\n}\n\n// convert the final JSONL string into a Buffer (raw binary data)\nconst buffer = Buffer.from(fileContentString, 'utf-8');\n// define the filename that will be used when this data is sent to OpenAI\nconst actualFileNameForOpenAI = \"data.jsonl\";\n// define the MIME type for the file\nconst mimeType = 'application/jsonl'; \n\n// prepare the binary data for output\nconst binaryData = await this.helpers.prepareBinaryData(buffer, actualFileNameForOpenAI, mimeType);\n\n// return the processed data\nreturn [{\n  json: {\n    processedFileName: actualFileNameForOpenAI \n  },\n  binary: {\n    // the \"Input Data Field Name\" in the OpenAI node\n    \"data.jsonl\": binaryData \n  }\n}];"},"typeVersion":2},{"id":"9e8f8656-79c5-4d8a-8e27-f07907ba852e","name":"OpenAI","type":"@n8n/n8n-nodes-langchain.openAi","position":[660,0],"parameters":{"options":{"purpose":"fine-tune"},"resource":"file","binaryPropertyName":"data.jsonl"},"credentials":{"openAiApi":{"id":"YOUR_OPENAI_CREDENTIAL_ID","name":"OpenAi account"}},"typeVersion":1.8},{"id":"f391f934-1804-41ad-9ad5-303c613999b6","name":"HTTP Request","type":"n8n-nodes-base.httpRequest","position":[840,0],"parameters":{"url":"https://api.openai.com/v1/fine_tuning/jobs","method":"POST","options":{},"jsonBody":"={\n  \"training_file\": \"{{ $json.id }}\",\n  \"model\": \"gpt-4o-mini-2024-07-18\"\n} ","sendBody":true,"specifyBody":"json","authentication":"predefinedCredentialType","nodeCredentialType":"openAiApi"},"credentials":{"openAiApi":{"id":"YOUR_OPENAI_CREDENTIAL_ID","name":"OpenAi account"}},"typeVersion":4.2},{"id":"add8279c-fdaf-4e6c-9b6b-242a85295cf5","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[0,200],"webhookId":"aa97eb0d-e190-40b8-aecd-f36f239f7ad1","parameters":{"options":{}},"typeVersion":1.1},{"id":"72c8af8d-45e0-4ae8-b10b-723e8bf1f61c","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[220,200],"parameters":{"options":{}},"typeVersion":2},{"id":"392b85ba-0ded-4838-ba17-df858e7f922d","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[260,420],"parameters":{"model":{"__rl":true,"mode":"id","value":"YOUR_FINE_TUNED_MODEL_ID"},"options":{"responseFormat":"text"}},"credentials":{"openAiApi":{"id":"YOUR_OPENAI_CREDENTIAL_ID","name":"OpenAi account"}},"typeVersion":1.2},{"id":"cab8fbc8-5cff-4b14-a36d-d7d89a83cf6e","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-380,-480],"parameters":{"width":280,"height":1080,"content":"This n8n workflow automates scraping Amazon product data and uses it for fine-tuning a custom OpenAI model for marketing copy.\n\n## Steps Overview\n\n1. **Manual Trigger:**  \n   The workflow starts when you click \"Execute workflow\" in n8n.\n\n2. **Bright Data Node:**  \n   Scrapes product data from a list of Amazon URLs using Bright Data's web scraper integration.\n\n3. **Code Node:**  \n   Processes the scraped product data:\n   - Generates training examples (system prompt, user prompt, assistant response) for each product.\n   - Aggregates these examples into a `.jsonl` file formatted for OpenAI fine-tuning.\n\n4. **OpenAI File Upload Node:**  \n   Uploads the `.jsonl` training file to OpenAI, declaring it for use in fine-tuning.\n\n5. **HTTP Request Node:**  \n   Starts a fine-tuning job for an OpenAI GPT model using the uploaded file.\n\n6. **Chat/Agent Subworkflow:**  \n   Contains a chat trigger and an AI agent. This uses the newly fine-tuned OpenAI model to generate product descriptions or marketing content via chat.\n\n---\n\n**Important:**  \nYou must replace the placeholder API credentials and IDs in the workflow (Bright Data API, OpenAI API, and the fine-tuned model ID in the agent node) with your own valid keys and model identifiers for the workflow to function correctly.\n"},"typeVersion":1}],"pinData":{},"connections":{"Code":{"main":[[{"node":"OpenAI","type":"main","index":0}]]},"OpenAI":{"main":[[{"node":"HTTP Request","type":"main","index":0}]]},"BrightData":{"main":[[{"node":"Code","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"When chat message received":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"When clicking 'Execute workflow'":{"main":[[{"node":"BrightData","type":"main","index":0}]]}}}


name: AI-Powered One-Click Virtual Fitting Room for WooCommerce, Shopify, Prestashop
author_name: Davide
author_username: n3witalia
nodes_used: ["n8n-nodes-base.httpRequest","n8n-nodes-base.ftp"]
categories: []
created_at: 2025-06-24T13:03:34.717Z
updated_at: 2025-06-24T13:03:34.717Z
url: https://n8n.io/workflows/5200
scraped_at: 2025-07-06 21:16:30
description:
  This low-code automation enables all eCommerce store visitors to upload a photo of themselves and virtually “try on” a garment in just a few clicks. 

  With this workflow, WooCommerce, Prestashop, Shopify and more merchants can offer a cutting-edge “virtual try-on” feature with minimal development effort, enhancing customer engagement and reducing product returns.

  Key Advantages

  Zero-Coding, Visual Setup**
    Build end-to-end e-commerce features with drag-and-drop nodes instead of custom backend code.

  Asynchronous, Scalable Processing**
    Non-blocking “Wait” + “If” loop handles multi-second AI jobs gracefully, freeing up the workflow for other tasks.

  Dynamic Inputs & URLs**
    Query strings (e.g. ?Product=IMAGE_URL) allow you to embed the form on any product page and pass the garment image on the fly.

  Seamless User Experience**
    Instant pop-up within your storefront and automatic redirect to the generated mock-up keeps shoppers engaged without page reloads.


  Easy Credential Management**
    API keys, FTP credentials, and webhook IDs are all stored securely in n8n’s credential manager.

  How It Works  
  Form Submission:  
     A user submits a form with their name, an image of themselves ("Me"), and a hidden product image URL ("Product").  
     The form is triggered via the On form submission node, which collects the input data.  

  Image Upload:  
     The uploaded image ("Me") is sent to an FTP server for temporary storage using the FTP node. The filename includes a timestamp to ensure uniqueness.  

  Virtual Try-on Request:  
     The Create Image node sends a POST request to the Fal.run API, providing:  
       The uploaded human image URL (from FTP).  
       The product image URL (from the hidden form field).  
     This generates a virtual try-on result.  

  Result Processing:  
     The workflow checks the status of the image generation (Get status node) in a loop (with a 10-second wait between checks) until it is marked as "COMPLETED."  
     Once ready, the final image URL is fetched (Get Url image node) and displayed to the user via a redirect (Form node).  

  User Experience:  
     The user is redirected to the generated try-on image, completing the process.  

  Set Up Steps  
  API Key Setup:  
     Create an account and obtain an API key.  
     Configure the Create Image node with HTTP Header Authentication:  
       Name: Authorization  
       Value: Key YOURAPIKEY  

  FTP/S3 Configuration:  
     Set up an FTP server or S3 bucket to temporarily store uploaded user images.  
     Configure the FTP node with your FTP credentials and storage path.  

  Ecommerce Integration:  
     On your WooCommerce site, add a "Try On" button that opens the form in a pop-up.  
     Dynamically pass the product image URL as a query parameter:  
       Example: https://URL_N8N/form/ca1c314d-46c6-4eeb-b6a5-359XXXXXX?Product=IMAGE_URL  

  Testing:  
     Verify the workflow by submitting a test form and ensuring the virtual try-on image is generated and displayed correctly.  

  Need help customizing?  
  Contact me for consulting and support or add me on Linkedin. 

workflow_json:
  {"id":"bnkWL5ReJLmi9DKA","meta":{"instanceId":"a4bfc93e975ca233ac45ed7c9227d84cf5a2329310525917adaf3312e10d5462","templateCredsSetupCompleted":true},"name":"Form Visual Try-on for Ecommerce webiste","tags":[],"nodes":[{"id":"ec6c9aa4-aa67-4f76-bda5-2d8368995993","name":"On form submission","type":"n8n-nodes-base.formTrigger","position":[-680,200],"webhookId":"ca1c314d-46c6-4eeb-b6a5-359de7601906","parameters":{"options":{"appendAttribution":false},"formTitle":"Virtual Try On","formFields":{"values":[{"fieldLabel":"Nome","placeholder":"Nome","requiredField":true},{"fieldName":"Product","fieldType":"hiddenField"},{"fieldType":"file","fieldLabel":"Me","requiredField":true,"acceptFileTypes":".jpg,.png"}]},"formDescription":"Upload your image and virtually try on the dress"},"typeVersion":2.2},{"id":"12941dfe-2c91-4270-87a4-510f83c7aa65","name":"FTP","type":"n8n-nodes-base.ftp","position":[-420,200],"parameters":{"path":"=/eolianpenthouse.dev.eureweb.it/test/{{$now.format('yyyyyyLLddHHii')}}-{{ $json.Me[0].filename }}","operation":"upload","binaryPropertyName":"Me"},"credentials":{"ftp":{"id":"VRMB0CWVo86cIM26","name":"FTP account (Eolian DEV)"}},"typeVersion":1},{"id":"d5524925-4d2d-4c95-9efc-c877004e65b0","name":"Get Url image","type":"n8n-nodes-base.httpRequest","position":[-680,460],"parameters":{"url":"=https://queue.fal.run/fal-ai/kling/requests/{{ $json.request_id }}","options":{},"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"daOZafXpRXLtoLUV","name":"Fal.run API"}},"typeVersion":4.2},{"id":"87300ee2-366e-469b-85bf-9dbd1d5de850","name":"Get status","type":"n8n-nodes-base.httpRequest","position":[240,200],"parameters":{"url":"=https://queue.fal.run/fal-ai/kling/requests/{{ $('Create Image').item.json.request_id }}/status ","options":{},"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"daOZafXpRXLtoLUV","name":"Fal.run API"}},"typeVersion":4.2},{"id":"8db4508e-b82a-4134-85c7-44b2162d5da6","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-300,-980],"parameters":{"color":6,"width":340,"height":540,"content":"## Me\n![image](https://n3wstorage.b-cdn.net/n3witalia/model.jpg)"},"typeVersion":1},{"id":"f4765a45-0ad4-49d6-8227-9cc3e050b429","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-700,-980],"parameters":{"color":6,"width":360,"height":540,"content":"## Product\n![image](https://n3wstorage.b-cdn.net/n3witalia/tshirt.jpg)"},"typeVersion":1},{"id":"79a6158d-fb3c-4293-82cc-e344aa21db37","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[80,-980],"parameters":{"color":4,"width":340,"height":540,"content":"## Result\n![image](https://n3wstorage.b-cdn.net/n3witalia/result.png)"},"typeVersion":1},{"id":"032557a3-1ced-47d3-8e72-b1e3057d9e46","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-700,-1260],"parameters":{"color":3,"width":740,"height":240,"content":"# Functionality\n\nThis low-code automation enables all eCommerce store visitors to upload a **photo of themselves and virtually “try on”** a garment in just a few clicks. \n\nWith this workflow, **WooCommerce, Prestashop, Shopify** and more merchants can offer a cutting-edge “virtual try-on” feature with minimal development effort, enhancing customer engagement and reducing product returns.\n\n"},"typeVersion":1},{"id":"6a740b21-b95f-4c8e-bb92-c205e52e3925","name":"Completed?","type":"n8n-nodes-base.if","position":[420,200],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"383d112e-2cc6-4dd4-8985-f09ce0bd1781","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"COMPLETED"}]}},"typeVersion":2.2},{"id":"f33040d8-cbac-4c21-845b-10397c5210cc","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-700,-80],"parameters":{"width":740,"height":180,"content":"## STEP 3  - ECOMMERCE\nIn production environment, the \"Product\" field must be dynamically filled with the url of the product dress image (e.g. https://n3wstorage.b-cdn.net/n3witalia/camicia-seta.png).\n\nOn the ecommerce, create a \"Try On\" button and the following url to open in pop-up format https://URL_N8N/form/ca1c314d-46c6-4eeb-b6a5-359XXXXXX?Product=IMAGE_URL"},"typeVersion":1},{"id":"0799d997-c38e-4c84-8096-0f2ef04b0223","name":"Create Image","type":"n8n-nodes-base.httpRequest","position":[-180,200],"parameters":{"url":"https://queue.fal.run/fal-ai/kling/v1-5/kolors-virtual-try-on","method":"POST","options":{},"jsonBody":"={\n  \"human_image_url\": \"https://eolianpenthouse.dev.eureweb.it/test/{{$now.format('yyyyyyLLddHHii')}}-{{ $json.Me[0].filename }}\",\n  \"garment_image_url\": \"{{ $('On form submission').item.json.Product }}\"\n} ","sendBody":true,"sendHeaders":true,"specifyBody":"json","authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","headerParameters":{"parameters":[{"name":"Content-Type","value":"application/json"}]}},"credentials":{"httpHeaderAuth":{"id":"daOZafXpRXLtoLUV","name":"Fal.run API"}},"typeVersion":4.2},{"id":"63e29ad5-5965-4a2c-98f5-bc89124a6b21","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-700,-400],"parameters":{"width":740,"height":140,"content":"## STEP 1 - GET API KEY (YOURAPIKEY)\nCreate an account [here](https://fal.ai/) and obtain API KEY.\nIn the node \"Create Image\" set \"Header Auth\" and set:\n- Name: \"Authorization\"\n- Value: \"Key YOURAPIKEY\""},"typeVersion":1},{"id":"67188445-73c4-4070-b1f8-6e21beb3e1fa","name":"Form","type":"n8n-nodes-base.form","position":[-240,460],"webhookId":"69559b3a-3175-4864-8e41-2892eaa80d8e","parameters":{"operation":"completion","redirectUrl":"={{ $json.image.url }}","respondWith":"redirect"},"typeVersion":1},{"id":"1a65532e-abb9-4c3f-99c3-ddf35e7ed5e4","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[-700,-220],"parameters":{"width":740,"height":100,"content":"## STEP 2  - FTP\nFTP space or S3 bucket to temporarily upload your image to"},"typeVersion":1},{"id":"cf2e4f76-e658-4aa3-a6c0-9a85bb1749e6","name":"Get image","type":"n8n-nodes-base.httpRequest","position":[-460,460],"parameters":{"url":"={{ $json.image.url }}","options":{}},"typeVersion":4.2},{"id":"04573589-8467-4768-9451-177aa2d19f57","name":"Wait 10 sec.","type":"n8n-nodes-base.wait","position":[60,200],"webhookId":"351bd496-a9cc-445c-86f6-a56189df0028","parameters":{"amount":10},"typeVersion":1.1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"c42ea134-5e24-4e45-9a6b-0f0765c4c13c","connections":{"FTP":{"main":[[{"node":"Create Image","type":"main","index":0}]]},"Form":{"main":[[]]},"Get image":{"main":[[{"node":"Form","type":"main","index":0}]]},"Completed?":{"main":[[{"node":"Get Url image","type":"main","index":0}],[{"node":"Wait 10 sec.","type":"main","index":0}]]},"Get status":{"main":[[{"node":"Completed?","type":"main","index":0}]]},"Create Image":{"main":[[{"node":"Wait 10 sec.","type":"main","index":0}]]},"Wait 10 sec.":{"main":[[{"node":"Get status","type":"main","index":0}]]},"Get Url image":{"main":[[{"node":"Get image","type":"main","index":0}]]},"On form submission":{"main":[[{"node":"FTP","type":"main","index":0}]]}}}


name: WhatsApp Expense Tracker with Multi-Input (Text, Image & Audio)
author_name: Roshan Ramani
author_username: rawsun007
categories: []
created_at: 2025-06-24T13:22:01.168Z
updated_at: 2025-06-24T13:22:01.168Z
url: https://n8n.io/workflows/5201
scraped_at: 2025-07-06 21:16:30
description:
  Description
  CashMate – Your AI-Powered WhatsApp Finance Agent  
  Turn WhatsApp into a smart finance assistant that auto-registers you, logs transactions in natural language, extracts data from receipts and voice notes, and delivers instant report summaries—no apps, no charts, just lightning-fast insights in chat.

  Who is this for?
  Personal finance enthusiasts wanting effortless expense tracking  
  Freelancers & solopreneurs juggling multiple incomes and expenses  
  Small business owners needing quick bookkeeping on the go  
  Busy professionals who prefer messaging over apps  
  Privacy-minded users who host data on their own PostgreSQL  

  What problem does this solve?
  Zero onboarding friction: Just send "Hi"—no forms, no sign-ups  
  No app switching: Track everything right inside WhatsApp  
  Manual entry eliminated: Natural-language, image, and voice input all auto-parsed  
  Instant summaries: On-demand report requests—no dashboards to navigate  

  How it works
  Auto-Registration
  New users: "Hi" → Creates your profile in PostgreSQL  
  Returning users: Bypasses creation if your number already exists  

  Intent Classification routes every message into one of five branches:
  Reports & Summaries
  Triggers on keywords like "today's report," "show May vs June," or "summary."  
  Returns concise text summary of income, expenses, and net balance.  

  Natural-Language Transactions
  Messages like "Give 200 to Mukesh for car repair" → AI extracts date, category, amount, payee → logs it.  

  Receipt OCR
  Attach a receipt image → Gemini OCR node reads line-items → AI categorizes and logs.  

  Voice-Driven Logging
  Send a voice note → Deepgram node transcribes → AI logs transaction.  

  General Chat & Greetings
  "Hi," "Hello," or casual finance questions → Routed to chat branch for greetings or tips.  

  Setup
  Prerequisites
  n8n instance (self-hosted or n8n.cloud, v1.0+)  
  WhatsApp Business Cloud API credentials  
  PostgreSQL database (host, port, user, password)  
  OpenRouter/OpenAI API key for NLP  
  Gemini API key for OCR  
  Deepgram API key for voice transcription  

  Quick Start
  Import CashMate.n8n.json into n8n.  
  Rename nodes to suit your environment.  
  Configure Credentials in n8n's Credentials section—avoid hard-coding keys.  
  Activate workflow and message "Hi" from WhatsApp.  
  Test by sending a sample expense text, image receipt, or voice note.  

  &gt; Note: All detailed setup instructions and deep configuration steps are provided in the sticky notes within the template.  

  How to Customize
  Categories & Currencies:** Edit parsing logic in the Function nodes.  
  AI Models:** Swap OpenAI/OpenRouter for GPT-4, Claude, or self-hosted alternatives.  
  Multi-User Support:** Extend registration logic to tag team or family accounts.  
  Additional Features:** Add budget alerts, multi-currency support, or bank integrations via Plaid.  

  Example Interactions
  1. Text Transaction
  User: 300 given to James for the coffee  
  CashMate: ✅ Transaction Added:
     • Date:          2025-06-24  
     • Category:      Coffee & Beverages  
     • Type:          Expense  
     • Amount:        ₹300.00  
     • Counterparty:  James

  2. Receipt Image (OCR)

  User: [sends image of café bill totaling ₹450]  
  CashMate: ✅ Transaction Added:
     • Date:          2025-06-24  
     • Category:      Coffee & Beverages  
     • Type:          Expense  
     • Amount:        ₹450.00  
     • Counterparty:  Café Aroma

  3. Voice Transaction
  User: [voice note: "Paid 650 rupees for office stationery"]  
  CashMate: ✅ Transaction Added:
     • Date:          2025-06-24  
     • Category:      Office Supplies  
     • Type:          Expense  
     • Amount:        ₹650.00  
     • Counterparty:  (none)

  `

nodes_used:
  ["n8n-nodes-base.httpRequest","n8n-nodes-base.postgres","n8n-nodes-base.whatsApp","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.outputParserStructured","@n8n/n8n-nodes-langchain.toolCalculator","@n8n/n8n-nodes-langchain.toolCode"]

workflow_json:
  {"id":"lD64El4ZjpXClZfJ","meta":{"instanceId":"51d1d0f94f0eb0d5e1f0abca36cf726ede396d46d8ae921dfe4272fca1637d49","templateCredsSetupCompleted":true},"name":"WhatsApp Financial Agent: Handles Text, Images & Audio","tags":[],"nodes":[{"id":"57dc8c80-7eac-4c5c-a2b5-dd8b6257b23b","name":"Date and time","type":"@n8n/n8n-nodes-langchain.toolCode","position":[-580,500],"parameters":{},"typeVersion":1.2},{"id":"2fb03ef5-bf65-4193-b6c4-8e347ade4065","name":"Structured Output Parser","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[-460,500],"parameters":{},"typeVersion":1.2},{"id":"0e8e6e89-8ecd-4fd4-acf9-51072555bdfb","name":"Calculator","type":"@n8n/n8n-nodes-langchain.toolCalculator","position":[-20,60],"parameters":{},"typeVersion":1},{"id":"1395263a-c11c-41b2-b4bb-7235ca4839b2","name":"Convert to File","type":"n8n-nodes-base.convertToFile","position":[-460,-160],"parameters":{},"typeVersion":1.1},{"id":"93f6a3da-17bf-4896-b9b0-0baa53532fc9","name":"Normal Conversation ","type":"n8n-nodes-base.whatsApp","position":[-1080,2340],"webhookId":"f71b40d3-80fc-49d5-85f9-bdac44343b7a","parameters":{},"typeVersion":1},{"id":"465e1083-d2b8-4099-a3cb-8b9c35e259ef","name":"Message Intent Classifier","type":"@n8n/n8n-nodes-langchain.agent","position":[-2260,1040],"parameters":{},"typeVersion":1.9},{"id":"c5bd26e9-d37d-46cb-812b-37e39c93def5","name":"Route by Intent","type":"n8n-nodes-base.switch","position":[-1884,998],"parameters":{},"typeVersion":3.2},{"id":"9f2dc65d-ff12-48bc-847e-296aaf7b6d07","name":"Parse & Validate Transaction","type":"@n8n/n8n-nodes-langchain.agent","position":[-660,280],"parameters":{},"typeVersion":1.9},{"id":"acde8129-25e9-48da-bf74-198089a9e647","name":"Build Custom Report Query","type":"@n8n/n8n-nodes-langchain.agent","position":[-1620,-160],"parameters":{},"typeVersion":1.9},{"id":"0444d98a-2988-401e-857a-33b40edb24bf","name":"Transform Custom Query for Postgres","type":"n8n-nodes-base.code","position":[-1240,-160],"parameters":{},"typeVersion":2},{"id":"fc40f501-8b48-49bc-b624-4e7775990333","name":"Format Custom Query Results","type":"n8n-nodes-base.code","position":[-800,-160],"parameters":{},"executeOnce":false,"typeVersion":2,"alwaysOutputData":true},{"id":"02a8ae3b-a2af-4274-baeb-3a0662600293","name":"Execute Custom Report Query","type":"n8n-nodes-base.postgres","position":[-1020,-160],"parameters":{},"typeVersion":2.6,"alwaysOutputData":true},{"id":"24a115f7-22d0-4e0a-8c45-653da2fa064e","name":"Build Custom Financial Summary","type":"@n8n/n8n-nodes-langchain.agent","position":[-100,-160],"parameters":{},"executeOnce":true,"typeVersion":1.9},{"id":"5643dd90-687f-4a2f-a50e-ac4a3089c2a4","name":"Send Custom Report","type":"n8n-nodes-base.whatsApp","position":[300,-160],"webhookId":"f71b40d3-80fc-49d5-85f9-bdac44343b7a","parameters":{},"typeVersion":1},{"id":"25829e7c-2726-4bf1-8adc-e562d094d929","name":"simple conversation ","type":"@n8n/n8n-nodes-langchain.agent","position":[-1460,2340],"parameters":{},"typeVersion":1.9},{"id":"ced786a9-840f-4c18-9993-c51754483604","name":"Date and time1","type":"@n8n/n8n-nodes-langchain.toolCode","position":[-1460,60],"parameters":{},"typeVersion":1.2},{"id":"8548dfa1-2c19-4e41-b4bb-cc1daebe810b","name":"Date and time2","type":"@n8n/n8n-nodes-langchain.toolCode","position":[100,60],"parameters":{},"typeVersion":1.2},{"id":"e9fd4787-d5f4-4ee0-9aca-b571c82d23ce","name":"Date and time4","type":"@n8n/n8n-nodes-langchain.toolCode","position":[-2112,1260],"parameters":{},"typeVersion":1.2},{"id":"12c1d2d7-5a7b-48dc-a8b3-e75b3d484670","name":"Date and time5","type":"@n8n/n8n-nodes-langchain.toolCode","disabled":true,"position":[-1320,2560],"parameters":{},"typeVersion":1.2},{"id":"7b9cf4fb-352e-458d-b5ad-792558ae08ea","name":"Transform image to base64","type":"n8n-nodes-base.extractFromFile","position":[-1068,1040],"parameters":{},"typeVersion":1},{"id":"b9b949e6-7912-4cf8-8f72-87825162b2b6","name":"Date and time6","type":"@n8n/n8n-nodes-langchain.toolCode","position":[-508,1160],"parameters":{},"typeVersion":1.2},{"id":"fd7a47b0-48da-4044-a548-3508d19ea5a3","name":"Send Financial Response1","type":"n8n-nodes-base.whatsApp","position":[1840,1020],"webhookId":"f71b40d3-80fc-49d5-85f9-bdac44343b7a","parameters":{},"executeOnce":true,"typeVersion":1},{"id":"7b53faf2-92d8-480c-91fd-89805f825cd6","name":"Format Transaction JSON1","type":"n8n-nodes-base.code","position":[800,1020],"parameters":{},"typeVersion":2},{"id":"3d6d765c-4a90-49ff-9ac6-e631419d61ee","name":"Validate Transaction Fields1","type":"n8n-nodes-base.code","position":[1020,1020],"parameters":{},"typeVersion":2},{"id":"c1afdf5f-4860-4697-a110-1af63843c5cb","name":"Insert Transaction into DB1","type":"n8n-nodes-base.postgres","position":[1240,1020],"parameters":{},"typeVersion":2.6},{"id":"43758734-53db-4ecd-8ddd-cb6ed2850a68","name":"Build Confirmation Message1","type":"@n8n/n8n-nodes-langchain.agent","position":[1460,1020],"parameters":{},"executeOnce":true,"typeVersion":1.9},{"id":"d818d14c-39f2-48c6-b7cd-fb523ac4b2b5","name":"Date and time7","type":"@n8n/n8n-nodes-langchain.toolCode","position":[1600,1240],"parameters":{},"typeVersion":1.2},{"id":"6fcbea28-acc4-420e-a72c-e2a1d42258db","name":"Structured Output Parser1","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[-388,1160],"parameters":{},"typeVersion":1.2},{"id":"4164a862-874c-4b93-9aa8-52a223ce95bb","name":"Date and time8","type":"@n8n/n8n-nodes-langchain.toolCode","position":[-360,1960],"parameters":{},"typeVersion":1.2},{"id":"fafedbd3-eb09-40ac-8ca7-ac1b30a9746c","name":"Structured Output Parser3","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[-240,1960],"parameters":{},"typeVersion":1.2},{"id":"7e839522-d4ff-4f21-b94e-0875bbc15e40","name":"Incoming WhatsApp Trigger","type":"n8n-nodes-base.whatsAppTrigger","position":[-3360,1040],"webhookId":"c9f59683-0d8a-474e-add3-d07c8fa53c94","parameters":{},"typeVersion":1},{"id":"f6a6b324-53a8-40f9-a35b-6b73c6b3fde2","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-140,60],"parameters":{},"typeVersion":1.2},{"id":"a60357ae-9439-44ac-a09a-2082a92455c9","name":"OpenAI Chat Model1","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[1480,1240],"parameters":{},"typeVersion":1.2},{"id":"bb041356-6d13-47ae-9270-1b0f9f64a762","name":"OpenAI Chat Model2","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-628,1160],"parameters":{},"typeVersion":1.2},{"id":"cac16e35-a3c3-4468-af44-8509472ac366","name":"OpenAI Chat Model3","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-480,1960],"parameters":{},"typeVersion":1.2},{"id":"1d898519-7c23-4de7-abd4-8baad0f7e1b6","name":"OpenAI Chat Model4","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-1440,2560],"parameters":{},"typeVersion":1.2},{"id":"cd5fc5d3-5cbc-4448-aa4e-c76ae51b9f96","name":"OpenAI Chat Model5","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-2232,1260],"parameters":{},"typeVersion":1.2},{"id":"f6287282-5e70-4ce7-bde5-db56e7d606f5","name":"OpenAI Chat Model6","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-1580,60],"parameters":{},"typeVersion":1.2},{"id":"9e001c7c-965f-446a-99d1-a420bb9fd514","name":"OpenAI Chat Model7","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-700,500],"parameters":{},"typeVersion":1.2},{"id":"4a67c108-4606-4478-a77a-b4fbb1918671","name":"Check Message Type","type":"n8n-nodes-base.if","position":[-3140,1040],"parameters":{},"typeVersion":2.2},{"id":"459b1564-0d8f-4e72-825b-c73efc151fc1","name":"Fetch User Profile from Postgres","type":"n8n-nodes-base.postgres","position":[-2920,1040],"parameters":{},"typeVersion":2.6,"alwaysOutputData":true},{"id":"f3f08eac-1296-4ce6-98be-5c3664ad2e0f","name":"Create New User","type":"n8n-nodes-base.postgres","position":[-2480,965],"parameters":{},"typeVersion":2.6},{"id":"8784aa11-8f13-4312-9a4e-1039a796ac03","name":"Check user Exists or not","type":"n8n-nodes-base.if","position":[-2700,1040],"parameters":{},"typeVersion":2.2},{"id":"dbabce46-b07c-47c5-b385-83027cde694d","name":"Create Image Download link ","type":"n8n-nodes-base.whatsApp","position":[-1586,1040],"webhookId":"0572f94a-ca8a-4f15-86cd-3b88c2e0fb6e","parameters":{},"typeVersion":1},{"id":"06f6129a-d307-40d3-bcf2-20b23fb9ae03","name":"Download Image","type":"n8n-nodes-base.httpRequest","position":[-1288,1040],"parameters":{},"typeVersion":4.2},{"id":"c1df6e4e-8ebc-41f1-a67d-11e1614a7032","name":"Run OCR on Image (Gemini API)","type":"n8n-nodes-base.httpRequest","position":[-848,1040],"parameters":{},"typeVersion":4.2},{"id":"2bc9b43a-c69f-49c3-8ba1-35453ffe400d","name":"Parse & Validate Transaction (Receipts & Bills)","type":"@n8n/n8n-nodes-langchain.agent","position":[-596,940],"parameters":{},"typeVersion":1.9},{"id":"1ea09f8b-9c99-4f95-83fe-f714fc8a6930","name":"Create Audio Download link ","type":"n8n-nodes-base.whatsApp","position":[-1140,1740],"webhookId":"0572f94a-ca8a-4f15-86cd-3b88c2e0fb6e","parameters":{},"typeVersion":1},{"id":"2dcb60bc-e934-4f0b-b74f-186d9572fb72","name":"Download Audio","type":"n8n-nodes-base.httpRequest","position":[-920,1740],"parameters":{},"typeVersion":4.2},{"id":"0a7a8f23-7c62-47e1-bf7c-6f5934576a0a","name":"Split Transaction Lines","type":"n8n-nodes-base.splitOut","position":[480,1020],"parameters":{},"typeVersion":1},{"id":"72cff440-c080-437e-8625-54d884c6e787","name":"Parse & Validate Transaction(Audio Transcribe)","type":"@n8n/n8n-nodes-langchain.agent","position":[-440,1740],"parameters":{},"typeVersion":1.9},{"id":"fc6392df-851f-45b3-ba85-7b455ee87100","name":"Transcribe Audio by deepgram ","type":"n8n-nodes-base.httpRequest","position":[-700,1740],"parameters":{},"typeVersion":4.2},{"id":"fb27211b-f000-4e55-8d07-f33e5b83fc68","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-4200,-160],"parameters":{"content":""},"typeVersion":1},{"id":"b1170a4a-8224-4b8d-b99b-926b4f1d3396","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-2160,-240],"parameters":{"content":""},"typeVersion":1},{"id":"d4c3c962-c3dc-4af2-a96b-283f2ce162e6","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-2240,2300],"parameters":{"content":""},"typeVersion":1},{"id":"9f08ab18-caab-4b20-98cf-9c999a55cbf3","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[820,-140],"parameters":{"content":""},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"23bccf93-d08e-479d-a0b3-d290c4f5fb90","connections":{"Calculator":{"ai_tool":[[{"node":"Build Custom Financial Summary","type":"ai_tool","index":0}]]},"Date and time":{"ai_tool":[[{"node":"Parse & Validate Transaction","type":"ai_tool","index":0}]]},"Date and time1":{"ai_tool":[[{"node":"Build Custom Report Query","type":"ai_tool","index":0}]]},"Date and time2":{"ai_tool":[[{"node":"Build Custom Financial Summary","type":"ai_tool","index":0}]]},"Date and time4":{"ai_tool":[[{"node":"Message Intent Classifier","type":"ai_tool","index":0}]]},"Date and time5":{"ai_tool":[[{"node":"simple conversation ","type":"ai_tool","index":0}]]},"Date and time6":{"ai_tool":[[{"node":"Parse & Validate Transaction (Receipts & Bills)","type":"ai_tool","index":0}]]},"Date and time7":{"ai_tool":[[{"node":"Build Confirmation Message1","type":"ai_tool","index":0}]]},"Date and time8":{"ai_tool":[[{"node":"Parse & Validate Transaction(Audio Transcribe)","type":"ai_tool","index":0}]]},"Download Audio":{"main":[[{"node":"Transcribe Audio by deepgram ","type":"main","index":0}]]},"Download Image":{"main":[[{"node":"Transform image to base64","type":"main","index":0}]]},"Convert to File":{"main":[[{"node":"Build Custom Financial Summary","type":"main","index":0}]]},"Create New User":{"main":[[{"node":"Message Intent Classifier","type":"main","index":0}]]},"Route by Intent":{"main":[[{"node":"Build Custom Report Query","type":"main","index":0}],[{"node":"Parse & Validate Transaction","type":"main","index":0}],[{"node":"Create Image Download link ","type":"main","index":0}],[{"node":"Create Audio Download link ","type":"main","index":0}],[{"node":"simple conversation ","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"Build Custom Financial Summary","type":"ai_languageModel","index":0}]]},"Check Message Type":{"main":[[{"node":"Fetch User Profile from Postgres","type":"main","index":0}]]},"OpenAI Chat Model1":{"ai_languageModel":[[{"node":"Build Confirmation Message1","type":"ai_languageModel","index":0}]]},"OpenAI Chat Model2":{"ai_languageModel":[[{"node":"Parse & Validate Transaction (Receipts & Bills)","type":"ai_languageModel","index":0}]]},"OpenAI Chat Model3":{"ai_languageModel":[[{"node":"Parse & Validate Transaction(Audio Transcribe)","type":"ai_languageModel","index":0}]]},"OpenAI Chat Model4":{"ai_languageModel":[[{"node":"simple conversation ","type":"ai_languageModel","index":0}]]},"OpenAI Chat Model5":{"ai_languageModel":[[{"node":"Message Intent Classifier","type":"ai_languageModel","index":0}]]},"OpenAI Chat Model6":{"ai_languageModel":[[{"node":"Build Custom Report Query","type":"ai_languageModel","index":0}]]},"OpenAI Chat Model7":{"ai_languageModel":[[{"node":"Parse & Validate Transaction","type":"ai_languageModel","index":0}]]},"simple conversation ":{"main":[[{"node":"Normal Conversation ","type":"main","index":0}]]},"Split Transaction Lines":{"main":[[{"node":"Format Transaction JSON1","type":"main","index":0}]]},"Check user Exists or not":{"main":[[{"node":"Create New User","type":"main","index":0}],[{"node":"Message Intent Classifier","type":"main","index":0}]]},"Format Transaction JSON1":{"main":[[{"node":"Validate Transaction Fields1","type":"main","index":0}]]},"Structured Output Parser":{"ai_outputParser":[[{"node":"Parse & Validate Transaction","type":"ai_outputParser","index":0}]]},"Build Custom Report Query":{"main":[[{"node":"Transform Custom Query for Postgres","type":"main","index":0}]]},"Incoming WhatsApp Trigger":{"main":[[{"node":"Check Message Type","type":"main","index":0}]]},"Message Intent Classifier":{"main":[[{"node":"Route by Intent","type":"main","index":0}]]},"Structured Output Parser1":{"ai_outputParser":[[{"node":"Parse & Validate Transaction (Receipts & Bills)","type":"ai_outputParser","index":0}]]},"Structured Output Parser3":{"ai_outputParser":[[{"node":"Parse & Validate Transaction(Audio Transcribe)","type":"ai_outputParser","index":0}]]},"Transform image to base64":{"main":[[{"node":"Run OCR on Image (Gemini API)","type":"main","index":0}]]},"Build Confirmation Message1":{"main":[[{"node":"Send Financial Response1","type":"main","index":0}]]},"Create Audio Download link ":{"main":[[{"node":"Download Audio","type":"main","index":0}]]},"Create Image Download link ":{"main":[[{"node":"Download Image","type":"main","index":0}]]},"Execute Custom Report Query":{"main":[[{"node":"Format Custom Query Results","type":"main","index":0}]]},"Format Custom Query Results":{"main":[[{"node":"Convert to File","type":"main","index":0}]]},"Insert Transaction into DB1":{"main":[[{"node":"Build Confirmation Message1","type":"main","index":0}]]},"Parse & Validate Transaction":{"main":[[{"node":"Split Transaction Lines","type":"main","index":0}]]},"Validate Transaction Fields1":{"main":[[{"node":"Insert Transaction into DB1","type":"main","index":0}]]},"Run OCR on Image (Gemini API)":{"main":[[{"node":"Parse & Validate Transaction (Receipts & Bills)","type":"main","index":0}]]},"Transcribe Audio by deepgram ":{"main":[[{"node":"Parse & Validate Transaction(Audio Transcribe)","type":"main","index":0}]]},"Build Custom Financial Summary":{"main":[[{"node":"Send Custom Report","type":"main","index":0}]]},"Fetch User Profile from Postgres":{"main":[[{"node":"Check user Exists or not","type":"main","index":0}]]},"Transform Custom Query for Postgres":{"main":[[{"node":"Execute Custom Report Query","type":"main","index":0}]]},"Parse & Validate Transaction(Audio Transcribe)":{"main":[[{"node":"Split Transaction Lines","type":"main","index":0}]]},"Parse & Validate Transaction (Receipts & Bills)":{"main":[[{"node":"Split Transaction Lines","type":"main","index":0}]]}}}


name: 🧠 AI Blog Post Journalist (Perplexity for Research, Anthropic Claude for Blog)
author_name: Automate With Marc
author_username: marconi
categories: []
created_at: 2025-06-24T14:29:45.049Z
updated_at: 2025-06-24T14:29:45.049Z
url: https://n8n.io/workflows/5202
scraped_at: 2025-07-06 21:16:30
description:
  This workflow contains community nodes that are only compatible with the self-hosted version of n8n. 

  🧠 AI-Powered Blog Post Generator
  Category: Content Automation / AI Writing / Marketing

  Description:
  This automated workflow helps you generate fresh, SEO-optimized blog posts daily using AI tools—perfect for solo creators, marketers, and content teams looking to stay on top of the latest AI trends without manual research or writing.

  For more of such builds and step-by-step Tutorial Guides, check out:
  https://www.youtube.com/@Automatewithmarc

  Here’s how it works:

  Schedule Trigger kicks off the workflow daily (or at your preferred interval).

  Perplexity AI Node researches the most interesting recent AI news tailored for a non-technical audience.

  AI Agent (Claude via Anthropic) turns that news into a full-length blog post based on a structured prompt that includes title, intro, 3+ section headers, takeaway, and meta description—designed for clarity, engagement, and SEO.

  Optional Memory & Perplexity Tool Nodes enhance the agent's responses by allowing it to clarify facts or fetch more context.

  Google Docs Node automatically saves the final blog post to your selected document—ready for review, scheduling, or publishing.

  Key Features:

  Combines Perplexity AI + Claude AI (Anthropic) for research + writing

  Built-in memory and retrieval logic for deeper contextual accuracy

  Non-technical, friendly writing style ideal for general audiences

  Output saved directly to Google Docs

  Fully no-code, customizable, and extendable

  Use Cases:

  Automate weekly blog content for your newsletter or site

  Repurpose content into social posts or scripts

  Keep your brand relevant in the fast-moving AI landscape

  Setup Requirements:

  Perplexity API Key

  Anthropic API Key

  Google Docs (OAuth2 connected)

nodes_used:
  ["n8n-nodes-base.googleDocs","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatAnthropic","@n8n/n8n-nodes-langchain.memoryBufferWindow","n8n-nodes-base.perplexity"]

workflow_json:
  {"id":"91ODWr9EkSAETwX2","meta":{"instanceId":"1c7b08fed4406d546caf4a44e8b942ca317e7e207bb9a5701955a1a6e1ce1843","templateCredsSetupCompleted":true},"name":"AI-Powered Blog Post Generator","tags":[],"nodes":[{"id":"bc282e38-6c6a-409c-b017-34cb852ff5b7","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[-120,0],"parameters":{"rule":{"interval":[{}]}},"typeVersion":1.2},{"id":"e7e64550-2d73-4797-a0f7-58456e76642c","name":"Perplexity - Blog Topic Research Node","type":"n8n-nodes-base.perplexity","position":[160,0],"parameters":{"model":"sonar-pro","options":{"searchRecency":"week"},"messages":{"message":[{"content":"Research on the latest AI news that will be interesting to blog about. Choose and return only the most interesting news for the blog intended for non-technical audience trying to learn more about AI."}]},"requestOptions":{}},"credentials":{"perplexityApi":{"id":"siBtNJfFZDULtMTv","name":"Perplexity account"}},"typeVersion":1},{"id":"ce9a37b0-5fac-4cc6-8877-7a09d23467e1","name":"Anthropic Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatAnthropic","position":[480,200],"parameters":{"model":{"__rl":true,"mode":"list","value":"claude-sonnet-4-20250514","cachedResultName":"Claude 4 Sonnet"},"options":{}},"credentials":{"anthropicApi":{"id":"Xwyc4eRrFeJRUxib","name":"Anthropic account"}},"typeVersion":1.3},{"id":"2ac602fb-7cde-4cae-971d-c374ae429b1e","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[520,0],"parameters":{"text":"={{ $json.choices[0].message.content }}","options":{"systemMessage":"=You are a professional blog content writer for a tech news site that translates the latest AI breakthroughs and developments into engaging, non-technical blog posts.\n\nYour task is to write a clear, captivating, and SEO-optimized blog post based on the latest AI topic provided by the previous node (Perplexity AI Search output). The post should be easy to understand by general readers with no technical background, while still sounding informed, current, and exciting.\n\nINSTRUCTIONS:\n\nAudience: General readers, professionals, and business folks curious about AI—but not developers or engineers.\n\nTone & Style:\n\nFriendly, conversational, curious\n\nNot clickbait, but exciting and easy to read\n\nAvoid jargon unless necessary, and always explain it simply\n\nUse storytelling or a real-world metaphor/example when possible\n\nFormat:\n\nTitle (must include primary keywords related to the topic)\n\n1-paragraph Hook/Intro (make the reader want to read on)\n\n3–5 short sections with headers\n\nFinal Takeaway / What this means for the average reader\n\nSEO Meta Description (max 155 characters)\n\nInclude 3–5 SEO keywords naturally in the body\n\nUse bullet points or bolding to improve skimmability\n\nRules:\n\nDo not fabricate facts.\n\nIf additional context is needed, call the Perplexity Search Tool for clarification\n\nDo not overuse buzzwords or technical terms—explain them simply if used\n\nKeep paragraphs short and engaging\n\nExample Topics This Prompt Can Work For:\n\n“How Apple is using AI in its new products”\n\n“Why the EU is regulating AI and what it means for us”\n\n“OpenAI’s latest model and what it can do for small businesses”\n\n# [Catchy SEO Blog Title with Keyword]\n\n*[Optional Subtitle for clarity]*\n\n**Intro:**  \n[Compelling hook paragraph that introduces the topic with relevance and clarity.]\n\n## [Subheading 1]\n[Explain one key point from the research, in a simple, friendly way.]\n\n## [Subheading 2]\n[Another key aspect, ideally with a metaphor, stat, or quote.]\n\n## [Subheading 3]\n[Implications, opportunities, or what to look out for.]\n\n**Takeaway:**  \n[A 2–3 sentence wrap-up telling readers what they should remember or what action they might take.]\n\n**Meta Description:**  \n[Short, SEO-focused summary of the blog post. Max 155 characters.]\n\n**SEO Keywords:**  \n[Include a few relevant SEO keywords you naturally used in the blog.]\n"},"promptType":"define"},"typeVersion":2},{"id":"9f7883ed-c94d-4012-a7ab-df12d9b874ca","name":"Simple Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[600,200],"parameters":{"sessionKey":"={{ $('Perplexity - Blog Topic Research Node').item.json.id }}","sessionIdType":"customKey"},"typeVersion":1.3},{"id":"e48b32af-4126-4afa-8d5b-680b95128b07","name":"Perplexity Search Tool","type":"n8n-nodes-base.perplexityTool","position":[760,200],"parameters":{"model":"sonar-pro","options":{},"messages":{"message":[{"content":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('message0_Text', ``, 'string') }}"}]},"simplify":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Simplify_Output', ``, 'boolean') }}","requestOptions":{}},"credentials":{"perplexityApi":{"id":"siBtNJfFZDULtMTv","name":"Perplexity account"}},"typeVersion":1},{"id":"28023ef7-b506-4a24-94aa-d238dd934fb7","name":"Google Docs","type":"n8n-nodes-base.googleDocs","position":[1020,0],"parameters":{"actionsUi":{"actionFields":[{"text":"={{ $json.output }}","action":"insert"}]},"operation":"update","documentURL":""},"credentials":{"googleDocsOAuth2Api":{"id":"uTMixjQqDRyGwqj4","name":"Google Docs account"}},"typeVersion":2},{"id":"1f08afc2-e82e-4299-a9d4-e5d22c61c77b","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-200,-200],"parameters":{"width":260,"height":600,"content":"Schedule Trigger"},"typeVersion":1},{"id":"3047e161-9da7-4dc3-97be-a80781bddf49","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[80,-200],"parameters":{"color":3,"width":300,"height":600,"content":"Schedule Trigger"},"typeVersion":1},{"id":"31e687c4-363f-49ee-abd2-93fc3d13ea59","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[400,-200],"parameters":{"color":5,"width":500,"height":600,"content":"Schedule Trigger"},"typeVersion":1},{"id":"32b8771b-67cf-4521-8d79-c032e3d70f72","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[920,-200],"parameters":{"color":6,"width":300,"height":600,"content":"Schedule Trigger"},"typeVersion":1},{"id":"ac2f86cc-099f-4985-a780-7c06b605bf91","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-860,-200],"parameters":{"width":620,"height":1020,"content":"🧠 AI-Powered Blog Post Generator\nCategory: Content Automation / AI Writing / Marketing\n\nDescription:\nThis automated workflow helps you generate fresh, SEO-optimized blog posts daily using AI tools—perfect for solo creators, marketers, and content teams looking to stay on top of the latest AI trends without manual research or writing.\n\nFor more of this build and step-by-step tutorials, check out:\nhttps://www.youtube.com/@Automatewithmarc\n\nHere’s how it works:\n\nSchedule Trigger kicks off the workflow daily (or at your preferred interval).\n\nPerplexity AI Node researches the most interesting recent AI news tailored for a non-technical audience.\n\nAI Agent (Claude via Anthropic) turns that news into a full-length blog post based on a structured prompt that includes title, intro, 3+ section headers, takeaway, and meta description—designed for clarity, engagement, and SEO.\n\nOptional Memory & Perplexity Tool Nodes enhance the agent's responses by allowing it to clarify facts or fetch more context.\n\nGoogle Docs Node automatically saves the final blog post to your selected document—ready for review, scheduling, or publishing.\n\nKey Features:\n\nCombines Perplexity AI + Claude AI (Anthropic) for research + writing\n\nBuilt-in memory and retrieval logic for deeper contextual accuracy\n\nNon-technical, friendly writing style ideal for general audiences\n\nOutput saved directly to Google Docs\n\nFully no-code, customizable, and extendable\n\nUse Cases:\n\nAutomate weekly blog content for your newsletter or site\n\nRepurpose content into social posts or scripts\n\nKeep your brand relevant in the fast-moving AI landscape\n\nSetup Requirements:\n\nPerplexity API Key\n\nAnthropic API Key\n\nGoogle Docs (OAuth2 connected)"},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"69254d17-147f-4e2a-9508-366be9ce75f2","connections":{"AI Agent":{"main":[[{"node":"Google Docs","type":"main","index":0}]]},"Simple Memory":{"ai_memory":[[{"node":"AI Agent","type":"ai_memory","index":0}]]},"Schedule Trigger":{"main":[[{"node":"Perplexity - Blog Topic Research Node","type":"main","index":0}]]},"Anthropic Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"Perplexity Search Tool":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"Perplexity - Blog Topic Research Node":{"main":[[{"node":"AI Agent","type":"main","index":0}]]}}}


name: Sentiment Analytics Visualizer
author_name: Franz
author_username: agents-by-franz
categories: []
created_at: 2025-06-24T15:13:14.114Z
updated_at: 2025-06-24T15:13:14.114Z
url: https://n8n.io/workflows/5204
scraped_at: 2025-07-06 21:16:30
description:
  🧠 Sentiment Analyzer

  Google Sheets → OpenAI GPT-4o → QuickChart → Gmail

  🚀 What this workflow does

  Fetches customer reviews from a Google Sheet.
  Classifies each review as Positive, Neutral or Negative with GPT-4o-mini.
  Writes the sentiment back to your sheet.
  Builds a doughnut chart summarising the totals.
  Emails the chart to your chosen recipient so the whole team stays in the loop.

  Perfect for support teams, product managers or anyone who wants a zero-code mood ring for their users’ feedback.

  🗺️ Node-by-node tour

  | 🔩 Node                                                 | 💡 Purpose                                                 |
  | ------------------------------------------------------- | ---------------------------------------------------------- |
  | Manual Trigger                                      | Lets you test the workflow on demand.                      |
  | Select Google Sheet                                 | Points to the spreadsheet that holds your reviews.         |
  | Loop Over Items                                     | Feeds each row through the analysis routine.               |
  | Sentiment Analysis (LangChain)                      | Calls GPT-4o-mini and returns only the sentiment category. |
  | Update Google Sheet                                 | Writes the new Sentiment value into column C.          |
  | Read Data from Google Sheet                         | Pulls the full sheet again to create a summary.            |
  | Extract Number of Answers per Sentiment (Code node) | Tallies up how many reviews fall into each category.       |
  | Generate QuickChart                                 | Creates a doughnut (or pie) chart as a PNG.                |
  | Send Gmail with Sentiment Chart                     | Fires the chart off to your inbox.                         |
  | (Sticky Notes)                                        | Friendly setup tips scattered around the canvas.           |

  🛠️ Setup checklist

  | ✅ Step                                                                                | Where                            |
  | ------------------------------------------------------------------------------------- | -------------------------------- |
  | Connect Google Sheets → paste your Spreadsheet ID & choose the correct sheet. | All Google Sheets nodes          |
  | Add OpenAI credentials (sk-… key).                                                | Sentiment Analysis node          |
  | Configure Gmail OAuth2 + recipient address.                                       | Gmail node                       |
  | Match your sheet columns → “Review title”, “Review text”, empty “Sentiment”.      | Google Sheet itself              |
  | (Optional) Switch to gpt-4o for maximum accuracy.                               | Sentiment Analysis “Model” param |

  🏃‍♂️ How to run

  Drop a few sample reviews into the sheet.
  Click “Test workflow” on the Manual Trigger.
  Watch each row march through → sentiment appears in column C.
  After all rows finish, check your inbox for a fresh chart. ✔️

  ✨ Ideas for next level

  Schedule** the trigger (Cron) to auto-process new reviews daily.
  Feed the counts to Slack or Discord instead of email.
  Add a second GPT call to generate a short summary for each review.

  Happy automating! 🎉

nodes_used:
  ["n8n-nodes-base.googleSheets","n8n-nodes-base.gmail","n8n-nodes-base.code","n8n-nodes-base.quickChart","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.sentimentAnalysis"]

workflow_json:
  {"id":"4BOP29RhumejWZ6r","meta":{"instanceId":"9cff38efa9e14e046ee88ad0878735c9b841d16e934d6ad95ba7fd58bb5558de"},"name":"Sentiment Analyzer","tags":[],"nodes":[{"id":"cb616bea-a6ad-4864-8169-9b0c24868761","name":"📋 Setup Instructions","type":"n8n-nodes-base.stickyNote","position":[-300,40],"parameters":{"width":400,"height":460,"content":"## 📋 SETUP REQUIRED\n\n**This workflow requires the following configurations:**\n\n1. **Google Sheets Connection**: Update all Google Sheets nodes with your spreadsheet ID\n2. **OpenAI API**: Add your OpenAI API credentials\n3. **Gmail Account**: Configure Gmail OAuth2 for email notifications\n4. **Email Recipient**: Update the email address in the Gmail node\n\n**Expected Sheet Structure:**\n- Column A: Review title\n- Column B: Review text\n- Column C: Sentiment (will be populated by workflow)\n\n**Before running:** Make sure your Google Sheet has the columns 'Review title' and 'Review text' with your data."},"typeVersion":1},{"id":"da05ebb8-6027-43d9-8c56-42d33d6d5f78","name":"🔧 Configure Google Sheets","type":"n8n-nodes-base.stickyNote","position":[300,-160],"parameters":{"width":300,"height":340,"content":"## 🔧 CUSTOMIZE THIS NODE\n\n**Google Sheets Configuration:**\n1. Replace the documentId with your Google Sheets ID\n2. Select the correct sheet name\n3. Ensure your sheet has 'Review title' and 'Review text' columns\n\n**To get your Sheet ID:**\n- Copy from URL: docs.google.com/spreadsheets/d/[SHEET_ID]/edit"},"typeVersion":1},{"id":"a07f32b5-1f38-4f61-b2c4-1e91b0df9512","name":"🤖 Configure OpenAI","type":"n8n-nodes-base.stickyNote","position":[720,740],"parameters":{"width":420,"height":200,"content":"## 🤖 CUSTOMIZE THIS NODE\n\n**OpenAI Configuration:**\n1. Add your OpenAI API credentials\n2. Model is set to gpt-4o-mini (cost-effective)\n3. You can change to gpt-4o for higher accuracy\n\n**Required:** Valid OpenAI API key with sufficient credits"},"typeVersion":1},{"id":"370277f5-8a80-4dc8-aff8-f025d6123356","name":"📧 Configure Gmail","type":"n8n-nodes-base.stickyNote","position":[1520,-60],"parameters":{"width":340,"height":220,"content":"## 📧 CUSTOMIZE THIS NODE\n\n**Gmail Configuration:**\n1. Replace email address with your recipient\n2. Configure Gmail OAuth2 credentials\n3. Customize email subject and message\n\n**Current recipient:** [YOUR_EMAIL_HERE]"},"typeVersion":1},{"id":"bccef3f8-801b-421a-8865-00064fc313f2","name":"Loop Over Items","type":"n8n-nodes-base.splitInBatches","position":[620,200],"parameters":{"options":{"reset":false}},"typeVersion":3},{"id":"76118dc2-c52d-4a1a-aba2-981a62d4a28a","name":"Sentiment Analysis","type":"@n8n/n8n-nodes-langchain.sentimentAnalysis","position":[820,360],"parameters":{"options":{"categories":"Positive, Neutral, Negative","enableAutoFixing":true,"systemPromptTemplate":"You are highly intelligent and accurate sentiment analyzer. Analyze the sentiment of the provided text. Categorize it into one of the following: {categories}. Use the provided formatting instructions. Only output the JSON.","includeDetailedResults":false},"inputText":"=Title: {{ $json['Review title'] }}\nText: {{ $json['Review text'] }}"},"retryOnFail":false,"typeVersion":1,"alwaysOutputData":false},{"id":"c34c8c45-fd8e-4cef-8156-6a5658c48c46","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[820,540],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"typeVersion":1.2},{"id":"7bd27f43-9207-40f4-9c6a-bea0be03a6fc","name":"When clicking 'Test workflow'","type":"n8n-nodes-base.manualTrigger","position":[180,200],"parameters":{},"typeVersion":1},{"id":"c2c21691-fd21-4afe-a60d-08c6399372e5","name":"Select Google Sheet","type":"n8n-nodes-base.googleSheets","position":[400,200],"parameters":{"options":{},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"REPLACE_WITH_YOUR_GOOGLE_SHEETS_ID","cachedResultUrl":"https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/edit","cachedResultName":"Your Customer Reviews Sheet"}},"typeVersion":4.5},{"id":"4a4b2f78-d043-4853-980d-f24c3f5139dd","name":"Update Google Sheet","type":"n8n-nodes-base.googleSheets","position":[1180,520],"parameters":{"columns":{"value":{"Sentiment":"={{ $json.sentimentAnalysis.category }}"},"schema":[{"id":"Review title","type":"string","display":true,"removed":false,"required":false,"displayName":"Review title","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Review text","type":"string","display":true,"required":false,"displayName":"Review text","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Sentiment","type":"string","display":true,"removed":false,"required":false,"displayName":"Sentiment","defaultMatch":false,"canBeUsedToMatch":true},{"id":"sentimentAnalysis","type":"string","display":true,"removed":true,"required":false,"displayName":"sentimentAnalysis","defaultMatch":false,"canBeUsedToMatch":true},{"id":"row_number","type":"string","display":true,"removed":false,"readOnly":true,"required":false,"displayName":"row_number","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"autoMapInputData","matchingColumns":["row_number"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{"cellFormat":"USER_ENTERED"},"operation":"update","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"REPLACE_WITH_YOUR_GOOGLE_SHEETS_ID","cachedResultUrl":"https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/edit","cachedResultName":"Your Customer Reviews Sheet"}},"typeVersion":4.5},{"id":"e8af1018-02ea-4961-be63-4ac7e0b2db4a","name":"Read Data from Google Sheet","type":"n8n-nodes-base.googleSheets","position":[980,180],"parameters":{"options":{},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"REPLACE_WITH_YOUR_GOOGLE_SHEETS_ID","cachedResultUrl":"https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/edit","cachedResultName":"Your Customer Reviews Sheet"}},"executeOnce":true,"typeVersion":4.5},{"id":"58cfddb4-cc28-451a-a4ec-f8d391c7b198","name":"Extract Number of Answers per Sentiment","type":"n8n-nodes-base.code","position":[1200,180],"parameters":{"jsCode":"const comments = $input.all();\nlet sentimentCount = { Positive: 0, Negative: 0, Neutral: 0 };\n\ncomments.forEach((comment) => {\n  const sentiment = comment?.json?.sentimentAnalysis;\n  if (sentiment.includes(\"Positive\")) {\n    sentimentCount.Positive++;\n  } else if (sentiment.includes(\"Negative\")) {\n    sentimentCount.Negative++;\n  } else if (sentiment.includes(\"Neutral\")) {\n    sentimentCount.Neutral++;\n  }\n});\n\nreturn {\n  labels: [\"Positive\", \"Neutral\", \"Negative\"],\n  values: [\n    sentimentCount.Positive,\n    sentimentCount.Neutral,\n    sentimentCount.Negative,\n  ],\n};\n"},"typeVersion":2,"alwaysOutputData":true},{"id":"fa766ee4-8dff-44cd-b2a5-9c2f079ab160","name":"Generate QuickChart","type":"n8n-nodes-base.quickChart","position":[1380,180],"parameters":{"data":"={{ $json.values }}","output":"=data","labelsMode":"array","labelsArray":"={{ $json.labels }}","chartOptions":{},"datasetOptions":{}},"typeVersion":1,"alwaysOutputData":true},{"id":"952e3afc-c5a3-4faf-92e1-a467399bc7c8","name":"Send Gmail with Sentiment Chart","type":"n8n-nodes-base.gmail","position":[1600,180],"webhookId":"WEBHOOK_ID_WILL_BE_GENERATED","parameters":{"sendTo":"YOUR_EMAIL@example.com","message":"=Dear Team,\n\nPlease find attached the sentiment analysis summary of recent customer reviews.\n\nBest regards,\nAutomated Sentiment Analysis System","options":{"attachmentsUi":{"attachmentsBinary":[{}]}},"subject":"Sentiment Analysis Summary","emailType":"text"},"typeVersion":2.1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"894d1878-53b7-4efd-a542-b2851424e27c","connections":{"Loop Over Items":{"main":[[{"node":"Read Data from Google Sheet","type":"main","index":0}],[{"node":"Sentiment Analysis","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"Sentiment Analysis","type":"ai_languageModel","index":0}]]},"Sentiment Analysis":{"main":[[{"node":"Update Google Sheet","type":"main","index":0}],[{"node":"Update Google Sheet","type":"main","index":0}],[{"node":"Update Google Sheet","type":"main","index":0}]]},"Generate QuickChart":{"main":[[{"node":"Send Gmail with Sentiment Chart","type":"main","index":0}]]},"Select Google Sheet":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Update Google Sheet":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Read Data from Google Sheet":{"main":[[{"node":"Extract Number of Answers per Sentiment","type":"main","index":0}]]},"When clicking 'Test workflow'":{"main":[[{"node":"Select Google Sheet","type":"main","index":0}]]},"Extract Number of Answers per Sentiment":{"main":[[{"node":"Generate QuickChart","type":"main","index":0}]]}}}


name: AI agents can get end of day market data with this Marketstack Tool MCP Server
author_name: David Ashby
author_username: cfomodz
nodes_used: []
categories: []
created_at: 2025-06-24T15:24:17.381Z
updated_at: 2025-06-24T15:24:17.381Z
url: https://n8n.io/workflows/5205
scraped_at: 2025-07-06 21:16:30
description:
  🛠️ Marketstack Tool MCP Server

  Complete MCP server exposing all Marketstack Tool operations to AI agents. Zero configuration needed - all 3 operations pre-built.

  ⚡ Quick Setup

  Import this workflow into your n8n instance
  Activate the workflow to start your MCP server
  Copy the webhook URL from the MCP trigger node
  Connect AI agents using the MCP URL

  🔧 How it Works

  • MCP Trigger: Serves as your server endpoint for AI agent requests
  • Tool Nodes: Pre-configured for every Marketstack Tool operation
  • AI Expressions: Automatically populate parameters via $fromAI() placeholders
  • Native Integration: Uses official n8n Marketstack Tool tool with full error handling

  📋 Available Operations (3 total)

  Every possible Marketstack Tool operation is included:

  🔧 Endofdaydata (1 operations)

  • Get many EoD data

  🔧 Exchange (1 operations)

  • Get an exchange

  🔧 Ticker (1 operations)

  • Get a ticker

  🤖 AI Integration

  Parameter Handling: AI agents automatically provide values for:
  • Resource IDs and identifiers
  • Search queries and filters
  • Content and data payloads
  • Configuration options

  Response Format: Native Marketstack Tool API responses with full data structure

  Error Handling: Built-in n8n error management and retry logic

  💡 Usage Examples

  Connect this MCP server to any AI agent or workflow:

  • Claude Desktop: Add MCP server URL to configuration
  • Custom AI Apps: Use MCP URL as tool endpoint
  • Other n8n Workflows: Call MCP tools from any workflow
  • API Integration: Direct HTTP calls to MCP endpoints

  ✨ Benefits

  • Complete Coverage: Every Marketstack Tool operation available
  • Zero Setup: No parameter mapping or configuration needed
  • AI-Ready: Built-in $fromAI() expressions for all parameters
  • Production Ready: Native n8n error handling and logging
  • Extensible: Easily modify or add custom logic

  &gt; 🆓 Free for community use! Ready to deploy in under 2 minutes.

workflow_json:
  {"meta":{"instanceId":"cd59eaaeb7b34d06e24511380db94cdb7fbce6037cc4de22e539c5158ab9cdfc"},"nodes":[{"id":"72c021e9-b1a5-48d5-98e3-c59278dc8d66","name":"Workflow Overview 0","type":"n8n-nodes-base.stickyNote","position":[-1460,-60],"parameters":{"width":420,"height":820,"content":"## 🛠️ Marketstack Tool MCP Server\n\n### 📋 Available Operations (3 total)\n\n**Endofdaydata**: get all\n**Exchange**: get\n**Ticker**: get\n\n### ⚙️ Setup Instructions\n\n1. **Import Workflow**: Load this workflow into your n8n instance\n\n1. **🔑 Add Credentials**: Configure Marketstack Tool authentication in one tool node then open and close all others.\n2. **🚀 Activate**: Enable this workflow to start your MCP server\n3. **🔗 Get URL**: Copy webhook URL from MCP trigger (right side)\n4. **🤖 Connect**: Use MCP URL in your AI agent configurations\n\n### ✨ Ready-to-Use Features\n\n• Zero configuration - all 3 operations pre-built\n• AI agents automatically populate parameters via `$fromAI()` expressions\n• Every resource and operation combination available\n• Native n8n error handling and response formatting\n• Modify parameter defaults in any tool node as needed\n\n### 💬 Need Help?\nCheck the [n8n documentation](https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolmcp/) or ping me on [discord](https://discord.me/cfomodz) for MCP integration guidance or customizations."},"typeVersion":1},{"id":"bf56d816-478e-4745-9f63-8d4cb063ab74","name":"Marketstack Tool MCP Server","type":"@n8n/n8n-nodes-langchain.mcpTrigger","position":[-700,-60],"webhookId":"a69e1598-9069-4e24-b62b-c6bd02d3ceaa","parameters":{"path":"marketstack-tool-mcp"},"typeVersion":1},{"id":"40a928b6-95be-46ec-b836-1acffdf482eb","name":"Get many EoD data","type":"n8n-nodes-base.marketstackTool","position":[-800,140],"parameters":{"limit":"={{ $fromAI('Limit', ``, 'number') }}","filters":{},"symbols":"={{ $fromAI('Symbols', ``, 'string') }}","returnAll":"={{ $fromAI('Return_All', ``, 'boolean') }}"},"credentials":{},"typeVersion":1},{"id":"e9760cd3-5040-4540-8d80-e454c91a8685","name":"Sticky Note 1","type":"n8n-nodes-base.stickyNote","position":[-1000,120],"parameters":{"color":4,"width":400,"content":"## Endofdaydata"},"typeVersion":1},{"id":"1d1009d4-2550-40f1-8898-9f852a51ebf8","name":"Get an exchange","type":"n8n-nodes-base.marketstackTool","position":[-800,380],"parameters":{"exchange":"={{ $fromAI('Exchange', ``, 'string') }}","resource":"exchange"},"credentials":{},"typeVersion":1},{"id":"a9486b80-8efe-4f31-ac1c-d63c5ad71d30","name":"Sticky Note 2","type":"n8n-nodes-base.stickyNote","position":[-1000,360],"parameters":{"color":5,"width":400,"content":"## Exchange"},"typeVersion":1},{"id":"c9927486-c562-4224-9644-c1e99e3e7bdd","name":"Get a ticker","type":"n8n-nodes-base.marketstackTool","position":[-800,620],"parameters":{"symbol":"={{ $fromAI('Symbol', ``, 'string') }}","resource":"ticker"},"credentials":{},"typeVersion":1},{"id":"61be9fc7-6369-4fec-91ef-1c158df8316c","name":"Sticky Note 3","type":"n8n-nodes-base.stickyNote","position":[-1000,600],"parameters":{"color":6,"width":400,"content":"## Ticker"},"typeVersion":1}],"pinData":{},"connections":{"Get a ticker":{"ai_tool":[[{"node":"Marketstack Tool MCP Server","type":"ai_tool","index":0}]]},"Get an exchange":{"ai_tool":[[{"node":"Marketstack Tool MCP Server","type":"ai_tool","index":0}]]},"Get many EoD data":{"ai_tool":[[{"node":"Marketstack Tool MCP Server","type":"ai_tool","index":0}]]}}}


name: Check Email via AI agent with Mailcheck Tool MCP Server
author_name: David Ashby
author_username: cfomodz
nodes_used: []
categories: []
created_at: 2025-06-24T15:31:58.769Z
updated_at: 2025-06-24T15:31:58.769Z
url: https://n8n.io/workflows/5208
scraped_at: 2025-07-06 21:16:30
description:
  🛠️ Mailcheck Tool MCP Server

  Complete MCP server exposing all Mailcheck Tool operations to AI agents. Zero configuration needed - 1 operations pre-built.

  ⚡ Quick Setup

  Import this workflow into your n8n instance
  Activate the workflow to start your MCP server
  Copy the webhook URL from the MCP trigger node
  Connect AI agents using the MCP URL

  🔧 How it Works

  • MCP Trigger: Serves as your server endpoint for AI agent requests
  • Tool Nodes: Pre-configured for every Mailcheck Tool operation
  • AI Expressions: Automatically populate parameters via $fromAI() placeholders
  • Native Integration: Uses official n8n Mailcheck Tool tool with full error handling

  📋 Available Operations (1 total)

  Every possible Mailcheck Tool operation is included:

  🔧 Email (1 operations)

  • Check an email

  🤖 AI Integration

  Parameter Handling: AI agents automatically provide values for:
  • Resource IDs and identifiers
  • Search queries and filters
  • Content and data payloads
  • Configuration options

  Response Format: Native Mailcheck Tool API responses with full data structure

  Error Handling: Built-in n8n error management and retry logic

  💡 Usage Examples

  Connect this MCP server to any AI agent or workflow:

  • Claude Desktop: Add MCP server URL to configuration
  • Custom AI Apps: Use MCP URL as tool endpoint
  • Other n8n Workflows: Call MCP tools from any workflow
  • API Integration: Direct HTTP calls to MCP endpoints

  ✨ Benefits

  • Complete Coverage: Every Mailcheck Tool operation available
  • Zero Setup: No parameter mapping or configuration needed
  • AI-Ready: Built-in $fromAI() expressions for all parameters
  • Production Ready: Native n8n error handling and logging
  • Extensible: Easily modify or add custom logic

  &gt; 🆓 Free for community use! Ready to deploy in under 2 minutes.

workflow_json:
  {"meta":{"instanceId":"cd59eaaeb7b34d06e24511380db94cdb7fbce6037cc4de22e539c5158ab9cdfc"},"nodes":[{"id":"c87a1e26-1254-4895-b4c1-d8648b499ed4","name":"Workflow Overview 0","type":"n8n-nodes-base.stickyNote","position":[-1460,-260],"parameters":{"width":420,"height":760,"content":"## 🛠️ Mailcheck Tool MCP Server\n\n### 📋 Available Operations (1 total)\n\n**Email**: check\n\n### ⚙️ Setup Instructions\n\n1. **Import Workflow**: Load this workflow into your n8n instance\n\n1. **🔑 Add Credentials**: Configure Mailcheck Tool authentication in one tool node then open and close all others.\n2. **🚀 Activate**: Enable this workflow to start your MCP server\n3. **🔗 Get URL**: Copy webhook URL from MCP trigger (right side)\n4. **🤖 Connect**: Use MCP URL in your AI agent configurations\n\n### ✨ Ready-to-Use Features\n\n• Zero configuration - all 1 operations pre-built\n• AI agents automatically populate parameters via `$fromAI()` expressions\n• Every resource and operation combination available\n• Native n8n error handling and response formatting\n• Modify parameter defaults in any tool node as needed\n\n### 💬 Need Help?\nCheck the [n8n documentation](https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolmcp/) or ping me on [discord](https://discord.me/cfomodz) for MCP integration guidance or customizations."},"typeVersion":1},{"id":"37c6a3cf-261a-4557-b47e-58b34cc99175","name":"Mailcheck Tool MCP Server","type":"@n8n/n8n-nodes-langchain.mcpTrigger","position":[-820,-160],"webhookId":"480fc81a-ca0c-4c3d-aa84-552340a857de","parameters":{"path":"mailcheck-tool-mcp"},"typeVersion":1},{"id":"7ebd82d9-afae-4baa-8da4-43ee5636394c","name":"Check an email","type":"n8n-nodes-base.mailcheckTool","position":[-800,140],"parameters":{"email":"={{ $fromAI('Email', ``, 'string') }}"},"credentials":{},"typeVersion":1},{"id":"69b0a0f1-9226-4b66-865a-af143e582329","name":"Sticky Note 1","type":"n8n-nodes-base.stickyNote","position":[-1000,120],"parameters":{"color":4,"width":400,"content":"## Email"},"typeVersion":1}],"pinData":{},"connections":{"Check an email":{"ai_tool":[[{"node":"Mailcheck Tool MCP Server","type":"ai_tool","index":0}]]}}}


name: Create LinkedIn Posts with AI Agents using MCP Server
author_name: David Ashby
author_username: cfomodz
nodes_used: []
categories: []
created_at: 2025-06-24T15:36:09.901Z
updated_at: 2025-06-24T15:36:09.901Z
url: https://n8n.io/workflows/5210
scraped_at: 2025-07-06 21:16:30
description:
  🛠️ LinkedIn Tool MCP Server

  Complete MCP server exposing all LinkedIn Tool operations to AI agents. Zero configuration needed - all 1 operations pre-built.

  ⚡ Quick Setup

  Import this workflow into your n8n instance
  Activate the workflow to start your MCP server
  Copy the webhook URL from the MCP trigger node
  Connect AI agents using the MCP URL

  🔧 How it Works

  • MCP Trigger: Serves as your server endpoint for AI agent requests
  • Tool Nodes: Pre-configured for every LinkedIn Tool operation
  • AI Expressions: Automatically populate parameters via $fromAI() placeholders
  • Native Integration: Uses official n8n LinkedIn Tool tool with full error handling

  📋 Available Operations (1 total)

  Every possible LinkedIn Tool operation is included:

  🔧 Post (1 operations)

  • Create a post

  🤖 AI Integration

  Parameter Handling: AI agents automatically provide values for:
  • Resource IDs and identifiers
  • Search queries and filters
  • Content and data payloads
  • Configuration options

  Response Format: Native LinkedIn Tool API responses with full data structure

  Error Handling: Built-in n8n error management and retry logic

  💡 Usage Examples

  Connect this MCP server to any AI agent or workflow:

  • Claude Desktop: Add MCP server URL to configuration
  • Custom AI Apps: Use MCP URL as tool endpoint
  • Other n8n Workflows: Call MCP tools from any workflow
  • API Integration: Direct HTTP calls to MCP endpoints

  ✨ Benefits

  • Complete Coverage: Every LinkedIn Tool operation available
  • Zero Setup: No parameter mapping or configuration needed
  • AI-Ready: Built-in $fromAI() expressions for all parameters
  • Production Ready: Native n8n error handling and logging
  • Extensible: Easily modify or add custom logic

  &gt; 🆓 Free for community use! Ready to deploy in under 2 minutes.

workflow_json:
  {"meta":{"instanceId":"cd59eaaeb7b34d06e24511380db94cdb7fbce6037cc4de22e539c5158ab9cdfc"},"nodes":[{"id":"e5f5a8ea-1bd2-48e9-881e-fae427079fab","name":"Workflow Overview 0","type":"n8n-nodes-base.stickyNote","position":[-1460,-300],"parameters":{"width":420,"height":780,"content":"## 🛠️ LinkedIn Tool MCP Server\n\n### 📋 Available Operations (1 total)\n\n**Post**: create\n\n### ⚙️ Setup Instructions\n\n1. **Import Workflow**: Load this workflow into your n8n instance\n\n1. **🔑 Add Credentials**: Configure LinkedIn Tool authentication in one tool node then open and close all others.\n2. **🚀 Activate**: Enable this workflow to start your MCP server\n3. **🔗 Get URL**: Copy webhook URL from MCP trigger (right side)\n4. **🤖 Connect**: Use MCP URL in your AI agent configurations\n\n### ✨ Ready-to-Use Features\n\n• Zero configuration - all 1 operations pre-built\n• AI agents automatically populate parameters via `$fromAI()` expressions\n• Every resource and operation combination available\n• Native n8n error handling and response formatting\n• Modify parameter defaults in any tool node as needed\n\n### 💬 Need Help?\nCheck the [n8n documentation](https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolmcp/) or ping me on [discord](https://discord.me/cfomodz) for MCP integration guidance or customizations."},"typeVersion":1},{"id":"731411cc-9ecc-4654-b187-cbd468fd3b88","name":"LinkedIn Tool MCP Server","type":"@n8n/n8n-nodes-langchain.mcpTrigger","position":[-840,-160],"webhookId":"a6ddc7a9-6e0a-454e-9728-6ad68b63a3e8","parameters":{"path":"linkedin-tool-mcp"},"typeVersion":1},{"id":"197f1ef7-d3ef-44d2-b5d1-c681a9e3333a","name":"Create a post","type":"n8n-nodes-base.linkedInTool","position":[-800,140],"parameters":{"text":"={{ $fromAI('Text', ``, 'string') }}","person":"={{ $fromAI('Person', ``, 'string') }}","additionalFields":{},"binaryPropertyName":"={{ $fromAI('Binary_Property_Name', ``, 'string') }}","shareMediaCategory":"={{ $fromAI('Share_Media_Category', ``, 'string') }}"},"credentials":{},"typeVersion":1},{"id":"9b8254b6-c00f-4e3d-bb9b-f29870a1c186","name":"Sticky Note 1","type":"n8n-nodes-base.stickyNote","position":[-1000,120],"parameters":{"color":4,"width":400,"content":"## Post"},"typeVersion":1}],"pinData":{},"connections":{"Create a post":{"ai_tool":[[{"node":"LinkedIn Tool MCP Server","type":"ai_tool","index":0}]]}}}


name: Find the Best Food Deals Automatically with Bright Data & n8n
author_name: Yaron Been
author_username: yaron-nofluff
nodes_used: ["n8n-nodes-base.httpRequest","n8n-nodes-base.gmail","n8n-nodes-base.html"]
categories: []
created_at: 2025-06-24T15:51:51.308Z
updated_at: 2025-06-24T15:51:51.308Z
url: https://n8n.io/workflows/5212
scraped_at: 2025-07-06 21:16:30
description:
  Description

  This workflow automatically scans food delivery platforms and restaurant websites to find the best deals and discounts. It helps you save money on meals by aggregating special offers and promotions in one place.

  Overview

  This workflow automates finding the best food deals and discounts from various websites. It uses Bright Data to scrape deal information and can be configured to send you notifications or save the deals to a spreadsheet.

  Tools Used

  n8n:** The automation platform that orchestrates the workflow.
  Bright Data:** For scraping food deal websites without getting blocked.
  (Optional) Google Sheets/Discord/Telegram:** To store or get notified about the deals.

  How to Install

  Import the Workflow: Download the .json file and import it into your n8n instance.
  Configure Bright Data: Add your Bright Data credentials to the Bright Data node.
  Set Up Notifications (Optional): Configure the nodes for Google Sheets, Discord, or Telegram if you want to receive notifications.
  Customize: Specify the websites you want to scrape for deals.

  Use Cases

  Foodies:** Always be the first to know about the best restaurant deals in your city.
  Students:** Save money by finding cheap eats and special offers.
  Families:** Plan your meals around the best grocery and restaurant discounts.

  Connect with Me

  Website:** https://www.nofluff.online
  YouTube:** https://www.youtube.com/@YaronBeen/videos
  LinkedIn:** https://www.linkedin.com/in/yaronbeen/
  Get Bright Data:** https://get.brightdata.com/1tndi4600b25 (Using this link supports my free workflows with a small commission)

  #n8n #automation #fooddeals #brightdata #webscraping #discounts #fooddiscounts #mealdeals #restaurantdeals #savemoney #foodoffers #n8nworkflow #workflow #nocode #foodtech #dealfinder #specialoffers #fooddelivery #budgetmeals #foodsavings #dealhunting #foodautomation #moneysaving #foodhacks #bestdeals #foodscraping

workflow_json:
  {"id":"PXfj3dKsPDIM8vKJ","meta":{"instanceId":"60046904b104f0f72b2629a9d88fe9f676be4035769f1f08dad1dd38a76b9480"},"name":"Automated_Food_Deal_Finder_via_Bright_Data","tags":[],"nodes":[{"id":"6c651293-5535-424b-ab9a-562326fcb0a5","name":"Trigger Workflow","type":"n8n-nodes-base.manualTrigger","position":[-400,680],"parameters":{},"typeVersion":1},{"id":"44ef6d02-59e1-4e00-adde-c0d0965d96e0","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[-2040,40],"parameters":{"color":4,"width":1300,"height":320,"content":"=======================================\n            WORKFLOW ASSISTANCE\n=======================================\nFor any questions or support, please contact:\n    Yaron@nofluff.online\n\nExplore more tips and tutorials here:\n   - YouTube: https://www.youtube.com/@YaronBeen/videos\n   - LinkedIn: https://www.linkedin.com/in/yaronbeen/\n=======================================\n"},"typeVersion":1},{"id":"6cb1eda2-5e6a-41f4-bb21-c9289c9e470f","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-2040,380],"parameters":{"color":4,"width":1289,"height":2758,"content":"# 🚀 **Pizza Deal Finder Automation – Breakdown**\n\nThis workflow automatically **scrapes Uber Eats for pizza deals**, **extracts the names and discounts**, and **emails the best offers** to you — all without writing any complex code!\n\n---\n\n## 🟢 **SECTION 1: 🔁 Trigger & 🌍 Fetch Pizza Deals Page**\n\n### 🔹 Nodes Included:\n\n1. ⚡ **Trigger Workflow**\n2. 🌐 **Fetch Uber Eats Search Page (Bright Data)**\n\n---\n\n### 🔧 What Happens Here:\n\n* **⚡ Trigger Workflow**: This node is the starting point. You can configure it to run:\n\n  * On-demand (when you click \"Execute\")\n  * On a schedule (e.g., every morning or every 4 hours)\n\n* **🌐 Fetch Uber Eats Search Page**:\n\n  * Sends a `POST` request to **Bright Data’s Web Unlocker API** to access UberEats.\n  * It bypasses JavaScript-heavy pages and bot protections.\n  * URL targeted: something like `https://www.ubereats.com/search?query=pizza`\n  * Returns full HTML of the results page with all pizza restaurant names and their deals.\n\n### 👨‍💻 For Beginners:\n\n* This is the **scraping engine** of your workflow.\n* Bright Data does the heavy lifting (proxying, unblocking, rendering).\n* You only need to provide your **Bright Data API key** and the target URL.\n\n---\n\n## 🟡 **SECTION 2: 🧹 Extract Pizza Names & Deals**\n\n### 🔹 Node Included:\n\n* 🧩 **Extract Names & Deals**\n\n---\n\n### 🔧 What Happens Here:\n\n* This is the **HTML Extract** node.\n* It scans the raw HTML from the previous step and pulls:\n\n  * 🏷️ Restaurant names (e.g., “Domino’s”)\n  * 💸 Deals or special offers (e.g., “Free Item on \\$9 Spend”)\n\n### 🛠️ CSS Selectors Used:\n\n* **Name Selector**: `div.be.f3.bg.f2.ck.bp.bn.k2` → extracts all names\n* **Deal Selector**: `div.hr.bn.k2` → extracts all visible deals\n\n⚙️ You configure it to **get all matches**, not just one. This ensures multiple restaurants are included.\n\n### 👨‍💻 For Beginners:\n\n* This is where **the magic happens** — HTML becomes readable data.\n* No coding is required — just CSS selectors you can get from “Inspect Element” in Chrome.\n* You can reuse this for other platforms like DoorDash or Grubhub by updating the selectors.\n\n---\n\n## 🔴 **SECTION 3: 📧 Send Best Deals via Gmail**\n\n### 🔹 Node Included:\n\n* ✉️ **Send Pizza Deals via Gmail**\n\n---\n\n### 🔧 What Happens Here:\n\n* Sends you an email (or to any recipient you define).\n* The email includes:\n\n  * 🧾 List of pizza restaurants\n  * 🎁 Associated deals\n\n📬 You can customize the subject and message format using simple templates:\n\n```html\n<h3>🍕 Today’s Top Pizza Deals</h3>\n<ul>\n  {{#each items}}\n    <li><b>{{this.title}}</b> — {{this.deal}}</li>\n  {{/each}}\n</ul>\n```\n\n### 👨‍💻 For Beginners:\n\n* This turns your data into a **daily email alert**.\n* You can plug in **Gmail, Outlook, Telegram, Slack**, etc.\n* Use this to stay updated or forward to your group of friends or a Discord bot.\n\n---\n\n## ✨ Final Thoughts\n\n| ✅ Feature                    | 💡 Benefit                              |\n| ---------------------------- | --------------------------------------- |\n| Fully visual                 | No coding knowledge needed              |\n| Web Unlocker via Bright Data | Access any site without getting blocked |\n| HTML Extraction              | Pull exactly what you need              |\n| Email Integration            | Automatically get results               |\n\nThis is a **production-grade workflow** that’s easy to understand, scalable, and customizable for other food types, locations, or platforms.\n\n---\n\n"},"typeVersion":1},{"id":"acfcd516-583b-49d9-a5ca-d610761e8ef4","name":"Fetch Uber Eats Search Page (Bright Data)","type":"n8n-nodes-base.httpRequest","position":[-140,680],"parameters":{"url":"https://api.brightdata.com/request","method":"POST","options":{},"sendBody":true,"sendHeaders":true,"bodyParameters":{"parameters":[{"name":"zone","value":"n8n_unblocker"},{"name":"url","value":"=https://www.ubereats.com/feed?diningMode=DELIVERY&pl=JTdCJTIyYWRkcmVzcyUyMiUzQSUyMkxvcyUyMEFuZGVzJTIwQmFrZXJ5JTIyJTJDJTIycmVmZXJlbmNlJTIyJTNBJTIyZDM2NThkYmItODRhNi1kMTRhLWMyNWEtNTBkZWVjMTRmY2RmJTIyJTJDJTIycmVmZXJlbmNlVHlwZSUyMiUzQSUyMnViZXJfcGxhY2VzJTIyJTJDJTIybGF0aXR1ZGUlMjIlM0EzMy44Nzk0NiUyQyUyMmxvbmdpdHVkZSUyMiUzQS04NC4zMDc5NCU3RA%3D%3D&scq=Pizza&sf=JTVCJTdCJTIydXVpZCUyMiUzQSUyMjMzZTBmN2NjLTg5MjctNGRhYy1hOTJlLTE5YTI5NmFhYjA5NyUyMiUyQyUyMm9wdGlvbnMlMjIlM0ElNUIlN0IlMjJ1dWlkJTIyJTNBJTIyZzk5NjQ3NmMtMmIxYi00ZGIyLWI0MGEtMTNkNDNjYjExN2RjJTIyJTdEJTVEJTdEJTVE"},{"name":"country","value":"us"},{"name":"format","value":"raw"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2},{"id":"0cea9a9b-5ccc-4ca9-8a2c-ab453206c88d","name":"Extract Names & Deals","type":"n8n-nodes-base.html","position":[160,680],"parameters":{"options":{},"operation":"extractHtmlContent","extractionValues":{"values":[{"key":"deak","cssSelector":"<div class=\"be f3 bg f2 ck bp bn k2\">Domino's</div>","returnArray":true},{"key":"Deal","cssSelector":"<div class=\"hr bn k2\">Free Item (Spend $9)</div>","returnArray":true}]}},"typeVersion":1.2},{"id":"802b5bac-0327-4fe3-8cbb-125af2912e06","name":"Send Pizza Deals via Gmail","type":"n8n-nodes-base.gmail","position":[480,680],"webhookId":"0d3a724c-e4b6-410a-b0f7-e6c7a342d629","parameters":{"sendTo":"shahkar.genai@gmail.com","message":"=Hey there! 👋\n\nHere are the best pizza deals we found near your location:\n\n🍱 Title: {{ $json.deak[0] }}\n🎉 Deal: {{ $json.Deal[0] }}\n\nWe’ve scanned the menu data for you using our smart scraper automation.","options":{},"subject":"=Best Pizza Deals Near You Today!","emailType":"text"},"credentials":{"gmailOAuth2":{"id":"AQDSl75AdzK3vmqJ","name":"Gmail account"}},"typeVersion":2.1},{"id":"6bb11eed-0b93-460e-be4a-bcce086fc5a5","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-440,-160],"parameters":{"color":3,"width":460,"height":1060,"content":"## 🟢 **SECTION 1: 🔁 Trigger & 🌍 Fetch Pizza Deals Page**\n\n### 🔹 Nodes Included:\n\n1. ⚡ **Trigger Workflow**\n2. 🌐 **Fetch Uber Eats Search Page (Bright Data)**\n\n---\n\n### 🔧 What Happens Here:\n\n* **⚡ Trigger Workflow**: This node is the starting point. You can configure it to run:\n\n  * On-demand (when you click \"Execute\")\n  * On a schedule (e.g., every morning or every 4 hours)\n\n* **🌐 Fetch Uber Eats Search Page**:\n\n  * Sends a `POST` request to **Bright Data’s Web Unlocker API** to access UberEats.\n  * It bypasses JavaScript-heavy pages and bot protections.\n  * URL targeted: something like `https://www.ubereats.com/search?query=pizza`\n  * Returns full HTML of the results page with all pizza restaurant names and their deals.\n\n### 👨‍💻 For Beginners:\n\n* This is the **scraping engine** of your workflow.\n* Bright Data does the heavy lifting (proxying, unblocking, rendering).\n* You only need to provide your **Bright Data API key** and the target URL.\n\n---\n\n"},"typeVersion":1},{"id":"b02aa18f-809e-4aec-9969-b1a30546a936","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[60,-320],"parameters":{"color":5,"width":300,"height":1220,"content":"## 🟡 **SECTION 2: 🧹 Extract Pizza Names & Deals**\n\n### 🔹 Node Included:\n\n* 🧩 **Extract Names & Deals**\n\n---\n\n### 🔧 What Happens Here:\n\n* This is the **HTML Extract** node.\n* It scans the raw HTML from the previous step and pulls:\n\n  * 🏷️ Restaurant names (e.g., “Domino’s”)\n  * 💸 Deals or special offers (e.g., “Free Item on \\$9 Spend”)\n\n### 🛠️ CSS Selectors Used:\n\n* **Name Selector**: `div.be.f3.bg.f2.ck.bp.bn.k2` → extracts all names\n* **Deal Selector**: `div.hr.bn.k2` → extracts all visible deals\n\n⚙️ You configure it to **get all matches**, not just one. This ensures multiple restaurants are included.\n\n### 👨‍💻 For Beginners:\n\n* This is where **the magic happens** — HTML becomes readable data.\n* No coding is required — just CSS selectors you can get from “Inspect Element” in Chrome.\n* You can reuse this for other platforms like DoorDash or Grubhub by updating the selectors.\n\n---\n\n"},"typeVersion":1},{"id":"09f351ad-1911-40ce-9d93-c8e8880c45cd","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[400,-20],"parameters":{"color":6,"width":300,"height":920,"content":"## 🔴 **SECTION 3: 📧 Send Best Deals via Gmail**\n\n### 🔹 Node Included:\n\n* ✉️ **Send Pizza Deals via Gmail**\n\n---\n\n### 🔧 What Happens Here:\n\n* Sends you an email (or to any recipient you define).\n* The email includes:\n\n  * 🧾 List of pizza restaurants\n  * 🎁 Associated deals\n\n📬 You can customize the subject and message format using simple templates:\n\n```html\n<h3>🍕 Today’s Top Pizza Deals</h3>\n<ul>\n  {{#each items}}\n    <li><b>{{this.title}}</b> — {{this.deal}}</li>\n  {{/each}}\n</ul>\n```\n"},"typeVersion":1},{"id":"f8c0655a-9550-488d-a9d9-592f95a193f9","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[760,-20],"parameters":{"color":7,"width":380,"height":240,"content":"## I’ll receive a tiny commission if you join Bright Data through this link—thanks for fueling more free content!\n\n### https://get.brightdata.com/1tndi4600b25"},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"31760015-fb12-44ab-bd99-c7688ec0fd6b","connections":{"Trigger Workflow":{"main":[[{"node":"Fetch Uber Eats Search Page (Bright Data)","type":"main","index":0}]]},"Extract Names & Deals":{"main":[[{"node":"Send Pizza Deals via Gmail","type":"main","index":0}]]},"Fetch Uber Eats Search Page (Bright Data)":{"main":[[{"node":"Extract Names & Deals","type":"main","index":0}]]}}}


name: Automated Freelance Gig Finder with Bright Data & n8n
author_name: Yaron Been
author_username: yaron-nofluff
nodes_used: ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest","n8n-nodes-base.html"]
categories: []
created_at: 2025-06-24T15:52:46.171Z
updated_at: 2025-06-24T15:52:46.171Z
url: https://n8n.io/workflows/5214
scraped_at: 2025-07-06 21:16:30
description:
  Description

  This workflow automatically searches multiple freelance platforms for new gigs matching your skills and requirements. It saves you time by eliminating the need to manually check multiple job boards and sends you alerts for relevant opportunities.

  Overview

  This workflow automatically scrapes freelance job boards and platforms for new gigs matching your skills and requirements. It uses Bright Data to access job listings and can notify you of new opportunities or save them to a database.

  Tools Used

  n8n:** The automation platform that orchestrates the workflow.
  Bright Data:** For scraping freelance platforms like Upwork, Fiverr, Freelancer, etc. without getting blocked.
  (Optional) Email/Slack/Database:** For notifications or data storage.

  How to Install

  Import the Workflow: Download the .json file and import it into your n8n instance.
  Configure Bright Data: Add your Bright Data credentials to the Bright Data node.
  Set Up Notifications: Configure how you want to receive job alerts.
  Customize: Add your skills, rate requirements, and other filters.

  Use Cases

  Freelancers:** Get notified of new gigs matching your skills.
  Agencies:** Monitor job boards for potential client opportunities.
  Remote Workers:** Track new remote job postings across multiple platforms.

  Connect with Me

  Website:** https://www.nofluff.online
  YouTube:** https://www.youtube.com/@YaronBeen/videos
  LinkedIn:** https://www.linkedin.com/in/yaronbeen/
  Get Bright Data:** https://get.brightdata.com/1tndi4600b25 (Using this link supports my free workflows with a small commission)

  #n8n #automation #freelance #brightdata #webscraping #remotework #freelancejobs #gigeconomy #upwork #fiverr #freelancer #jobsearch #remotejobs #freelanceopportunities #n8nworkflow #workflow #nocode #jobhunting #freelancegigs #jobscraper #jobnotifications #freelancecareer #digitalnomad #workfromhome #jobopportunities #freelancetools #jobmonitoring #freelancesuccess

workflow_json:
  {"id":"HyNR7wCUHOWoSMB1","meta":{"instanceId":"60046904b104f0f72b2629a9d88fe9f676be4035769f1f08dad1dd38a76b9480","templateCredsSetupCompleted":true},"name":"Automated_Freelance_Gig_Scraper_via_Bright_data","tags":[],"nodes":[{"id":"ca434966-ab56-4335-88ea-c066a3a33cf4","name":"Run Scraper Daily","type":"n8n-nodes-base.scheduleTrigger","position":[1720,1400],"parameters":{"rule":{"interval":[{"triggerAtHour":9}]}},"typeVersion":1.2},{"id":"f5446f3e-3eaf-44ac-b363-1fd61da36512","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[0,0],"parameters":{"color":4,"width":1300,"height":320,"content":"=======================================\n            WORKFLOW ASSISTANCE\n=======================================\nFor any questions or support, please contact:\n    Yaron@nofluff.online\n\nExplore more tips and tutorials here:\n   - YouTube: https://www.youtube.com/@YaronBeen/videos\n   - LinkedIn: https://www.linkedin.com/in/yaronbeen/\n=======================================\n"},"typeVersion":1},{"id":"b7e24008-ca38-4d8a-b17c-57a979307618","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[0,340],"parameters":{"color":4,"width":1289,"height":3418,"content":"# 🚀 **Automated Daily Job Scraper Workflow**\n\nThis automation scrapes new job gigs from **We Work Remotely (WWR)** daily based on your preferred skill, extracts job information, and appends it neatly into a **Google Sheet** — all without lifting a finger! Let’s break it down into 3 easy-to-understand sections:\n\n---\n\n## 🔹 **SECTION 1: Trigger + Set Your Filter**\n\n> *Automate and personalize your job search.*\n\n### 🕒 1. Run Scraper Daily\n\n**Node Type**: Trigger\n**Purpose**: Automatically runs the workflow every 24 hours.\n**How it helps**:\nNo manual work needed! The automation ensures the job list is updated daily without you having to remember anything.\n\n🔧 **Icon Tip**:\n`⚡` = Trigger\n`⏰` = Time-based action\n\n---\n\n### 🖋️ 2. Set Skill Filter\n\n**Node Type**: Manual Input / Set Node\n**Purpose**: Define the specific skill (e.g., “Python”, “UI/UX”) you want to search gigs for.\n**How it helps**:\nYou control what kind of job gigs to track. Want only \"React\" jobs? Just set it once and forget.\n\n🧠 **Beginner Tip**:\nThink of this as setting the topic for your daily newsletter — you get exactly what you’re interested in.\n\n🔧 **Icon Tip**:\n`🖋️` = Skill Input or Filter Logic\n\n---\n\n## 🌐 **SECTION 2: Scraping & Extraction**\n\n> *Fetch real job listings based on your criteria.*\n\n### 🌍 3. Scrape WWR with Bright Data\n\n**Node Type**: HTTP Request\n**Purpose**: Uses the Bright Data Web Unlocker to visit the We Work Remotely website and fetch HTML data of job postings.\n**How it helps**:\nBy using Bright Data, you're bypassing bot detection and scraping like a pro without writing a single line of code.\n\n🔧 **Icon Tip**:\n`🌐` = API/Web scraper\n\n🔐 **Beginner Tip**:\nBright Data makes sure you're not blocked while scraping websites that usually don’t allow bots.\n\n---\n\n### 🧾 4. Extract Jobs from HTML\n\n**Node Type**: Code / Extraction\n**Purpose**: Converts raw HTML into structured job information (like job title, company, and link).\n**How it helps**:\nNo need to look at complicated HTML. This step cleans and formats the data into something meaningful and usable.\n\n🔧 **Icon Tip**:\n`🖥️📄` or `</>` = HTML parser\n\n🧠 **Beginner Tip**:\nThis is like taking a messy newspaper and extracting only the job ads you care about.\n\n---\n\n## 📊 **SECTION 3: Save to Google Sheets**\n\n> *Turn your daily gigs into a growing list you can use and filter anytime.*\n\n### 📄 5. Save Gigs to Google Sheets\n\n**Node Type**: Google Sheets\n**Purpose**: Appends each new gig to a Google Sheet in your Drive.\n**How it helps**:\nYou now have a daily updating list of remote jobs — ready to view, sort, and apply from one place.\n\n📌 **Icon Tip**:\n`📄🟩` = Google Sheets\n\n🧠 **Beginner Tip**:\nThis becomes your personal remote job tracker that updates itself daily!\n\n---\n\n## 💡 **How Beginners Can Take Advantage**\n\n1. **Zero Code Needed**: All done visually in tools like n8n – no programming background required.\n2. **Customization Friendly**: Just change the skill filter to get different job types.\n3. **Scalable**: Add more job boards or filters in future.\n4. **Saves Hours**: No need to visit sites daily or manually copy job info.\n5. **Great for Freelancers, Students & Job Seekers**.\n\n---\n\n## 🌟 Final Summary (With Emojis for Fun)\n\n| Step | Node           | Emoji | Description                           |\n| ---- | -------------- | ----- | ------------------------------------- |\n| 1    | Run Daily      | ⏰     | Automatically starts every day        |\n| 2    | Set Skill      | 🖋️   | Choose what skill to search jobs for  |\n| 3    | Scrape WWR     | 🌐    | Uses Bright Data to grab job postings |\n| 4    | Extract HTML   | 🧾    | Converts raw HTML to structured data  |\n| 5    | Save to Sheets | 📊    | Appends new jobs to a Google Sheet    |\n\n---\n\n\n"},"typeVersion":1},{"id":"a83a04d5-6bec-4c7e-8d8d-538c4957a9c8","name":"Set Skill Filter","type":"n8n-nodes-base.set","position":[1960,1400],"parameters":{"options":{},"assignments":{"assignments":[{"id":"442d4787-7045-46e7-a86a-ccc522413ac9","name":"Skills","type":"string","value":"AI"}]}},"typeVersion":3.4},{"id":"33e2c73b-41e4-4f60-9b6c-4c954cc7e856","name":"Scrape WWR with Bright Data","type":"n8n-nodes-base.httpRequest","position":[2200,1400],"parameters":{"url":"https://api.brightdata.com/request","method":"POST","options":{},"sendBody":true,"sendHeaders":true,"bodyParameters":{"parameters":[{"name":"zone","value":"n8n_unblocker"},{"name":"url","value":"=https://weworkremotely.com/remote-jobs/search?term={{ $json.Skills }}"},{"name":"country","value":"us"},{"name":"format","value":"raw"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2},{"id":"23709278-a9bb-4b46-a418-62a15c49f6ab","name":"Extract Jobs from HTML","type":"n8n-nodes-base.html","position":[2420,1400],"parameters":{"options":{},"operation":"extractHtmlContent","extractionValues":{"values":[{"key":"Job","cssSelector":"#category-18 > article > ul > li.new-listing-container.feature > a > div > div.new-listing__header > h4"},{"key":"Company","cssSelector":"#category-18 > article > ul > li.new-listing-container.feature > a > div > p.new-listing__company-name"},{"key":"Country","cssSelector":"#category-18 > article > ul > li.new-listing-container.feature > a > div > p.new-listing__company-headquarters"}]}},"typeVersion":1.2},{"id":"564c4101-2929-49fe-a651-134a0addfe35","name":"Save Jobs to Google Sheets","type":"n8n-nodes-base.googleSheets","position":[2720,1400],"parameters":{"columns":{"value":{"Job":"={{ $json.Job }}","Company":"={{ $json.Company }}","Location":"={{ $json.Country }}"},"schema":[{"id":"Job","type":"string","display":true,"required":false,"displayName":"Job","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Company","type":"string","display":true,"required":false,"displayName":"Company","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Location","type":"string","display":true,"required":false,"displayName":"Location","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"append","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/14JmN5gkBRW6Vgevf2oNXXvEuZXPwBCk4JxQqEfJOHSw/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"14JmN5gkBRW6Vgevf2oNXXvEuZXPwBCk4JxQqEfJOHSw","cachedResultUrl":"https://docs.google.com/spreadsheets/d/14JmN5gkBRW6Vgevf2oNXXvEuZXPwBCk4JxQqEfJOHSw/edit?usp=drivesdk","cachedResultName":"weworkremotely jobs"}},"credentials":{"googleSheetsOAuth2Api":{"id":"r2mDaisH6e9VkwHl","name":"Google Sheets account"}},"typeVersion":4.5},{"id":"3354904f-1735-4e89-a0a8-1914f707ee8b","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1700,-20],"parameters":{"color":6,"width":380,"height":1640,"content":"## 🔹 **SECTION 1: Trigger + Set Your Filter**\n\n> *Automate and personalize your job search.*\n\n### 🕒 1. Run Scraper Daily\n\n**Node Type**: Trigger\n**Purpose**: Automatically runs the workflow every 24 hours.\n**How it helps**:\nNo manual work needed! The automation ensures the job list is updated daily without you having to remember anything.\n\n🔧 **Icon Tip**:\n`⚡` = Trigger\n`⏰` = Time-based action\n\n---\n\n### 🖋️ 2. Set Skill Filter\n\n**Node Type**: Manual Input / Set Node\n**Purpose**: Define the specific skill (e.g., “Python”, “UI/UX”) you want to search gigs for.\n**How it helps**:\nYou control what kind of job gigs to track. Want only \"React\" jobs? Just set it once and forget.\n\n🧠 **Beginner Tip**:\nThink of this as setting the topic for your daily newsletter — you get exactly what you’re interested in.\n\n🔧 **Icon Tip**:\n`🖋️` = Skill Input or Filter Logic\n\n---\n\n"},"typeVersion":1},{"id":"302ea26f-4b92-41c2-9859-17a937f7b141","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[2140,-160],"parameters":{"color":5,"width":420,"height":1780,"content":"## 🌐 **SECTION 2: Scraping & Extraction**\n\n> *Fetch real job listings based on your criteria.*\n\n### 🌍 3. Scrape WWR with Bright Data\n\n**Node Type**: HTTP Request\n**Purpose**: Uses the Bright Data Web Unlocker to visit the We Work Remotely website and fetch HTML data of job postings.\n**How it helps**:\nBy using Bright Data, you're bypassing bot detection and scraping like a pro without writing a single line of code.\n\n🔧 **Icon Tip**:\n`🌐` = API/Web scraper\n\n🔐 **Beginner Tip**:\nBright Data makes sure you're not blocked while scraping websites that usually don’t allow bots.\n\n---\n\n### 🧾 4. Extract Jobs from HTML\n\n**Node Type**: Code / Extraction\n**Purpose**: Converts raw HTML into structured job information (like job title, company, and link).\n**How it helps**:\nNo need to look at complicated HTML. This step cleans and formats the data into something meaningful and usable.\n\n🔧 **Icon Tip**:\n`🖥️📄` or `</>` = HTML parser\n\n🧠 **Beginner Tip**:\nThis is like taking a messy newspaper and extracting only the job ads you care about.\n\n---\n\n"},"typeVersion":1},{"id":"a789140f-8006-4cae-ad40-0e595052b0d9","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[2620,420],"parameters":{"color":3,"width":300,"height":1200,"content":"## 📊 **SECTION 3: Save to Google Sheets**\n\n> *Turn your daily gigs into a growing list you can use and filter anytime.*\n\n### 📄 5. Save Gigs to Google Sheets\n\n**Node Type**: Google Sheets\n**Purpose**: Appends each new gig to a Google Sheet in your Drive.\n**How it helps**:\nYou now have a daily updating list of remote jobs — ready to view, sort, and apply from one place.\n\n📌 **Icon Tip**:\n`📄🟩` = Google Sheets\n\n🧠 **Beginner Tip**:\nThis becomes your personal remote job tracker that updates itself daily!\n\n---\n\n"},"typeVersion":1},{"id":"1c541cd3-09f3-4534-b6cb-53027d87873b","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[3020,420],"parameters":{"color":7,"width":380,"height":240,"content":"## I’ll receive a tiny commission if you join Bright Data through this link—thanks for fueling more free content!\n\n### https://get.brightdata.com/1tndi4600b25"},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"860467ec-cde7-45f3-aab5-814a1cab069f","connections":{"Set Skill Filter":{"main":[[{"node":"Scrape WWR with Bright Data","type":"main","index":0}]]},"Run Scraper Daily":{"main":[[{"node":"Set Skill Filter","type":"main","index":0}]]},"Extract Jobs from HTML":{"main":[[{"node":"Save Jobs to Google Sheets","type":"main","index":0}]]},"Scrape WWR with Bright Data":{"main":[[{"node":"Extract Jobs from HTML","type":"main","index":0}]]}}}


name: Automate Social Media Headlines with Bright Data & n8n
author_name: Yaron Been
author_username: yaron-nofluff
categories: []
created_at: 2025-06-24T15:53:15.239Z
updated_at: 2025-06-24T15:53:15.239Z
url: https://n8n.io/workflows/5215
scraped_at: 2025-07-06 21:16:30
description:
  Description

  This workflow automatically finds trending headlines and content from various sources and posts them to your social media accounts. It helps maintain an active social media presence without the daily manual effort of content curation.

  Overview

  This workflow automatically scrapes trending headlines and content from various sources and posts them to your social media accounts. It uses Bright Data to access content and n8n to schedule and post to platforms like Twitter, LinkedIn, or Facebook.

  Tools Used

  n8n:** The automation platform that orchestrates the workflow.
  Bright Data:** For scraping trending content from news sites, blogs, or other sources without getting blocked.
  Social Media APIs:** To post content to your accounts.

  How to Install

  Import the Workflow: Download the .json file and import it into your n8n instance.
  Configure Bright Data: Add your Bright Data credentials to the Bright Data node.
  Connect Social Media: Authenticate your social media accounts.
  Customize: Set your content preferences, posting schedule, and hashtag strategy.

  Use Cases

  Social Media Managers:** Automate content curation and posting.
  Content Creators:** Share trending topics in your niche.
  Businesses:** Maintain an active social media presence with minimal effort.

  Connect with Me

  Website:** https://www.nofluff.online
  YouTube:** https://www.youtube.com/@YaronBeen/videos
  LinkedIn:** https://www.linkedin.com/in/yaronbeen/
  Get Bright Data:** https://get.brightdata.com/1tndi4600b25 (Using this link supports my free workflows with a small commission)

  #n8n #automation #socialmedia #brightdata #contentcuration #scheduling #socialmediaautomation #contentmarketing #socialmediamanagement #autoposting #trendingcontent #n8nworkflow #workflow #nocode #socialmediatools #digitalmarketing #contentcalendar #socialmediapresence #headlinecuration #trendalerts #socialmediaschedule #contentautomation #socialmediamarketing #contentdistribution #automatedposting #socialmediastrategy

nodes_used:
  ["n8n-nodes-base.httpRequest","n8n-nodes-base.twitter","n8n-nodes-base.linkedIn","n8n-nodes-base.html","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatOpenAi"]

workflow_json:
  {"id":"u2mAzsvf9Aj0k3Ux","meta":{"instanceId":"60046904b104f0f72b2629a9d88fe9f676be4035769f1f08dad1dd38a76b9480"},"name":"Automated_Social_Media_Headline_Poster_via_Bright_data","tags":[],"nodes":[{"id":"22814b65-765e-48c3-98c2-00982b74e70e","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[3000,900],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"8sEyPDkC5p4w4Jha","name":"OpenAi account"}},"typeVersion":1.2},{"id":"0fd15cfb-7564-4db3-bdb0-b0a32b69c4fb","name":"LinkedIn post writer","type":"@n8n/n8n-nodes-langchain.agent","position":[2980,680],"parameters":{"text":"={{ $json.Title }}","options":{"systemMessage":"Extract the headline and write a post for LinkedIn based on the headline"},"promptType":"define"},"typeVersion":1.9},{"id":"aac3869f-9f8e-49b0-bdc9-9eae0921474c","name":"Run workflow","type":"n8n-nodes-base.manualTrigger","position":[1960,680],"parameters":{},"typeVersion":1},{"id":"a5187a0d-25b8-45d4-8578-4ad51397ab41","name":"Set Target News URL","type":"n8n-nodes-base.set","position":[2180,680],"parameters":{"options":{},"assignments":{"assignments":[{"id":"2c5f11b0-9f25-4b30-b0a0-1080fd33e7d4","name":"SIte","type":"string","value":"Vogue"},{"id":"65be4ab3-6cef-4f70-9cb9-e9753fbf7543","name":"URL","type":"string","value":"https://www.vogue.com/fashion"}]}},"typeVersion":3.4},{"id":"79362a39-b73d-4f40-bdee-780d78abfae6","name":"Publish to LinkedIn","type":"n8n-nodes-base.linkedIn","position":[3360,680],"parameters":{"text":"={{ $json.output }}","additionalFields":{}},"typeVersion":1},{"id":"fbf2c950-fd2c-4aa3-9e24-45d171f1056b","name":"Publish to X (Twitter)","type":"n8n-nodes-base.twitter","position":[3980,680],"parameters":{"text":"={{ $json.output }}","additionalFields":{}},"typeVersion":2},{"id":"7f4e4da6-3611-496b-a4bc-93daa1d9039f","name":"X (Twitter) post writer","type":"@n8n/n8n-nodes-langchain.agent","position":[3620,680],"parameters":{"text":"={{ $('Extract Title').item.json.Title }}","options":{"systemMessage":"Extract the headline and write a post for Twitter based on the headline"},"promptType":"define"},"typeVersion":1.9},{"id":"7b730fa3-5c0a-422f-8de5-f713b2f945ab","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[0,0],"parameters":{"color":4,"width":1300,"height":320,"content":"=======================================\n            WORKFLOW ASSISTANCE\n=======================================\nFor any questions or support, please contact:\n    Yaron@nofluff.online\n\nExplore more tips and tutorials here:\n   - YouTube: https://www.youtube.com/@YaronBeen/videos\n   - LinkedIn: https://www.linkedin.com/in/yaronbeen/\n=======================================\n"},"typeVersion":1},{"id":"defc9ec0-917a-4020-940b-9cb926a3a582","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[0,340],"parameters":{"color":4,"width":1289,"height":3418,"content":"# ⚡ Automated Vogue Headline → Social Media Poster\n\n### 🧠 Purpose:\n\nAutomatically scrape trending headlines from Vogue, convert them into engaging posts using AI, and publish them to **LinkedIn** and **Twitter (X)** — *no manual effort needed*.\n\n---\n\n## 🔶 **Section 1: Set the Target Source**\n\n📌 *Nodes:*\n\n* `Run workflow`\n* `Set Target News URL`\n\n### 🛠 What’s Happening:\n\n* ✅ `Run workflow`: Triggers the automation either manually or on a schedule (e.g., daily).\n* 🖊 `Set Target News URL`: Sets the **source URL** (e.g., `https://www.vogue.com/fashion`) from where the headlines will be scraped.\n\n### 💡 Why It Matters:\n\nThis lets you choose your news source dynamically. You could even expand this later for other websites like *TechCrunch, Forbes, etc.*\n\n> ![🧭](https://em-content.zobj.net/thumbs/120/apple/354/compass_1f9ed.png) Think of this section as the **GPS** – it tells the system where to go fetch the news from.\n\n---\n\n## 🔷 **Section 2: Scrape & Extract Headlines**\n\n📌 *Nodes:*\n\n* `Scrape Vogue via Bright Data`\n* `Extract Title`\n\n### 🛠 What’s Happening:\n\n* 🌐 `Scrape Vogue via Bright Data`: Uses **Bright Data Web Unlocker** to bypass bot protection and get the full HTML of the Vogue page using a POST request.\n* 🧾 `Extract Title`: Extracts the headline(s) from the HTML using a CSS selector like `.article-feed-card__hed-text`.\n\n### 💡 Why It Matters:\n\nSome websites block scraping — **Bright Data** ensures you can reliably extract content. The extractor node ensures you get clean, usable text.\n\n> ![🕸️](https://em-content.zobj.net/thumbs/120/apple/354/spider-web_1f578-fe0f.png) This is your **web crawler** and **filter**, doing the dirty work of fetching and cleaning up info.\n\n---\n\n## 🟣 **Section 3: Use AI to Write Engaging Posts**\n\n📌 *Nodes:*\n\n* `LinkedIn post writer`\n* `X (Twitter) post writer`\n\n### 🛠 What’s Happening:\n\n* 🤖 `LinkedIn post writer`: Passes the headline to an OpenAI Chat Model to turn it into a professional, catchy LinkedIn post.\n* 🐦 `X (Twitter) post writer`: Similarly formats a shorter, witty version for X/Twitter.\n\nBoth use prompts like:\n\n> “Write a trendy post about the following Vogue headline for \\[LinkedIn/Twitter]. Add hashtags. Keep tone professional/casual.”\n\n### 💡 Why It Matters:\n\nAI tailors each post **per platform** — no copy-pasting. Your brand voice is preserved while staying context-aware.\n\n> ![✍️](https://em-content.zobj.net/thumbs/120/apple/354/writing-hand_270d-fe0f.png) This is your **copywriting intern** — except it works 24/7 and never gets tired.\n\n---\n\n## 🔴 **Section 4: Auto-Publish to Social Media**\n\n📌 *Nodes:*\n\n* `Publish to LinkedIn`\n* `Publish to X (Twitter)`\n\n### 🛠 What’s Happening:\n\n* 💼 `Publish to LinkedIn`: Posts the AI-generated content directly to your **LinkedIn page or profile**.\n* 📣 `Publish to X (Twitter)`: Tweets the optimized content via your **Twitter developer account**.\n\n> Note: These nodes are showing ⚠️ errors — make sure authentication and permissions (tokens) are set up correctly.\n\n### 💡 Why It Matters:\n\nThis eliminates **manual social media posting** — great for content marketers, personal branding, or agencies.\n\n> ![🚀](https://em-content.zobj.net/thumbs/120/apple/354/rocket_1f680.png) This section is your **launchpad**, sending your posts to the world.\n\n---\n\n# 🧩 Summary Table\n\n| Section | Function                     | What It Does                                     | Key Tools                      |\n| ------- | ---------------------------- | ------------------------------------------------ | ------------------------------ |\n| 1       | Set Target URL               | Tells the system what site to scrape             | `Manual Trigger`, `Set Node`   |\n| 2       | Scrape & Extract             | Uses Bright Data to get HTML + Extract headlines | `HTTP Request`, `HTML Extract` |\n| 3       | AI Content Generation        | Converts headline into social media post         | `OpenAI`, `Chat Model`         |\n| 4       | Auto-Publish to Social Media | Posts to LinkedIn and Twitter                    | `LinkedIn`, `X/Twitter`        |\n\n---\n\n# ✨ Bonus Suggestions\n\n✅ Add a **scheduler** to run this daily\n✅ Log posted headlines in **Google Sheets or Notion**\n✅ Add a filter to **skip duplicate headlines**\n\n---\n\n\n"},"typeVersion":1},{"id":"490c2efe-0d1e-408c-806c-5e3a48f61264","name":"Scrape Vogue via Bright data","type":"n8n-nodes-base.httpRequest","position":[2480,680],"parameters":{"url":"https://api.brightdata.com/request","method":"POST","options":{},"sendBody":true,"sendHeaders":true,"bodyParameters":{"parameters":[{"name":"zone","value":"n8n_unblocker"},{"name":"url","value":"={{ $json.URL }}"},{"name":"country","value":"us"},{"name":"format","value":"raw"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2},{"id":"a7a4f66f-b5a8-4563-a306-57b72c1ac0a1","name":"Extract Title","type":"n8n-nodes-base.html","position":[2720,680],"parameters":{"options":{},"operation":"extractHtmlContent","extractionValues":{"values":[{"key":"Title","cssSelector":"#\\35 f10df145161a26b33fec09b > div > div > div > div.SummaryItemWrapper-iwvBff.juTBkb.summary-item.summary-item--no-icon.summary-item--text-align-center.summary-item--layout-placement-text-below.summary-item--layout-position-image-left.summary-item--layout-proportions-50-50.summary-item--side-by-side-align-center.summary-item--side-by-side-image-right-mobile-false.summary-item--standard.SummaryCollageFiveItem-kWJUcr.fqnbhT.search_result_item-68507588d2b17faf259ac70e.undefined_summary_item-68507588d2b17faf259ac70e > div.SummaryItemContent-eiDYMl.fSburJ.summary-item__content > a > h3"}]}},"typeVersion":1.2},{"id":"f4d2614f-ddf7-48ea-83cc-7f7675ca35be","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[1940,-40],"parameters":{"color":5,"width":380,"height":920,"content":"## 🔶 **Section 1: Set the Target Source**\n\n📌 *Nodes:*\n\n* `Run workflow`\n* `Set Target News URL`\n\n### 🛠 What’s Happening:\n\n* ✅ `Run workflow`: Triggers the automation either manually or on a schedule (e.g., daily).\n* 🖊 `Set Target News URL`: Sets the **source URL** (e.g., `https://www.vogue.com/fashion`) from where the headlines will be scraped.\n\n### 💡 Why It Matters:\n\nThis lets you choose your news source dynamically. You could even expand this later for other websites like *TechCrunch, Forbes, etc.*\n\n> ![🧭](https://em-content.zobj.net/thumbs/120/apple/354/compass_1f9ed.png) Think of this section as the **GPS** – it tells the system where to go fetch the news from.\n\n---\n"},"typeVersion":1},{"id":"4926a696-817c-417e-86d7-ebb4eacb5c3a","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[2420,-80],"parameters":{"color":7,"width":440,"height":960,"content":"## 🔷 **Section 2: Scrape & Extract Headlines**\n\n📌 *Nodes:*\n\n* `Scrape Vogue via Bright Data`\n* `Extract Title`\n\n### 🛠 What’s Happening:\n\n* 🌐 `Scrape Vogue via Bright Data`: Uses **Bright Data Web Unlocker** to bypass bot protection and get the full HTML of the Vogue page using a POST request.\n* 🧾 `Extract Title`: Extracts the headline(s) from the HTML using a CSS selector like `.article-feed-card__hed-text`.\n\n### 💡 Why It Matters:\n\nSome websites block scraping — **Bright Data** ensures you can reliably extract content. The extractor node ensures you get clean, usable text.\n\n> ![🕸️](https://em-content.zobj.net/thumbs/120/apple/354/spider-web_1f578-fe0f.png) This is your **web crawler** and **filter**, doing the dirty work of fetching and cleaning up info.\n\n---\n\n"},"typeVersion":1},{"id":"aaab5f22-013e-4697-80c5-3fac64a76e6f","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[2940,-80],"parameters":{"color":6,"width":540,"height":1100,"content":"## 🟣 **Section 3: Use AI to Write Engaging Posts**\n\n📌 *Nodes:*\n\n* `LinkedIn post writer`\n* `X (Twitter) post writer`\n\n### 🛠 What’s Happening:\n\n* 🤖 `LinkedIn post writer`: Passes the headline to an OpenAI Chat Model to turn it into a professional, catchy LinkedIn post.\n* 🐦 `X (Twitter) post writer`: Similarly formats a shorter, witty version for X/Twitter.\n\nBoth use prompts like:\n\n> “Write a trendy post about the following Vogue headline for \\[LinkedIn/Twitter]. Add hashtags. Keep tone professional/casual.”\n\n### 💡 Why It Matters:\n\nAI tailors each post **per platform** — no copy-pasting. Your brand voice is preserved while staying context-aware.\n\n> ![✍️](https://em-content.zobj.net/thumbs/120/apple/354/writing-hand_270d-fe0f.png) This is your **copywriting intern** — except it works 24/7 and never gets tired.\n\n---\n\n"},"typeVersion":1},{"id":"fb12e0fa-64e2-4ea3-a01b-8b1204efae2a","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[3580,-60],"parameters":{"color":3,"width":540,"height":940,"content":"## 🔴 **Section 4: Auto-Publish to Social Media**\n\n📌 *Nodes:*\n\n* `Publish to LinkedIn`\n* `Publish to X (Twitter)`\n\n### 🛠 What’s Happening:\n\n* 💼 `Publish to LinkedIn`: Posts the AI-generated content directly to your **LinkedIn page or profile**.\n* 📣 `Publish to X (Twitter)`: Tweets the optimized content via your **Twitter developer account**.\n\n> Note: These nodes are showing ⚠️ errors — make sure authentication and permissions (tokens) are set up correctly.\n\n### 💡 Why It Matters:\n\nThis eliminates **manual social media posting** — great for content marketers, personal branding, or agencies.\n\n> ![🚀](https://em-content.zobj.net/thumbs/120/apple/354/rocket_1f680.png) This section is your **launchpad**, sending your posts to the world.\n\n---\n\n"},"typeVersion":1},{"id":"2ea582b1-c9ac-4a6c-8c39-ec97cd14b6f4","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[4240,-60],"parameters":{"color":7,"width":380,"height":240,"content":"## I’ll receive a tiny commission if you join Bright Data through this link—thanks for fueling more free content!\n\n### https://get.brightdata.com/1tndi4600b25"},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"cb513f17-9010-4f78-bc85-756813814380","connections":{"Run workflow":{"main":[[{"node":"Set Target News URL","type":"main","index":0}]]},"Extract Title":{"main":[[{"node":"LinkedIn post writer","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"LinkedIn post writer","type":"ai_languageModel","index":0},{"node":"X (Twitter) post writer","type":"ai_languageModel","index":0}]]},"Publish to LinkedIn":{"main":[[{"node":"X (Twitter) post writer","type":"main","index":0}]]},"Set Target News URL":{"main":[[{"node":"Scrape Vogue via Bright data","type":"main","index":0}]]},"LinkedIn post writer":{"main":[[{"node":"Publish to LinkedIn","type":"main","index":0}]]},"X (Twitter) post writer":{"main":[[{"node":"Publish to X (Twitter)","type":"main","index":0}]]},"Scrape Vogue via Bright data":{"main":[[{"node":"Extract Title","type":"main","index":0}]]}}}


name: Auto-Sync Local Events to Google Calendar with n8n
author_name: Yaron Been
author_username: yaron-nofluff
categories: []
created_at: 2025-06-24T15:53:39.105Z
updated_at: 2025-06-24T15:53:39.105Z
url: https://n8n.io/workflows/5216
scraped_at: 2025-07-06 21:16:30
description:
  Description

  This workflow automates the process of finding local events and adding them directly to your Google Calendar. It eliminates the need for manual event tracking by automatically scraping event information and creating calendar entries.

  Overview

  This workflow automates the process of finding local events and adding them to your Google Calendar. It uses Bright Data to scrape event information from a specified source and then creates new events in your calendar, ensuring you never miss out on what's happening around you.

  Tools Used

  n8n:** The automation platform that orchestrates the workflow.
  Bright Data:** For scraping event data from websites without getting blocked.
  Google Calendar API:** To create and manage calendar events.

  How to Install

  Import the Workflow: Download the .json file and import it into your n8n instance.
  Configure Bright Data: Add your Bright Data credentials to the Bright Data node.
  Set Up Google Calendar: Authenticate your Google Calendar account in the Google Calendar node.
  Customize: Adjust the workflow to target the specific websites and event types you're interested in.

  Use Cases

  Community Managers:** Keep track of local meetups and community events.
  Event Enthusiasts:** Never miss a concert, festival, or local gathering.
  Marketing Professionals:** Monitor competitor events and industry conferences.

  Connect with Me

  Website:** https://www.nofluff.online
  YouTube:** https://www.youtube.com/@YaronBeen/videos
  LinkedIn:** https://www.linkedin.com/in/yaronbeen/
  Get Bright Data:** https://get.brightdata.com/1tndi4600b25 (Using this link supports my free workflows with a small commission)

  #n8n #automation #googlecalendar #brightdata #webscraping #events #eventautomation #localevents #calendarintegration #eventtracking #n8nworkflow #workflow #nocode #eventmanagement #productivitytools #timemanagement #eventplanning #automatedcalendar #eventdiscovery #techautomation #eventnotifications #eventscheduling #calendarsync #eventorganizer #automatedevents

nodes_used:
  ["n8n-nodes-base.httpRequest","n8n-nodes-base.googleCalendar","n8n-nodes-base.code","n8n-nodes-base.html"]

workflow_json:
  {"id":"y1ZOHX6Zq13C68dP","meta":{"instanceId":"60046904b104f0f72b2629a9d88fe9f676be4035769f1f08dad1dd38a76b9480"},"name":"AutoSync_Local_Events_to_Google_Calendar","tags":[],"nodes":[{"id":"433e4192-599f-4f3d-a251-651b81db4960","name":"Daily Event Sync Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[-2740,220],"parameters":{"rule":{"interval":[{"triggerAtHour":8}]}},"typeVersion":1.2},{"id":"94f20c26-9a90-43ba-8ab1-b1107c17345c","name":"Fetch Event Page (Bright Data)","type":"n8n-nodes-base.httpRequest","position":[-2520,220],"parameters":{"url":"https://api.brightdata.com/request","method":"POST","options":{},"sendBody":true,"sendHeaders":true,"bodyParameters":{"parameters":[{"name":"zone","value":"n8n_unblocker"},{"name":"url","value":"https://www.nypl.org/events/calendar"},{"name":"country","value":"us"},{"name":"format","value":"raw"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2},{"id":"e55c8584-f673-4201-bda7-42cdbadf49bf","name":"Extract Event Data (HTML Parser)","type":"n8n-nodes-base.html","position":[-2220,220],"parameters":{"options":{},"operation":"extractHtmlContent","extractionValues":{"values":[{"key":"Title","cssSelector":".event-title","returnArray":true},{"key":"Location","cssSelector":".event-location","returnArray":true},{"key":"Audience","cssSelector":".event-audience","returnArray":true},{"key":"Time","cssSelector":".event-time","returnArray":true}]}},"typeVersion":1.2},{"id":"48196549-0378-4cd9-8e1d-f289c4b50180","name":"Clean & Format Event Data","type":"n8n-nodes-base.code","position":[-2000,220],"parameters":{"jsCode":"const data = items[0].json;\n\n// Extract arrays\nconst titles = data.Title || [];\nconst locations = data.Location || [];\nconst audiences = data.Audience || [];\nconst rawTimes = data.Time || [];\n\n// Step 1: Remove invalid \"time\" placeholders\nconst invalidTimeLabels = [\"Date/Time\", \"Title/Description\", \"Location\", \"Audience\"];\nconst times = rawTimes.filter(time => !invalidTimeLabels.includes(time.trim()));\n\n// Step 2: Safely calculate number of valid events\nconst eventCount = Math.min(titles.length, locations.length, audiences.length, times.length);\n\n// Helper: Convert \"Today @ 10 AM\" → ISO string with timezone\nfunction parseTimeToISO(rawTime) {\n  const match = rawTime.match(/@ ([0-9]{1,2})(?::([0-9]{2}))?\\s?(AM|PM)/i);\n  const now = new Date();\n\n  if (!match) return null;\n\n  let hour = parseInt(match[1]);\n  const minute = match[2] ? parseInt(match[2]) : 0;\n  const meridian = match[3].toUpperCase();\n\n  if (meridian === \"PM\" && hour !== 12) hour += 12;\n  if (meridian === \"AM\" && hour === 12) hour = 0;\n\n  const start = new Date(now.getFullYear(), now.getMonth(), now.getDate(), hour, minute);\n  const end = new Date(start.getTime() + 60 * 60 * 1000); // 1-hour event\n\n  const offsetMinutes = start.getTimezoneOffset();\n  const offsetHours = Math.floor(Math.abs(offsetMinutes) / 60);\n  const offsetMins = Math.abs(offsetMinutes) % 60;\n  const offsetSign = offsetMinutes > 0 ? \"-\" : \"+\";\n  const offset = `${offsetSign}${String(offsetHours).padStart(2, \"0\")}:${String(offsetMins).padStart(2, \"0\")}`;\n\n  const toISOStringWithOffset = (d) => {\n    const pad = (n) => n.toString().padStart(2, \"0\");\n    return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}:00${offset}`;\n  };\n\n  return {\n    start: toISOStringWithOffset(start),\n    end: toISOStringWithOffset(end),\n  };\n}\n\n// Step 3: Build cleaned and enriched event objects\nconst results = [];\n\nfor (let i = 0; i < eventCount; i++) {\n  const titleText = titles[i];\n  const timeText = times[i]?.trim();\n  const parsedTime = parseTimeToISO(timeText);\n\n  results.push({\n    json: {\n      title: titleText.split('\\n')[0]?.trim(),\n      description: titleText.trim(),\n      location: locations[i]?.trim(),\n      audience: audiences[i]?.trim(),\n      time: timeText,\n      start: { dateTime: parsedTime?.start || null },\n      end: { dateTime: parsedTime?.end || null },\n      sourceUrl: \"https://www.nypl.org\" + (titleText.match(/\\[([^\\]]+)\\]/)?.[1] || '')\n    }\n  });\n}\n\nreturn results;\n"},"typeVersion":2},{"id":"945e912a-609a-42e0-82a4-c3d36623a767","name":"Create Google Calendar Events","type":"n8n-nodes-base.googleCalendar","position":[-1700,220],"parameters":{"end":"={{ $json.end.dateTime }}","start":"={{ $json.start.dateTime }}","calendar":{"__rl":true,"mode":"list","value":"f14d18c7802fe01f77d5200ada9658c96cbc69b3cb9ff7b2914dc63bf6f263e3@group.calendar.google.com","cachedResultName":"Community Events"},"additionalFields":{"attendees":[],"description":"=Title: {{ $json.title }}\nDescription: {{ $json.description }}\nLocation: {{ $json.location }}\nAudience: {{ $json.audience }}\nTime: {{ $json.time }}"}},"credentials":{"googleCalendarOAuth2Api":{"id":"ZiXaTJAXCcyzY5iy","name":"Google Calendar account"}},"typeVersion":1.3},{"id":"6c5825a7-6a1e-485c-820b-ed4188c6b718","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-2800,-540],"parameters":{"color":5,"width":440,"height":980,"content":"## 🧭 **Section 1: Event Data Fetcher**\n\n### 🔁 `🕒 Daily Event Sync Trigger`\n\n> **Node:** *Schedule Trigger*\n> ⏰ This node sets **when** your automation runs. For example, you might want it to run every morning at 8:00 AM to check for new community events.\n\n🔍 Why it matters:\n\n> This ensures your public calendar is always up to date without manual work.\n\n---\n\n### 🌐 `🌐 Fetch Event Page (Bright Data)`\n\n> **Node:** *HTTP Request using Bright Data Web Unlocker*\n> 🛡 This node sends a request to a **local government or library event page** using Bright Data’s **Web Unlocker proxy**, which helps bypass blocks or bot detection.\n\n🔧 What’s special here:\n\n* It uses your **Bright Data proxy zone**\n* It targets a public events URL (e.g., a `.gov` or `.org`)\n* Makes sure you get the raw HTML page — even if the site tries to hide it\n\n✅ Benefit:\n\n> This lets you scrape data reliably from websites that are normally hard to reach for bots.\n\n---\n\n"},"typeVersion":1},{"id":"aa5624b4-6c2e-4d70-a05b-4e038ee82dfb","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-2300,-660],"parameters":{"color":3,"width":440,"height":1100,"content":"## 🧩 **Section 2: Smart Event Extractor**\n\n### 🧩 `🧩 Extract Event Data (HTML Parser)`\n\n> **Node:** *HTML*\n> 📄 This node parses the raw HTML response from the website and extracts useful information like:\n\n* 🏷 Event Titles\n* 📍 Locations\n* 👥 Target Audience\n* ⏰ Raw Times\n\nIt uses selectors (like CSS) to grab content from specific parts of the page.\n\n🎯 Goal:\n\n> Transform messy website code into **structured data** you can actually use.\n\n---\n\n### 🧠 `🧠 Clean & Format Event Data`\n\n> **Node:** *Code*\n> 🧼 This is the brain of your workflow. It takes the raw extracted data and:\n\n* Matches titles with their correct time/location\n* Skips garbage data like `\"Date/Time\"` headers\n* 🧮 Converts time to proper ISO format (like `2025-06-21T11:00:00-07:00`) for Google Calendar\n\n🚀 Bonus:\n\n> This ensures only **valid**, well-structured events are passed forward — nothing broken, empty, or misaligned.\n\n---\n\n"},"typeVersion":1},{"id":"b19c44ba-1abb-4d0b-a854-1d844163ffdf","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-1800,-240],"parameters":{"color":6,"width":320,"height":680,"content":"## 📅 **Section 3: Auto Calendar Creator**\n\n### 📅 `📅 Create Google Calendar Events`\n\n> **Node:** *Google Calendar*\n> 🧙‍♂️ This node automatically **creates public calendar events** using the cleaned-up data.\n\nHere’s what it sets:\n\n* **Summary:** Event title\n* **Description:** Full details (e.g., location, what it’s about)\n* **Start/End Time:** In the correct Google Calendar format\n\n"},"typeVersion":1},{"id":"85488a2c-a51a-4561-8f7d-44901a3a04a1","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[-4600,-500],"parameters":{"color":4,"width":1300,"height":320,"content":"=======================================\n            WORKFLOW ASSISTANCE\n=======================================\nFor any questions or support, please contact:\n    Yaron@nofluff.online\n\nExplore more tips and tutorials here:\n   - YouTube: https://www.youtube.com/@YaronBeen/videos\n   - LinkedIn: https://www.linkedin.com/in/yaronbeen/\n=======================================\n"},"typeVersion":1},{"id":"2395bf91-efa9-4149-b411-38d18924c5c5","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-4600,-160],"parameters":{"color":4,"width":1289,"height":2298,"content":"# **📅 AutoSync Local Events to Google Calendar**\n\n### *A No-Code Automation to Scrape, Clean, and Publish Community Events*\n\n---\n## 🧭 **Section 1: Event Data Fetcher**\n\n### 🔁 `🕒 Daily Event Sync Trigger`\n\n> **Node:** *Schedule Trigger*\n> ⏰ This node sets **when** your automation runs. For example, you might want it to run every morning at 8:00 AM to check for new community events.\n\n🔍 Why it matters:\n\n> This ensures your public calendar is always up to date without manual work.\n\n---\n\n### 🌐 `🌐 Fetch Event Page (Bright Data)`\n\n> **Node:** *HTTP Request using Bright Data Web Unlocker*\n> 🛡 This node sends a request to a **local government or library event page** using Bright Data’s **Web Unlocker proxy**, which helps bypass blocks or bot detection.\n\n🔧 What’s special here:\n\n* It uses your **Bright Data proxy zone**\n* It targets a public events URL (e.g., a `.gov` or `.org`)\n* Makes sure you get the raw HTML page — even if the site tries to hide it\n\n✅ Benefit:\n\n> This lets you scrape data reliably from websites that are normally hard to reach for bots.\n\n---\n\n## 🧩 **Section 2: Smart Event Extractor**\n\n### 🧩 `🧩 Extract Event Data (HTML Parser)`\n\n> **Node:** *HTML*\n> 📄 This node parses the raw HTML response from the website and extracts useful information like:\n\n* 🏷 Event Titles\n* 📍 Locations\n* 👥 Target Audience\n* ⏰ Raw Times\n\nIt uses selectors (like CSS) to grab content from specific parts of the page.\n\n🎯 Goal:\n\n> Transform messy website code into **structured data** you can actually use.\n\n---\n\n### 🧠 `🧠 Clean & Format Event Data`\n\n> **Node:** *Code*\n> 🧼 This is the brain of your workflow. It takes the raw extracted data and:\n\n* Matches titles with their correct time/location\n* Skips garbage data like `\"Date/Time\"` headers\n* 🧮 Converts time to proper ISO format (like `2025-06-21T11:00:00-07:00`) for Google Calendar\n\n🚀 Bonus:\n\n> This ensures only **valid**, well-structured events are passed forward — nothing broken, empty, or misaligned.\n\n---\n\n## 📅 **Section 3: Auto Calendar Creator**\n\n### 📅 `📅 Create Google Calendar Events`\n\n> **Node:** *Google Calendar*\n> 🧙‍♂️ This node automatically **creates public calendar events** using the cleaned-up data.\n\nHere’s what it sets:\n\n* **Summary:** Event title\n* **Description:** Full details (e.g., location, what it’s about)\n* **Start/End Time:** In the correct Google Calendar format\n\n🫶 Why this matters:\n\n> Now your scraped community events are published straight to a **Google Calendar** — which you can embed on a website, share with citizens, or subscribe to.\n\n---\n\n## 🧩 Summary: Why This Workflow Rocks\n\n| 🔧 Step              | 📌 What It Does                                       | 🎁 Benefit to You                            |\n| -------------------- | ----------------------------------------------------- | -------------------------------------------- |\n| **Schedule Trigger** | Starts the automation daily                           | Keeps your calendar always fresh             |\n| **HTTP Request**     | Grabs raw event info from a gov/library site          | Reliable access to public event data         |\n| **HTML Parser**      | Pulls structured info from messy HTML                 | Turns code into useful content               |\n| **Code Node**        | Fixes formatting, converts time, aligns titles & more | Clean data ready for use                     |\n| **Calendar Node**    | Publishes events into your Google Calendar            | Fully automated public calendar — no effort! |\n\n---\n\n"},"typeVersion":1},{"id":"f4286f93-9457-4042-9b4d-bbb8304eaac1","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-1420,-240],"parameters":{"color":7,"width":380,"height":240,"content":"## I’ll receive a tiny commission if you join Bright Data through this link—thanks for fueling more free content!\n\n### https://get.brightdata.com/1tndi4600b25"},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"69086b47-9272-4887-8844-db532999a0ba","connections":{"Daily Event Sync Trigger":{"main":[[{"node":"Fetch Event Page (Bright Data)","type":"main","index":0}]]},"Clean & Format Event Data":{"main":[[{"node":"Create Google Calendar Events","type":"main","index":0}]]},"Fetch Event Page (Bright Data)":{"main":[[{"node":"Extract Event Data (HTML Parser)","type":"main","index":0}]]},"Extract Event Data (HTML Parser)":{"main":[[{"node":"Clean & Format Event Data","type":"main","index":0}]]}}}


name: Real-Time Bitcoin Price Alerts with Bright Data & n8n
author_name: Yaron Been
author_username: yaron-nofluff
categories: []
created_at: 2025-06-24T15:54:04.538Z
updated_at: 2025-06-24T15:54:04.538Z
url: https://n8n.io/workflows/5217
scraped_at: 2025-07-06 21:16:30
description:
  Description

  This workflow monitors Bitcoin prices across multiple exchanges and sends you alerts when significant price drops occur. It helps crypto traders and investors identify buying opportunities without constantly watching the markets.

  Overview

  This workflow monitors Bitcoin prices across multiple exchanges and sends you alerts when significant price drops occur. It uses Bright Data to scrape real-time price data and can be configured to notify you through various channels.

  Tools Used

  n8n:** The automation platform that orchestrates the workflow.
  Bright Data:** For scraping cryptocurrency exchange data without getting blocked.
  Notification Services:** Email, SMS, Telegram, or other messaging platforms.

  How to Install

  Import the Workflow: Download the .json file and import it into your n8n instance.
  Configure Bright Data: Add your Bright Data credentials to the Bright Data node.
  Set Up Notifications: Configure your preferred notification method.
  Customize: Set your price thresholds, monitoring frequency, and which exchanges to track.

  Use Cases

  Crypto Traders:** Get notified of buying opportunities during price dips.
  Investors:** Monitor your crypto investments and make informed decisions.
  Financial Analysts:** Track Bitcoin price movements for market analysis.

  Connect with Me

  Website:** https://www.nofluff.online
  YouTube:** https://www.youtube.com/@YaronBeen/videos
  LinkedIn:** https://www.linkedin.com/in/yaronbeen/
  Get Bright Data:** https://get.brightdata.com/1tndi4600b25 (Using this link supports my free workflows with a small commission)

  #n8n #automation #bitcoin #cryptocurrency #brightdata #pricealerts #cryptotrading #bitcoinalerts #cryptoalerts #cryptomonitoring #n8nworkflow #workflow #nocode #cryptoinvesting #bitcoinprice #cryptomarket #tradingalerts #cryptotools #bitcointrading #pricemonitoring #cryptoautomation #bitcoininvestment #cryptotracker #marketalerts #tradingopportunities #cryptoprices

nodes_used:
  ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest","n8n-nodes-base.gmail","n8n-nodes-base.code","n8n-nodes-base.html"]

workflow_json:
  {"id":"HPuntqVPRH2UITi4","meta":{"instanceId":"60046904b104f0f72b2629a9d88fe9f676be4035769f1f08dad1dd38a76b9480"},"name":"Bitcoin_Price_Drop_Alert_System_via_Bright_Data","tags":[],"nodes":[{"id":"8746bf3b-5e6b-4f14-815d-4b774c3302c3","name":"Manual Trigger","type":"n8n-nodes-base.manualTrigger","position":[2040,780],"parameters":{},"typeVersion":1},{"id":"1a5d6ae5-9491-4199-a6fe-ae01593ebedd","name":"Get Last Recorded Price","type":"n8n-nodes-base.googleSheets","position":[2880,780],"parameters":{"options":{},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/15DSwLkRw9NK2RIhXLMjzysmF9QYa5afreDXFrDQNXPM/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"15DSwLkRw9NK2RIhXLMjzysmF9QYa5afreDXFrDQNXPM","cachedResultUrl":"https://docs.google.com/spreadsheets/d/15DSwLkRw9NK2RIhXLMjzysmF9QYa5afreDXFrDQNXPM/edit?usp=drivesdk","cachedResultName":"Bitcoin latest price"}},"credentials":{"googleSheetsOAuth2Api":{"id":"r2mDaisH6e9VkwHl","name":"Google Sheets account"}},"typeVersion":4.6},{"id":"b48cce2e-63f3-4b4a-b9e7-f7506695dd8a","name":"Send Alert Email","type":"n8n-nodes-base.gmail","position":[3780,600],"webhookId":"bb09c84f-b390-4ce6-937e-eaeaefc979c5","parameters":{"sendTo":"shahkar.genai@gmail.com","message":"=Hello,\n\nThe price of Bitcoin has dropped by {{ $json.dropPercent }}% since the last check.\n\nPrevious Price: {{ $json.previousPrice }}\nCurrent Price: {{ $json.currentPrice }}\n\nPlease review accordingly.\n\nBest regards,\nYour Crypto Monitor Bot\n`;\n","options":{"appendAttribution":false},"subject":"=Bitcoin Price has dropped {{ $json.dropPercent }}%","emailType":"text"},"credentials":{"gmailOAuth2":{"id":"AQDSl75AdzK3vmqJ","name":"Gmail account"}},"typeVersion":2.1},{"id":"d1f96797-9558-403d-a37c-604e07e76563","name":"No Alert Needed","type":"n8n-nodes-base.noOp","position":[3780,900],"parameters":{},"typeVersion":1},{"id":"208006b9-4cae-4199-9342-d7646fe38672","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[0,0],"parameters":{"color":4,"width":1300,"height":320,"content":"=======================================\n            WORKFLOW ASSISTANCE\n=======================================\nFor any questions or support, please contact:\n    Yaron@nofluff.online\n\nExplore more tips and tutorials here:\n   - YouTube: https://www.youtube.com/@YaronBeen/videos\n   - LinkedIn: https://www.linkedin.com/in/yaronbeen/\n=======================================\n"},"typeVersion":1},{"id":"403e8b40-1a0f-464e-8d81-a162c0308252","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[0,340],"parameters":{"color":4,"width":1289,"height":2558,"content":"# 📉💰 **Bitcoin Price Drop Alert Workflow**\n\nThis automated workflow checks the current Bitcoin price and **sends an email alert if it drops by 5% or more** compared to the last recorded value. It’s split into 3 easy-to-understand sections:\n\n---\n\n## 🔎 **Section 1: Fetch the Current Bitcoin Price**\n\n🧩 **Nodes:**\n\n1. **⚡ Manual Trigger**\n2. **🌐 Fetch Bitcoin Price**\n3. **🧱 Extract Price**\n\n### 🧠 What Happens:\n\n* **⚡ Manual Trigger**\n  This starts the process manually. Think of it like pressing a \"Start\" button.\n\n* **🌐 Fetch Bitcoin Price**\n  Uses the [Bright Data API](https://brightdata.com/) to scrape the live Bitcoin price from a specific website using a POST request.\n\n* **🧱 Extract Price**\n  Extracts the **exact price value** from the scraped HTML using selectors (like CSS paths).\n\n### 💡 Why It’s Useful:\n\nYou can track the **real-time price** of Bitcoin straight from any public site, even those not offering official APIs. It's like building your own live feed.\n\n---\n\n## 📊 **Section 2: Calculate and Compare with Historical Price**\n\n🧩 **Nodes:**\n4\\. **🔄 Convert Type**\n5\\. **📗 Get Last Recorded Price (Google Sheet)**\n6\\. **📉 Find Drop Percentage**\n\n### 🧠 What Happens:\n\n* **🔄 Convert Type**\n  Converts the price from a text format to a number so we can calculate with it.\n\n* **📗 Get Last Recorded Price**\n  Pulls the **previous Bitcoin price** from a Google Sheet (a record from last check). Acts like your “memory”.\n\n* **📉 Find Drop Percentage**\n  Calculates how much the price has dropped:\n\n  $$\n  \\text{Drop (\\%)} = \\frac{\\text{Previous Price - Current Price}}{\\text{Previous Price}} \\times 100\n  $$\n\n### 💡 Why It’s Useful:\n\nYou’re comparing real-time data with past values automatically—no spreadsheets or calculators needed! This makes it ideal for **traders or enthusiasts** watching for price alerts.\n\n---\n\n## 🚨 **Section 3: Send Alert if Drop ≥ 5%**\n\n🧩 **Nodes:**\n7\\. **🔀 If droppercentage >= 5**\n8\\. **📧 Send Alert Email**\n9\\. **➡️ No Alert Needed**\n\n### 🧠 What Happens:\n\n* **🔀 If Statement**\n  Checks: Has the price dropped by **5% or more**?\n\n* **📧 Send Alert Email** (if true)\n  Automatically sends an email to notify you about the drop. This could go to your inbox, or a team.\n\n* **➡️ No Alert Needed** (if false)\n  The workflow ends quietly without doing anything else.\n\n### 💡 Why It’s Useful:\n\nIt **only alerts you when it matters**, saving your attention for big changes. You don’t need to monitor prices all day.\n\n---\n\n## 🎁 **Final Benefits:**\n\n✅ **No coding required**\n✅ **Real-time price check**\n✅ **Smart alerts based on thresholds**\n✅ **Great for traders, analysts, or crypto fans**\n✅ **Fully extendable** – you could log alerts, update the sheet, send Slack/Telegram messages, etc.\n\n---\n\n## 🌈 BONUS IDEA:\n\nWant it to run automatically? Add a **🕒 Cron Trigger** to check every 10 mins, 1 hour, or even daily!\n\n---\n"},"typeVersion":1},{"id":"201e7c73-d960-47c5-934e-f8fe0630ca2c","name":"Fetch Bitcoin Price","type":"n8n-nodes-base.httpRequest","position":[2240,780],"parameters":{"url":"https://api.brightdata.com/request","method":"POST","options":{},"sendBody":true,"sendHeaders":true,"bodyParameters":{"parameters":[{"name":"zone","value":"n8n_unblocker"},{"name":"url","value":"https://coinmarketcap.com/currencies/bitcoin/"},{"name":"country","value":"us"},{"name":"format","value":"raw"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2},{"id":"ff6d0c30-0e72-4a28-9628-b94606461a20","name":"Extract Price","type":"n8n-nodes-base.html","position":[2440,780],"parameters":{"options":{},"operation":"extractHtmlContent","extractionValues":{"values":[{"key":"price","cssSelector":"<span class=\"sc-65e7f566-0 esyGGG base-text\" data-test=\"text-cdp-price-display\">$105,095.42</span>"}]}},"typeVersion":1.2},{"id":"759e26b7-a260-469e-ba17-fc5bee7be762","name":"Convert type","type":"n8n-nodes-base.code","position":[2660,780],"parameters":{"jsCode":"return items.map(item => {\n  const priceStr = item.json.price;\n  const priceNumber = parseFloat(priceStr.replace(/[$,]/g, ''));\n  return {\n    json: {\n      price: priceNumber\n    }\n  };\n});\n"},"typeVersion":2},{"id":"c33e81f4-f06e-4e47-942f-4764027f270c","name":"Find drop percentage","type":"n8n-nodes-base.code","position":[3100,780],"parameters":{"jsCode":"// Extract current and previous price from separate input items\nconst currentPrice = $('Convert type').first().json.price;\nconst previousPrice = $input.first().json.Price;\n\nconst dropPercent = previousPrice !== 0 \n  ? ((previousPrice - currentPrice) / previousPrice) * 100 \n  : 0;\n\nreturn [{\n  json: {\n    currentPrice,\n    previousPrice,\n    dropPercent: parseFloat(dropPercent.toFixed(2))\n  }\n}];\n"},"typeVersion":2},{"id":"cb64ae28-6086-4301-85b7-a8bdac6c2370","name":"If droppercentage >= 5","type":"n8n-nodes-base.if","position":[3420,780],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"9b9dfa4e-92d1-408e-90f0-355141f73d54","operator":{"type":"number","operation":"gte"},"leftValue":"={{ $json.dropPercent }}","rightValue":5}]}},"typeVersion":2.2},{"id":"08bcbb20-2f85-45c9-b56e-61edb70ccd74","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[2020,0],"parameters":{"color":3,"width":540,"height":980,"content":"## 🔎 **Section 1: Fetch the Current Bitcoin Price**\n\n🧩 **Nodes:**\n\n1. **⚡ Manual Trigger**\n2. **🌐 Fetch Bitcoin Price**\n3. **🧱 Extract Price**\n\n### 🧠 What Happens:\n\n* **⚡ Manual Trigger**\n  This starts the process manually. Think of it like pressing a \"Start\" button.\n\n* **🌐 Fetch Bitcoin Price**\n  Uses the [Bright Data API](https://brightdata.com/) to scrape the live Bitcoin price from a specific website using a POST request.\n\n* **🧱 Extract Price**\n  Extracts the **exact price value** from the scraped HTML using selectors (like CSS paths).\n\n### 💡 Why It’s Useful:\n\nYou can track the **real-time price** of Bitcoin straight from any public site, even those not offering official APIs. It's like building your own live feed.\n\n---\n\n"},"typeVersion":1},{"id":"9c153740-4fb9-4ab7-b129-c6bc8c61c274","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[2640,-40],"parameters":{"color":5,"width":600,"height":1020,"content":"## 📊 **Section 2: Calculate and Compare with Historical Price**\n\n🧩 **Nodes:**\n4\\. **🔄 Convert Type**\n5\\. **📗 Get Last Recorded Price (Google Sheet)**\n6\\. **📉 Find Drop Percentage**\n\n### 🧠 What Happens:\n\n* **🔄 Convert Type**\n  Converts the price from a text format to a number so we can calculate with it.\n\n* **📗 Get Last Recorded Price**\n  Pulls the **previous Bitcoin price** from a Google Sheet (a record from last check). Acts like your “memory”.\n\n* **📉 Find Drop Percentage**\n  Calculates how much the price has dropped:\n\n  $$\n  \\text{Drop (\\%)} = \\frac{\\text{Previous Price - Current Price}}{\\text{Previous Price}} \\times 100\n  $$\n\n### 💡 Why It’s Useful:\n\nYou’re comparing real-time data with past values automatically—no spreadsheets or calculators needed! This makes it ideal for **traders or enthusiasts** watching for price alerts.\n\n---\n\n"},"typeVersion":1},{"id":"58dbf6d5-371f-4123-8838-5c6f40185711","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[3380,100],"parameters":{"color":6,"width":540,"height":940,"content":"## 🚨 **Section 3: Send Alert if Drop ≥ 5%**\n\n🧩 **Nodes:**\n7\\. **🔀 If droppercentage >= 5**\n8\\. **📧 Send Alert Email**\n9\\. **➡️ No Alert Needed**\n\n### 🧠 What Happens:\n\n* **🔀 If Statement**\n  Checks: Has the price dropped by **5% or more**?\n\n* **📧 Send Alert Email** (if true)\n  Automatically sends an email to notify you about the drop. This could go to your inbox, or a team.\n\n* **➡️ No Alert Needed** (if false)\n  The workflow ends quietly without doing anything else.\n\n\n"},"typeVersion":1},{"id":"a9608daf-aff9-460a-8ca5-14c1fc41916e","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[4000,100],"parameters":{"color":7,"width":380,"height":240,"content":"## I’ll receive a tiny commission if you join Bright Data through this link—thanks for fueling more free content!\n\n### https://get.brightdata.com/1tndi4600b25"},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"125a795b-a427-4a83-abee-62fe60538000","connections":{"Convert type":{"main":[[{"node":"Get Last Recorded Price","type":"main","index":0}]]},"Extract Price":{"main":[[{"node":"Convert type","type":"main","index":0}]]},"Manual Trigger":{"main":[[{"node":"Fetch Bitcoin Price","type":"main","index":0}]]},"Fetch Bitcoin Price":{"main":[[{"node":"Extract Price","type":"main","index":0}]]},"Find drop percentage":{"main":[[{"node":"If droppercentage >= 5","type":"main","index":0}]]},"If droppercentage >= 5":{"main":[[{"node":"Send Alert Email","type":"main","index":0}],[{"node":"No Alert Needed","type":"main","index":0}]]},"Get Last Recorded Price":{"main":[[{"node":"Find drop percentage","type":"main","index":0}]]}}}


name: Find the Cheapest Flights Automatically with Bright Data & n8n
author_name: Yaron Been
author_username: yaron-nofluff
nodes_used: ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest","n8n-nodes-base.html"]
categories: []
created_at: 2025-06-24T15:54:24.914Z
updated_at: 2025-06-24T15:54:24.914Z
url: https://n8n.io/workflows/5218
scraped_at: 2025-07-06 21:16:30
description:
  Description

  This workflow automatically searches multiple flight booking websites to find the cheapest flights for your desired routes. It leverages web scraping to compare prices across platforms, helping you save money on air travel.

  Overview

  This workflow automatically searches multiple flight booking websites to find the cheapest flights for your desired routes. It uses Bright Data to scrape flight prices and can notify you when prices drop below your target threshold.

  Tools Used

  n8n:** The automation platform that orchestrates the workflow.
  Bright Data:** For scraping flight prices from booking websites.
  Notification Services:** Email, SMS, or other messaging platforms.

  How to Install

  Import the Workflow: Download the .json file and import it into your n8n instance.
  Configure Bright Data: Add your Bright Data credentials to the Bright Data node.
  Set Up Notifications: Configure your preferred notification method.
  Customize: Set your routes, date ranges, and price thresholds.

  Use Cases

  Frequent Travelers:** Find the best deals for your regular routes.
  Travel Agencies:** Monitor flight prices for client bookings.
  Budget Travelers:** Get notified when flights to your dream destination become affordable.

  Connect with Me

  YouTube:** https://www.youtube.com/@YaronBeen/videos
  LinkedIn:** https://www.linkedin.com/in/yaronbeen/
  Get Bright Data:** https://get.brightdata.com/1tndi4600b25 (Using this link supports my free workflows with a small commission)

  #n8n #automation #travel #flights #brightdata #dealalerts #webscraping #flightdeals #cheapflights #travelhacks #budgettravel #travelplanning #airfare #flightprices #travelautomation #n8nworkflow #workflow #nocode #traveltech #flightbooking #savemoney #traveltools #flightcomparison #bestflightdeals #travelsmarter #automatedtravel

workflow_json:
  {"id":"YhwckWo4y8FNZ4v4","meta":{"instanceId":"60046904b104f0f72b2629a9d88fe9f676be4035769f1f08dad1dd38a76b9480","templateCredsSetupCompleted":true},"name":"Cheapest_Flight_Finder_via_Bright_Data","tags":[],"nodes":[{"id":"6da8e17f-3448-4195-b812-43564470d376","name":"Manual Trigger","type":"n8n-nodes-base.manualTrigger","position":[-480,2340],"parameters":{},"typeVersion":1},{"id":"6e92c67b-3e06-4de8-ac8f-f09d33bc6115","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[-2460,500],"parameters":{"color":4,"width":1300,"height":320,"content":"=======================================\n            WORKFLOW ASSISTANCE\n=======================================\nFor any questions or support, please contact:\n    Yaron@nofluff.online\n\nExplore more tips and tutorials here:\n   - YouTube: https://www.youtube.com/@YaronBeen/videos\n   - LinkedIn: https://www.linkedin.com/in/yaronbeen/\n=======================================\n"},"typeVersion":1},{"id":"ffb0ba94-e697-409d-9190-1e6f8656c775","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-2460,840],"parameters":{"color":4,"width":1289,"height":2458,"content":"# 🧳 ✈️ **Flight Price Scraper from Skiplagged using Bright Data**\n\nThis automation helps you extract **cheap flight prices** from [Skiplagged.com](https://skiplagged.com) using **Bright Data** and automatically logs those prices into a **Google Sheet** for review and tracking.\n\n---\n\n## 🔹 **SECTION 1: Getting the Flight Prices**\n\n*Combining: Manual Trigger + HTTP Request (Bright Data)*\n\n### 🌩️ 1. **Manual Trigger**\n\n* **🧠 What it does**: Starts the workflow when you click **Execute Workflow** in n8n.\n* **👨‍🏫 For beginners**: Think of it like a **start button**. No schedule, just run it manually whenever you want to check for deals.\n\n---\n\n### 🌐 2. **Fetch Flight Details from Skiplagged via Bright Data**\n\n* **🔧 Node Type**: `HTTP Request` (POST)\n\n* **🌍 What's happening**:\n\n  * Uses Bright Data Web Unlocker to **bypass bot protection** and fetch HTML content from Skiplagged.\n  * You’re sending a POST request to `https://api.brightdata.com/request`, asking Bright Data to open:\n    `https://skiplagged.com/flights/DUB/LON/2024-06-30` (or a dynamic route).\n  * Headers & proxy make it **look like a real browser**.\n\n* **💡 Why it’s useful**:\n\n  * **Skiplagged is tricky to scrape** directly, but Bright Data makes it easy.\n  * You get the **entire HTML** of the search results page, ready to extract price info.\n\n* ✅ **Returns**: HTML of the page (not yet structured — we handle that next)\n\n---\n\n## 🔹 **SECTION 2: Extracting & Storing Flight Prices**\n\n*Combining: HTML Node + Google Sheets*\n\n### 🖥️ 3. **HTML Extract (extractHtmlContent)**\n\n* **🔧 Node Type**: `HTML Extract`\n\n* **🎯 Goal**: Pull out **all flight prices** from the raw HTML.\n\n* **How it works**:\n\n  * Uses a selector like `.flights-landing__flight-price` to find every element that matches.\n  * **Returns multiple values** if \"Return All Matches\" is enabled.\n\n* 🧠 **Beginner Note**: Imagine your browser looking for all `<div class=\"flights-landing__flight-price\">`. This is like **copying all price tags off the screen**.\n\n* ✅ **Returns**:\n\n  ```json\n  [\n    \"$104\", \"$117\", \"$99\", \"$88\"\n  ]\n  ```\n\n---\n\n### 📊 4. **Google Sheets (append: sheet)**\n\n* **🔧 Node Type**: `Google Sheets Append`\n\n* **📋 What it does**: Appends each flight price as a new row in your spreadsheet.\n\n* **🛠️ Tip**: Make sure your sheet has one column titled something like `Price` and authentication is set up.\n\n* ❌ **Error Warning**: If this node is red, likely issues are:\n\n  * Missing Google credentials\n  * Sheet name doesn’t match\n  * Field mapping mismatch\n\n* ✅ **Returns**: New rows in your sheet like:\n\n| Price |\n| ----- |\n| \\$88  |\n| \\$99  |\n| \\$104 |\n\n---\n\n## 🌟 Final Thoughts: Why This Is Powerful\n\n✅ **Perfect for spontaneous travelers** who want to grab last-minute deals.\n✅ **Low-cost** thanks to free tools (n8n + Google Sheets) and flexible Bright Data usage.\n✅ **Easy to expand**: Add logic to filter cheapest flight, add Telegram/email alert, or schedule it daily.\n\n---\n\n## 🧭 Next Steps You Could Add\n\n* 📅 Add a **Cron node** to automate daily checks.\n* 📬 Add **Telegram or Email node** to notify when price < \\$100.\n* 🔧 Use **Set node** to make route and date dynamic.\n\n---\n\n\n"},"typeVersion":1},{"id":"3e3a26e0-eeed-4a0f-85bb-ac49e438eb43","name":"HTML","type":"n8n-nodes-base.html","position":[20,2340],"parameters":{"options":{},"operation":"extractHtmlContent","extractionValues":{"values":[{"key":"Title","cssSelector":"<span class=\"flights-landing__flight-logo-txt\" data-translate=\"false\">United</span>"},{"key":"Price","cssSelector":"<div class=\"flights-landing__flight-price\">$114</div>"}]}},"typeVersion":1.2},{"id":"4213760f-1d00-4d4c-b918-5b46728c78e8","name":"Google Sheets","type":"n8n-nodes-base.googleSheets","position":[240,2340],"parameters":{"operation":"append","sheetName":{"__rl":true,"mode":"list","value":""},"documentId":{"__rl":true,"mode":"list","value":""}},"credentials":{"googleSheetsOAuth2Api":{"id":"r2mDaisH6e9VkwHl","name":"Google Sheets account"}},"typeVersion":4.6},{"id":"c1bda948-e9f0-4539-ba18-fa37ac431d91","name":"Fetch flight details from skiplegged via bright data","type":"n8n-nodes-base.httpRequest","position":[-260,2340],"parameters":{"url":"https://api.brightdata.com/request","method":"POST","options":{},"jsonBody":"{\n  \"zone\": \"n8n_unblocker\",\n  \"url\": \"https://skiplagged.com/flights/NYC/LAX/2024-07-01\",\n  \"country\": \"ie\",\n  \"format\": \"raw\",\n  \"headers\": {\n    \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36\",\n    \"Accept-Language\": \"en-US,en;q=0.9\",\n    \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\"\n  }\n}","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2},{"id":"6f4009d4-bd47-4bda-a4b1-cd6bdfa59821","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-500,1340],"parameters":{"color":3,"width":400,"height":1200,"content":"## 🔹 **SECTION 1: Getting the Flight Prices**\n\n*Combining: Manual Trigger + HTTP Request (Bright Data)*\n\n### 🌩️ 1. **Manual Trigger**\n\n* **🧠 What it does**: Starts the workflow when you click **Execute Workflow** in n8n.\n* **👨‍🏫 For beginners**: Think of it like a **start button**. No schedule, just run it manually whenever you want to check for deals.\n\n---\n\n### 🌐 2. **Fetch Flight Details from Skiplagged via Bright Data**\n\n* **🔧 Node Type**: `HTTP Request` (POST)\n\n* **🌍 What's happening**:\n\n  * Uses Bright Data Web Unlocker to **bypass bot protection** and fetch HTML content from Skiplagged.\n  * You’re sending a POST request to `https://api.brightdata.com/request`, asking Bright Data to open:\n    `https://skiplagged.com/flights/DUB/LON/2024-06-30` (or a dynamic route).\n  * Headers & proxy make it **look like a real browser**.\n\n* **💡 Why it’s useful**:\n\n  * **Skiplagged is tricky to scrape** directly, but Bright Data makes it easy.\n  * You get the **entire HTML** of the search results page, ready to extract price info.\n\n* ✅ **Returns**: HTML of the page (not yet structured — we handle that next)\n\n---\n\n"},"typeVersion":1},{"id":"15115b20-c08a-4953-be0b-8e7a7f2a4030","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-20,1080],"parameters":{"color":5,"width":400,"height":1460,"content":"## 🔹 **SECTION 2: Extracting & Storing Flight Prices**\n\n*Combining: HTML Node + Google Sheets*\n\n### 🖥️ 3. **HTML Extract (extractHtmlContent)**\n\n* **🔧 Node Type**: `HTML Extract`\n\n* **🎯 Goal**: Pull out **all flight prices** from the raw HTML.\n\n* **How it works**:\n\n  * Uses a selector like `.flights-landing__flight-price` to find every element that matches.\n  * **Returns multiple values** if \"Return All Matches\" is enabled.\n\n* 🧠 **Beginner Note**: Imagine your browser looking for all `<div class=\"flights-landing__flight-price\">`. This is like **copying all price tags off the screen**.\n\n* ✅ **Returns**:\n\n  ```json\n  [\n    \"$104\", \"$117\", \"$99\", \"$88\"\n  ]\n  ```\n\n---\n\n### 📊 4. **Google Sheets (append: sheet)**\n\n* **🔧 Node Type**: `Google Sheets Append`\n\n* **📋 What it does**: Appends each flight price as a new row in your spreadsheet.\n\n* **🛠️ Tip**: Make sure your sheet has one column titled something like `Price` and authentication is set up.\n\n* ❌ **Error Warning**: If this node is red, likely issues are:\n\n  * Missing Google credentials\n  * Sheet name doesn’t match\n  * Field mapping mismatch\n\n* ✅ **Returns**: New rows in your sheet like:\n\n| Price |\n| ----- |\n| \\$88  |\n| \\$99  |\n| \\$104 |\n\n---\n"},"typeVersion":1},{"id":"b151fc17-d628-4e38-a5e7-91b2555b8e1f","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[460,1080],"parameters":{"color":7,"width":380,"height":240,"content":"## I’ll receive a tiny commission if you join Bright Data through this link—thanks for fueling more free content!\n\n### https://get.brightdata.com/1tndi4600b25"},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"d966578d-4e22-4067-b7b6-1b310276ba5a","connections":{"HTML":{"main":[[{"node":"Google Sheets","type":"main","index":0}]]},"Manual Trigger":{"main":[[{"node":"Fetch flight details from skiplegged via bright data","type":"main","index":0}]]},"Fetch flight details from skiplegged via bright data":{"main":[[{"node":"HTML","type":"main","index":0}]]}}}


name: Automated Competitor Price Monitoring with Bright Data & n8n
author_name: Yaron Been
author_username: yaron-nofluff
categories: []
created_at: 2025-06-24T15:54:46.724Z
updated_at: 2025-06-24T15:54:46.724Z
url: https://n8n.io/workflows/5219
scraped_at: 2025-07-06 21:16:30
description:
  Description

  This workflow automatically monitors your competitors' product prices and notifies you of any changes. It helps you stay competitive in the market by providing real-time insights into pricing strategies without manual checking.

  Overview

  This workflow automatically tracks your competitors' pricing across their websites and notifies you of any changes. It uses Bright Data to scrape pricing data and can generate reports or send alerts when prices change.

  Tools Used

  n8n:** The automation platform that orchestrates the workflow.
  Bright Data:** For scraping competitor websites without being blocked.
  Spreadsheets/Databases:** For storing and analyzing price data.
  Notification Services:** For alerting you to significant price changes.

  How to Install

  Import the Workflow: Download the .json file and import it into your n8n instance.
  Configure Bright Data: Add your Bright Data credentials to the Bright Data node.
  Set Up Data Storage: Configure where you want to store the price data.
  Customize: Add your competitors' URLs and the specific products to monitor.

  Use Cases

  E-commerce Businesses:** Stay competitive with real-time price monitoring.
  Pricing Analysts:** Automate data collection for pricing strategy.
  Retailers:** Adjust your pricing strategy based on market trends.

  Connect with Me

  Website:** https://www.nofluff.online
  YouTube:** https://www.youtube.com/@YaronBeen/videos
  LinkedIn:** https://www.linkedin.com/in/yaronbeen/
  Get Bright Data:** https://get.brightdata.com/1tndi4600b25 (Using this link supports my free workflows with a small commission)

  #n8n #automation #pricing #competitoranalysis #brightdata #ecommerce #pricemonitoring #competitiveintelligence #pricetracking #marketanalysis #n8nworkflow #workflow #nocode #pricingstrategy #competitortracking #ecommercetools #pricecomparison #businessintelligence #marketresearch #competitivepricing #retailautomation #pricealerts #datadriven #webscraping #pricinganalysis #competitorinsights

nodes_used:
  ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest","n8n-nodes-base.gmail","n8n-nodes-base.code","n8n-nodes-base.html"]

workflow_json:
  {"id":"6RP5sxs8BvIIinq2","meta":{"instanceId":"60046904b104f0f72b2629a9d88fe9f676be4035769f1f08dad1dd38a76b9480"},"name":"Competitor_Price_Monitoring_via_Bright_Data","tags":[],"nodes":[{"id":"0fa21dc1-fae9-45ca-b2a9-8c4dc212c964","name":"Check Pricing Every Day","type":"n8n-nodes-base.scheduleTrigger","position":[-1400,1000],"parameters":{"rule":{"interval":[{"triggerAtHour":9}]}},"typeVersion":1.2},{"id":"58e4effc-32b1-4767-bc79-1f5147a00c4e","name":"Fetch Page via Bright Data","type":"n8n-nodes-base.httpRequest","position":[-1180,1000],"parameters":{"url":"https://api.brightdata.com/request","method":"POST","options":{},"jsonBody":"{\n  \"zone\": \"n8n_unblocker\",\n  \"url\": \"https://www.shopify.com/uk/pricing\",\n  \"country\": \"us\",\n  \"format\": \"raw\",\n  \"headers\": {\n    \"User-Agent\": \"Mozilla/5.0\",\n    \"Accept\": \"text/html\"\n  }\n}","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2},{"id":"d1bfc4d4-5951-459f-8dd9-65cbeee325ea","name":"Extract HTML Content","type":"n8n-nodes-base.html","position":[-960,1000],"parameters":{"options":{},"operation":"extractHtmlContent","extractionValues":{"values":[{"key":"Plan name","cssSelector":"h3","returnArray":true},{"key":"Pricing","cssSelector":"span","returnArray":true}]}},"typeVersion":1.2},{"id":"4983085d-a355-4f1a-8141-cbb622e94776","name":"Format & Isolate Price Block","type":"n8n-nodes-base.code","position":[-760,1000],"parameters":{"jsCode":"// Step 1: Get data from the previous node\nconst inputData = items[0].json;\n\n// Extract plan names and pricing blocks\nconst planNames = inputData[\"Plan name\"];\nconst pricingList = inputData[\"Pricing\"];\n\n// Regex to match entries like \"$2,300USD/month\"\nconst priceRegex = /\\$[\\d,]+USD\\/month/;\n\n// Step 2: Extract only valid price strings\nconst prices = pricingList.filter(item => typeof item === 'string' && priceRegex.test(item));\n\n// Clean prices: \"$2,300USD/month\" -> 2300 (number)\nconst cleanedPrices = prices.map(p => {\n  const match = p.match(/\\$[\\d,]+/);\n  if (match) {\n    return parseFloat(match[0].replace(/[$,]/g, ''));\n  }\n  return null;\n}).filter(p => p !== null);\n\n// Step 3: Build result object\nconst planPriceMap = {};\n\nfor (let i = 0; i < planNames.length; i++) {\n  const plan = planNames[i];\n\n  if (['Basic', 'Grow', 'Advanced', 'Plus'].includes(plan) && !(plan in planPriceMap)) {\n    planPriceMap[plan] = cleanedPrices.shift() ?? null;\n  }\n}\n\n// Step 4: Return final structured item\nreturn [\n  {\n    json: planPriceMap\n  }\n];\n"},"typeVersion":2},{"id":"178945da-4167-43d1-af20-f3acb8003f17","name":"Read Last Saved Price","type":"n8n-nodes-base.googleSheets","position":[-520,1000],"parameters":{"options":{},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1LTGVeEXaU1PSMcNWI6beT_IuETKH147vfi8vAtWJ0MQ/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1LTGVeEXaU1PSMcNWI6beT_IuETKH147vfi8vAtWJ0MQ","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1LTGVeEXaU1PSMcNWI6beT_IuETKH147vfi8vAtWJ0MQ/edit?usp=drivesdk","cachedResultName":"Competitor price analyzer"}},"credentials":{"googleSheetsOAuth2Api":{"id":"r2mDaisH6e9VkwHl","name":"Google Sheets account"}},"typeVersion":4.6},{"id":"67534ae0-f365-4e11-b244-73cc999ed47a","name":"Has Price Changed?","type":"n8n-nodes-base.if","position":[-300,1000],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"2ca35690-3534-40c4-8d79-02833e331e17","operator":{"type":"number","operation":"equals"},"leftValue":"={{ $('Format & Isolate Price Block').item.json.Basic }}","rightValue":"={{ $json.Basic }}"},{"id":"fe7e3cac-d614-4962-82a4-d3e06464ae14","operator":{"type":"number","operation":"equals"},"leftValue":"={{ $('Format & Isolate Price Block').item.json.Grow }}","rightValue":"={{ $json.Grow }}"},{"id":"bf877945-b2f4-48f9-be88-c3e97600c984","operator":{"type":"number","operation":"equals"},"leftValue":"={{ $('Format & Isolate Price Block').item.json.Advanced }}","rightValue":"={{ $json.Advanced }}"},{"id":"5045eaa9-4798-4ca8-83e3-6c8c51a297d2","operator":{"type":"number","operation":"equals"},"leftValue":"={{ $('Format & Isolate Price Block').item.json.Plus }}","rightValue":"={{ $json.Plus }}"}]}},"typeVersion":2.2},{"id":"023f6e01-6625-4310-a61f-4dac9748c19d","name":"No Change Detected – Stop","type":"n8n-nodes-base.noOp","position":[60,800],"parameters":{},"typeVersion":1},{"id":"eaf629e8-eb2d-49b2-a568-a87c52dbe131","name":"Update Stored Price","type":"n8n-nodes-base.googleSheets","position":[60,1180],"parameters":{"columns":{"value":{"Grow":"={{ $json.Grow }}","Plus":"={{ $json.Plus }}","Basic":"={{ $json.Basic }}","Advanced":"={{ $json.Advanced }}","row_number":"={{ $json.row_number }}"},"schema":[{"id":"Basic","type":"string","display":true,"required":false,"displayName":"Basic","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Grow","type":"string","display":true,"required":false,"displayName":"Grow","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Advanced","type":"string","display":true,"required":false,"displayName":"Advanced","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Plus","type":"string","display":true,"required":false,"displayName":"Plus","defaultMatch":false,"canBeUsedToMatch":true},{"id":"row_number","type":"string","display":true,"removed":false,"readOnly":true,"required":false,"displayName":"row_number","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["row_number"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"update","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1LTGVeEXaU1PSMcNWI6beT_IuETKH147vfi8vAtWJ0MQ/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1LTGVeEXaU1PSMcNWI6beT_IuETKH147vfi8vAtWJ0MQ","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1LTGVeEXaU1PSMcNWI6beT_IuETKH147vfi8vAtWJ0MQ/edit?usp=drivesdk","cachedResultName":"Competitor price analyzer"}},"credentials":{"googleSheetsOAuth2Api":{"id":"r2mDaisH6e9VkwHl","name":"Google Sheets account"}},"typeVersion":4.6},{"id":"7505ca0e-f968-437e-a4ca-0cdbd4fee93b","name":"Send Price Change Alert Email","type":"n8n-nodes-base.gmail","position":[280,1180],"webhookId":"b2bf0aba-123e-489e-9669-4034d16a060c","parameters":{"sendTo":"shahkar.genai@gmail.com","message":"=<p>Hi Team,</p>  <p>This is an automated alert to inform you that the pricing page of a competitor has changed.</p>  <ul>   <li><strong>Competitor:</strong> Wix</li>   <li><strong>Page URL:</strong> <a href=\"https://www.wix.com/upgrade/website\">https://www.wix.com/upgrade/website</a></li>   <li><strong>Checked On:</strong> {{ $now }}</li> </ul>  <p>Please review the new pricing to assess if any strategic adjustments are needed.\nPlease check in Google sheets for the latest pricing as soon as possible\n</p>  <p>Best regards,<br>Muhammad Shahkar </p>","options":{"appendAttribution":false},"subject":"Competitor Pricing Page Has Changed"},"credentials":{"gmailOAuth2":{"id":"AQDSl75AdzK3vmqJ","name":"Gmail account"}},"typeVersion":2.1},{"id":"494ab1e4-de04-4a98-acca-a0e8e242575c","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1460,640],"parameters":{"color":6,"width":840,"height":540,"content":"\n## 🟢 **SECTION 1: Fetch the Latest Pricing Info**\n\n### 📡 Scheduled Scraping Using Bright Data\n\n| 🧩 Nodes Involved                   | 💬 Description                                                                                                                                               |\n| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| 🕒 **Check Pricing Every Hour**     | This **Schedule Trigger** runs your workflow automatically (e.g., every hour). You don’t have to manually check the website.                                 |\n| 🌐 **Fetch Page via Bright Data**   | Uses **Bright Data Web Unlocker API** to bypass bot protections and fetch the HTML of the pricing page from a competitor site (e.g., Wix, Squarespace, etc). |\n| 🧾 **Extract HTML Content**         | This node pulls out the actual **HTML code** of the page from the API response, ready to be analyzed.                                                        |\n| 🔧 **Format & Isolate Price Block** | This custom code node filters or extracts just the **pricing section** (e.g., plan names, \\$ amounts) from the HTML to compare later.                        |\n\n> ✅ **Advantage for Beginners**: You don’t need to manually visit or inspect the site. Everything is automated and updated behind the scenes.\n\n---\n\n"},"typeVersion":1},{"id":"a9beb646-c639-408c-a3c4-678e19e7bee2","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-580,520],"parameters":{"color":3,"width":440,"height":660,"content":"## 🟡 **SECTION 2: Check If the Price Has Changed**\n\n### 🔍 Compare New Data with the Last Saved One\n\n| 🧩 Nodes Involved            | 💬 Description                                                                                                                                                                                          |\n| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| 📄 **Read Last Saved Price** | This reads from a **Google Sheet** that stores the **last known pricing data**. This becomes your reference point for comparison.                                                                       |\n| 🔁 **Has Price Changed?**    | A simple **IF condition** compares the current scraped pricing to the previously saved one. If the content is **exactly the same**, nothing happens. If it's **different**, it moves to the alert flow. |\n\n> ✅ **Advantage for Beginners**: No need for complex logic. n8n handles the comparison using a basic condition node.\n\n---"},"typeVersion":1},{"id":"cdb1ef33-fcbb-449d-b81e-b7f8cbaf7a18","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[0,0],"parameters":{"color":5,"width":440,"height":1360,"content":"## 🔴 **SECTION 3: Alert & Save New Price**\n\n### 🚨 Notify + Update Sheet\n\n| 🧩 Nodes Involved                    | 💬 Description                                                                                                                                          |\n| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| ➖ **No Change Detected – Stop**      | If no changes were found, this does nothing and exits. Keeps your flow efficient.                                                                       |\n| 📄 **Update Stored Price**           | If the price **has changed**, it writes the new value to the **Google Sheet** so future comparisons are accurate.                                       |\n| 📧 **Send Price Change Alert Email** | This node sends a **professional email** (via Gmail) to alert you or your team about the pricing update. The email includes the date and the page link. |\n\n> ✅ **Advantage for Beginners**: No need to monitor email manually or check sheets. You’re notified only when something meaningful happens!\n\n---\n\n## 🖼️ 📊 VISUAL WORKFLOW SUMMARY\n\n```mermaid\ngraph TD;\n  A[🕒 Schedule Trigger] --> B[🌐 Fetch via Bright Data];\n  B --> C[🧾 Extract HTML];\n  C --> D[🔧 Extract Pricing];\n  D --> E[📄 Read Last Price from Sheet];\n  E --> F{🔁 Has Price Changed?};\n  F -- Yes --> G[📄 Update Sheet];\n  G --> H[📧 Send Alert Email];\n  F -- No --> I[➖ Do Nothing];\n```\n\n---\n"},"typeVersion":1},{"id":"afc23ae0-ef5e-490a-980b-a56e9436fa31","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[-3160,640],"parameters":{"color":4,"width":1300,"height":320,"content":"=======================================\n            WORKFLOW ASSISTANCE\n=======================================\nFor any questions or support, please contact:\n    Yaron@nofluff.online\n\nExplore more tips and tutorials here:\n   - YouTube: https://www.youtube.com/@YaronBeen/videos\n   - LinkedIn: https://www.linkedin.com/in/yaronbeen/\n=======================================\n"},"typeVersion":1},{"id":"4a1af414-b88b-4618-970e-0b2e67beda67","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-3160,980],"parameters":{"color":4,"width":1289,"height":1798,"content":"## 🧠💼 Title:\n\n**Competitor Pricing Page Monitor — Automated Alerts Using n8n + Bright Data**\n\nThis workflow automatically **monitors a competitor’s pricing page**, **detects changes**, and sends an **alert email** while keeping a record in **Google Sheets**. Perfect for businesses tracking market moves or SaaS competitors!\n\n---\n\n## 🟢 **SECTION 1: Fetch the Latest Pricing Info**\n\n### 📡 Scheduled Scraping Using Bright Data\n\n| 🧩 Nodes Involved                   | 💬 Description                                                                                                                                               |\n| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| 🕒 **Check Pricing Every Hour**     | This **Schedule Trigger** runs your workflow automatically (e.g., every hour). You don’t have to manually check the website.                                 |\n| 🌐 **Fetch Page via Bright Data**   | Uses **Bright Data Web Unlocker API** to bypass bot protections and fetch the HTML of the pricing page from a competitor site (e.g., Wix, Squarespace, etc). |\n| 🧾 **Extract HTML Content**         | This node pulls out the actual **HTML code** of the page from the API response, ready to be analyzed.                                                        |\n| 🔧 **Format & Isolate Price Block** | This custom code node filters or extracts just the **pricing section** (e.g., plan names, \\$ amounts) from the HTML to compare later.                        |\n\n> ✅ **Advantage for Beginners**: You don’t need to manually visit or inspect the site. Everything is automated and updated behind the scenes.\n\n---\n\n## 🟡 **SECTION 2: Check If the Price Has Changed**\n\n### 🔍 Compare New Data with the Last Saved One\n\n| 🧩 Nodes Involved            | 💬 Description                                                                                                                                                                                          |\n| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| 📄 **Read Last Saved Price** | This reads from a **Google Sheet** that stores the **last known pricing data**. This becomes your reference point for comparison.                                                                       |\n| 🔁 **Has Price Changed?**    | A simple **IF condition** compares the current scraped pricing to the previously saved one. If the content is **exactly the same**, nothing happens. If it's **different**, it moves to the alert flow. |\n\n> ✅ **Advantage for Beginners**: No need for complex logic. n8n handles the comparison using a basic condition node.\n\n---\n\n## 🔴 **SECTION 3: Alert & Save New Price**\n\n### 🚨 Notify + Update Sheet\n\n| 🧩 Nodes Involved                    | 💬 Description                                                                                                                                          |\n| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| ➖ **No Change Detected – Stop**      | If no changes were found, this does nothing and exits. Keeps your flow efficient.                                                                       |\n| 📄 **Update Stored Price**           | If the price **has changed**, it writes the new value to the **Google Sheet** so future comparisons are accurate.                                       |\n| 📧 **Send Price Change Alert Email** | This node sends a **professional email** (via Gmail) to alert you or your team about the pricing update. The email includes the date and the page link. |\n\n> ✅ **Advantage for Beginners**: No need to monitor email manually or check sheets. You’re notified only when something meaningful happens!\n\n---\n\n## 🖼️ 📊 VISUAL WORKFLOW SUMMARY\n\n```mermaid\ngraph TD;\n  A[🕒 Schedule Trigger] --> B[🌐 Fetch via Bright Data];\n  B --> C[🧾 Extract HTML];\n  C --> D[🔧 Extract Pricing];\n  D --> E[📄 Read Last Price from Sheet];\n  E --> F{🔁 Has Price Changed?};\n  F -- Yes --> G[📄 Update Sheet];\n  G --> H[📧 Send Alert Email];\n  F -- No --> I[➖ Do Nothing];\n```\n\n---\n\n## 🌟 WHY THIS WORKFLOW IS POWERFUL (EVEN FOR BEGINNERS):\n\n| Feature                  | Benefit                                                   |\n| ------------------------ | --------------------------------------------------------- |\n| ✅ No Code                | Drag-and-drop automation — no dev experience needed       |\n| 🔐 Unlocks Sites         | Bright Data handles websites that block scrapers          |\n| 📈 Business Intelligence | Stay competitive by tracking market pricing in real-time  |\n| 💬 Real-time Alerts      | Act fast with Gmail notifications when pricing changes    |\n| 📝 Data Logging          | Google Sheets keeps a historical log of every price point |\n\n---\n\n"},"typeVersion":1},{"id":"eb40dc03-c451-4442-9742-90ca7aa11f16","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[520,0],"parameters":{"color":7,"width":380,"height":240,"content":"## I’ll receive a tiny commission if you join Bright Data through this link—thanks for fueling more free content!\n\n### https://get.brightdata.com/1tndi4600b25"},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"10b3a37b-12c0-4a26-a058-b9950a6e26ff","connections":{"Has Price Changed?":{"main":[[{"node":"No Change Detected – Stop","type":"main","index":0}],[{"node":"Update Stored Price","type":"main","index":0}]]},"Update Stored Price":{"main":[[{"node":"Send Price Change Alert Email","type":"main","index":0}]]},"Extract HTML Content":{"main":[[{"node":"Format & Isolate Price Block","type":"main","index":0}]]},"Read Last Saved Price":{"main":[[{"node":"Has Price Changed?","type":"main","index":0}]]},"Check Pricing Every Day":{"main":[[{"node":"Fetch Page via Bright Data","type":"main","index":0}]]},"Fetch Page via Bright Data":{"main":[[{"node":"Extract HTML Content","type":"main","index":0}]]},"Format & Isolate Price Block":{"main":[[{"node":"Read Last Saved Price","type":"main","index":0}]]}}}


name: Automated Property Market Reports with Bright Data & n8n
author_name: Yaron Been
author_username: yaron-nofluff
nodes_used: ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest","n8n-nodes-base.html"]
categories: []
created_at: 2025-06-24T15:55:09.767Z
updated_at: 2025-06-24T15:55:09.767Z
url: https://n8n.io/workflows/5220
scraped_at: 2025-07-06 21:16:30
description:
  Description

  This workflow automatically generates comprehensive property market reports by scraping real estate listings and market data from multiple sources. It helps real estate professionals save time and provide data-driven insights to clients without manual research.

  Overview

  This workflow automatically generates property market reports by scraping real estate listings and market data. It uses Bright Data to access multiple real estate websites and compiles the data into comprehensive reports.

  Tools Used

  n8n:** The automation platform that orchestrates the workflow.
  Bright Data:** For scraping real estate websites and property data without getting blocked.
  Spreadsheets/Databases:** For storing and analyzing property data.
  Document Generation:** For creating professional PDF reports.

  How to Install

  Import the Workflow: Download the .json file and import it into your n8n instance.
  Configure Bright Data: Add your Bright Data credentials to the Bright Data node.
  Set Up Data Storage: Configure where you want to store the property data.
  Customize: Specify locations, property types, and report format.

  Use Cases

  Real Estate Agents:** Generate market reports for clients.
  Property Investors:** Track market trends in target areas.
  Market Analysts:** Automate data collection for property market analysis.

  Connect with Me

  Website:** https://www.nofluff.online
  YouTube:** https://www.youtube.com/@YaronBeen/videos
  LinkedIn:** https://www.linkedin.com/in/yaronbeen/
  Get Bright Data:** https://get.brightdata.com/1tndi4600b25 (Using this link supports my free workflows with a small commission)

  #n8n #automation #realestate #propertymarket #brightdata #marketreports #propertyanalysis #realestatedata #markettrends #propertyinvestment #n8nworkflow #workflow #nocode #realestateanalysis #propertyreports #realestateintelligence #marketresearch #propertyscraping #realestateautomation #investmentanalysis #propertytrends #datadriven #realestatetech #propertyinsights #marketanalysis #realestateinvesting

workflow_json:
  {"id":"TmVkR7VvM0nMMgE8","meta":{"instanceId":"60046904b104f0f72b2629a9d88fe9f676be4035769f1f08dad1dd38a76b9480","templateCredsSetupCompleted":true},"name":"Property_Market_Report_via_Bright_data","tags":[],"nodes":[{"id":"8891d7b5-79a7-4270-9bf2-374928f36c2a","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[-2160,260],"parameters":{"color":4,"width":1300,"height":320,"content":"=======================================\n            WORKFLOW ASSISTANCE\n=======================================\nFor any questions or support, please contact:\n    Yaron@nofluff.online\n\nExplore more tips and tutorials here:\n   - YouTube: https://www.youtube.com/@YaronBeen/videos\n   - LinkedIn: https://www.linkedin.com/in/yaronbeen/\n=======================================\n"},"typeVersion":1},{"id":"edafc05e-31ee-4451-b0cf-89f83db0cbca","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-2160,600],"parameters":{"color":4,"width":1289,"height":2218,"content":"# 📊 **Commercial Real Estate Weekly Report Automation**\n\nThis automation helps you **scrape commercial property listings** (like office and retail spaces) from top websites using **Bright Data**, and automatically stores that data into a **Google Sheet**, ready for reporting or analysis.\n\n---\n\n## 🔹 **SECTION 1: 🔁 Automate + Scrape Listings**\n\n### 🧩 1. 📆 Weekly Market Trigger\n\n**Node Name:** `Weekly Market Trigger`\n**What it does:**\nThis node automatically starts the workflow every week (e.g., Monday at 8 AM). You don't have to press a button — it just runs in the background.\n\n🧠 **Beginner Benefit:**\n\n> Automate your market research without ever missing a week. Set it once and let it run!\n\n---\n\n### 🧩 2. 🌐 Fetch Listings via Bright Data\n\n**Node Name:** `Fetch Listings via Bright Data`\n**What it does:**\nThis node sends a `POST` request to **Bright Data Web Unlocker API**, which is a tool that bypasses captchas, anti-bot systems, and complex JavaScript-loaded pages to give you clean HTML content.\n\n**It targets a URL like:**\n\n```\nhttps://www.loopnet.com/for-lease/office/san-francisco-ca/\n```\n\n🛡️ Bright Data ensures the page is accessed as if it's being opened by a real user — no blocks, no errors.\n\n🧠 **Beginner Benefit:**\n\n> Even if a website has bot protections or hidden content, this node ensures you can access the data consistently and safely.\n\n---\n\n## 🔸 **SECTION 2: 🧱 Extract + Save Listings**\n\n### 🧩 3. 🧱 Extract Listing Details (HTML)\n\n**Node Name:** `Extract Listing Details (HTML)`\n**What it does:**\nIt scans the HTML content from the Bright Data response and pulls out important fields like:\n\n* 🏢 Property Title\n* 💵 Price\n* 📍 Address\n* 📐 Size\n* 🔗 Link to the listing\n\nUses **CSS selectors** like `.listing-title` or `.price-info` to find this info.\n\n🧠 **Beginner Benefit:**\n\n> This node turns messy website code into clean, structured data you can actually use in a report or analysis.\n\n---\n\n### 🧩 4. 📊 Save to Google Sheets\n\n**Node Name:** `Save to Google Sheets`\n**What it does:**\nThis final step **appends each extracted listing** into a Google Sheet in real time.\n\nYou’ll get a spreadsheet like this:\n\n| Title | Price | Address | Size | URL |\n| ----- | ----- | ------- | ---- | --- |\n\n🧠 **Beginner Benefit:**\n\n> Your scraped data is saved instantly where you can filter, chart, or share it with clients or your team.\n\n---\n\n## 🚀 **What You Can Do With This Workflow**\n\n* 📈 Track weekly commercial real estate trends\n* 🧠 Compare price per square foot by neighborhood\n* 📨 Send reports to clients or investors\n* 🔁 Use Google Sheets to trigger visual dashboards\n\n---\n\n## 🎁 Want to Make It Better?\n\n* Add a ✉️ **Slack or Email notification** node at the end\n* Use a 🪄 **Markdown Generator** to create beautiful weekly summaries\n* Append data to **separate tabs by week** for historical tracking\n\n---\n"},"typeVersion":1},{"id":"f1c420c9-ad46-48a5-83cf-f43a6377241c","name":"Weekly Market Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[-400,1660],"parameters":{"rule":{"interval":[{"field":"weeks","triggerAtDay":[1],"triggerAtHour":9}]}},"typeVersion":1.2},{"id":"a8acbc10-66cf-4568-b81d-4fce0ec576e7","name":"Fetch Listings via Bright Data","type":"n8n-nodes-base.httpRequest","position":[-180,1660],"parameters":{"url":"https://api.brightdata.com/request","method":"POST","options":{},"sendBody":true,"sendHeaders":true,"bodyParameters":{"parameters":[{"name":"zone","value":"n8n_unblocker"},{"name":"url","value":"https://www.crexi.com/properties?geo=san-francisco-ca"},{"name":"country","value":"us"},{"name":"format","value":"raw"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2},{"id":"800989c9-af12-4c5f-b7a4-4a2ea290110f","name":"Extract Listing Details (HTML)","type":"n8n-nodes-base.html","position":[120,1660],"parameters":{"options":{},"operation":"extractHtmlContent","extractionValues":{"values":[{"key":"Price","cssSelector":"<span _ngcontent-ng-c2107907900=\"\" data-cy=\"propertyPrice\" class=\"ng-star-inserted\">$3,995,000</span>","returnArray":true}]}},"typeVersion":1.2},{"id":"54724fca-c18d-44df-a0e7-f267ddd09d73","name":"Save to Google Sheets","type":"n8n-nodes-base.googleSheets","position":[340,1660],"parameters":{"operation":"append","sheetName":{"__rl":true,"mode":"list","value":""},"documentId":{"__rl":true,"mode":"list","value":""}},"credentials":{"googleSheetsOAuth2Api":{"id":"r2mDaisH6e9VkwHl","name":"Google Sheets account"}},"typeVersion":4.6},{"id":"3d8af14f-3cb5-4f4f-aa71-be521322c113","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-440,720],"parameters":{"color":6,"width":420,"height":1120,"content":"## 🔹 **SECTION 1: 🔁 Automate + Scrape Listings**\n\n### 🧩 1. 📆 Weekly Market Trigger\n\n**Node Name:** `Weekly Market Trigger`\n**What it does:**\nThis node automatically starts the workflow every week (e.g., Monday at 8 AM). You don't have to press a button — it just runs in the background.\n\n🧠 **Beginner Benefit:**\n\n> Automate your market research without ever missing a week. Set it once and let it run!\n\n---\n\n### 🧩 2. 🌐 Fetch Listings via Bright Data\n\n**Node Name:** `Fetch Listings via Bright Data`\n**What it does:**\nThis node sends a `POST` request to **Bright Data Web Unlocker API**, which is a tool that bypasses captchas, anti-bot systems, and complex JavaScript-loaded pages to give you clean HTML content.\n\n**It targets a URL like:**\n\n```\nhttps://www.loopnet.com/for-lease/office/san-francisco-ca/\n```\n\n🛡️ Bright Data ensures the page is accessed as if it's being opened by a real user — no blocks, no errors.\n\n🧠 **Beginner Benefit:**\n\n> Even if a website has bot protections or hidden content, this node ensures you can access the data consistently and safely.\n\n---\n"},"typeVersion":1},{"id":"2fd2d9bb-ec9c-48c7-a745-bd5b653e76b5","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[60,700],"parameters":{"color":5,"width":420,"height":1140,"content":"## 🔸 **SECTION 2: 🧱 Extract + Save Listings**\n\n### 🧩 3. 🧱 Extract Listing Details (HTML)\n\n**Node Name:** `Extract Listing Details (HTML)`\n**What it does:**\nIt scans the HTML content from the Bright Data response and pulls out important fields like:\n\n* 🏢 Property Title\n* 💵 Price\n* 📍 Address\n* 📐 Size\n* 🔗 Link to the listing\n\nUses **CSS selectors** like `.listing-title` or `.price-info` to find this info.\n\n🧠 **Beginner Benefit:**\n\n> This node turns messy website code into clean, structured data you can actually use in a report or analysis.\n\n---\n\n### 🧩 4. 📊 Save to Google Sheets\n\n**Node Name:** `Save to Google Sheets`\n**What it does:**\nThis final step **appends each extracted listing** into a Google Sheet in real time.\n\nYou’ll get a spreadsheet like this:\n\n| Title | Price | Address | Size | URL |\n| ----- | ----- | ------- | ---- | --- |\n\n🧠 **Beginner Benefit:**\n\n> Your scraped data is saved instantly where you can filter, chart, or share it with clients or your team.\n\n---\n"},"typeVersion":1},{"id":"82aa81aa-39af-410e-9434-ee6189aabc7b","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[560,700],"parameters":{"color":7,"width":380,"height":240,"content":"## I’ll receive a tiny commission if you join Bright Data through this link—thanks for fueling more free content!\n\n### https://get.brightdata.com/1tndi4600b25"},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"b60c01a8-a0b5-43de-bde0-5fa9fd1bb732","connections":{"Weekly Market Trigger":{"main":[[{"node":"Fetch Listings via Bright Data","type":"main","index":0}]]},"Extract Listing Details (HTML)":{"main":[[{"node":"Save to Google Sheets","type":"main","index":0}]]},"Fetch Listings via Bright Data":{"main":[[{"node":"Extract Listing Details (HTML)","type":"main","index":0}]]}}}


name: Automate Research Paper Collection with Bright Data & n8n
author_name: Yaron Been
author_username: yaron-nofluff
categories: []
created_at: 2025-06-24T15:55:40.455Z
updated_at: 2025-06-24T15:55:40.455Z
url: https://n8n.io/workflows/5221
scraped_at: 2025-07-06 21:16:30
description:
  Description

  This workflow automatically collects and organizes research papers from academic databases and journals into Google Sheets. It helps researchers and students save time by eliminating manual searches across multiple academic sources and centralizing research materials.

  Overview

  This workflow automatically scrapes research papers from academic databases and journals, then organizes them in Google Sheets. It uses Bright Data to access academic sources and extracts key information like titles, authors, abstracts, and citations.

  Tools Used

  n8n:** The automation platform that orchestrates the workflow.
  Bright Data:** For scraping academic websites and research databases without getting blocked.
  Google Sheets:** For organizing and storing research paper data.

  How to Install

  Import the Workflow: Download the .json file and import it into your n8n instance.
  Configure Bright Data: Add your Bright Data credentials to the Bright Data node.
  Connect Google Sheets: Authenticate your Google account.
  Customize: Specify research topics, journals, or authors to track.

  Use Cases

  Academic Researchers:** Stay updated on new papers in your field.
  Students:** Collect research for literature reviews and dissertations.
  Research Teams:** Collaborate on literature databases.

  Connect with Me

  Website:** https://www.nofluff.online
  YouTube:** https://www.youtube.com/@YaronBeen/videos
  LinkedIn:** https://www.linkedin.com/in/yaronbeen/
  Get Bright Data:** https://get.brightdata.com/1tndi4600b25 (Using this link supports my free workflows with a small commission)

  #n8n #automation #research #academicpapers #brightdata #googlesheets #researchpapers #academicresearch #literaturesearch #scholarlyarticles #n8nworkflow #workflow #nocode #researchautomation #academicscraping #researchtools #papertracking #academicjournals #researchdatabase #literaturereview #academicwriting #datascraping #researchorganization #scholarlyresearch #citationmanagement #academicproductivity

nodes_used:
  ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest","n8n-nodes-base.code","n8n-nodes-base.html"]

workflow_json:
  {"id":"giq3zqaP4QbY6LgC","meta":{"instanceId":"60046904b104f0f72b2629a9d88fe9f676be4035769f1f08dad1dd38a76b9480"},"name":"Research_Paper_Scraper_to_Google_Sheets","tags":[],"nodes":[{"id":"7d81edf3-6f00-4634-b79f-dbda3f9958e5","name":"Start Scraping (Manual Trigger)","type":"n8n-nodes-base.manualTrigger","position":[-1080,580],"parameters":{},"typeVersion":1},{"id":"6e172db5-7483-4079-bf8a-785602526bdc","name":"Set Research topic","type":"n8n-nodes-base.set","position":[-860,580],"parameters":{"options":{},"assignments":{"assignments":[{"id":"b530a847-0bb2-4039-9ad0-cbc9cc4d909e","name":"Topic","type":"string","value":"machine+learning"}]}},"typeVersion":3.4},{"id":"e65d092a-6854-478c-b33e-2fc309f71ae8","name":"Send Request to Bright Data API","type":"n8n-nodes-base.httpRequest","position":[-600,580],"parameters":{"url":"https://api.brightdata.com/request","method":"POST","options":{},"sendBody":true,"sendHeaders":true,"bodyParameters":{"parameters":[{"name":"zone","value":"n8n_unblocker"},{"name":"url","value":"=https://scholar.google.com/scholar?q={{ $json.Topic }}"},{"name":"country","value":"us"},{"name":"format","value":"raw"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2},{"id":"211bae33-32c5-44e8-b306-a5e0d520a4a0","name":"Extract Data from HTML (Title, Author, etc.)","type":"n8n-nodes-base.html","position":[-400,580],"parameters":{"options":{},"operation":"extractHtmlContent","extractionValues":{"values":[{"key":"Title","cssSelector":"h3.gs_rt, a.gs_rt","returnArray":true},{"key":"Author","cssSelector":"div.gs_a","returnArray":true},{"key":"Abstract","cssSelector":"div.gs_rs","returnArray":true},{"key":"PDF Link\t","cssSelector":"a[href*='pdf']","returnArray":true,"returnValue":"attribute"}]}},"typeVersion":1.2},{"id":"9ab7ba20-8614-46c5-b57a-3749d6ae04c4","name":"Clean & Structure Extracted Data","type":"n8n-nodes-base.code","position":[-200,580],"parameters":{"jsCode":"const titles = items[0].json.Title || [];\nconst authors = items[0].json.Author || [];\nconst abstracts = items[0].json.Abstract || [];\nconst pdfLinks = items[0].json[\"PDF Link\\t\"] || [];\n\nconst output = [];\n\nfor (let i = 0; i < titles.length; i++) {\n  // Clean title (remove tags like [PDF][B])\n  let title = titles[i].replace(/\\[.*?\\]/g, '').trim();\n\n  // Clean author (remove any trailing dashes or HTML leftovers)\n  let author = authors[i] ? authors[i].replace(/\\s*-\\s*.*/, '').trim() : '';\n\n  // Abstract fallback\n  let abstract = abstracts[i] || '';\n\n  // Get PDF link — from either a single object or array of duplicates\n  let linkObj = pdfLinks[i];\n  let pdfLink = '';\n\n  if (Array.isArray(linkObj)) {\n    // If multiple objects per item\n    pdfLink = linkObj.find(obj => obj.href)?.href || '';\n  } else if (linkObj?.href) {\n    pdfLink = linkObj.href;\n  }\n\n  // Push cleaned object\n  output.push({\n    json: {\n      title,\n      author,\n      abstract,\n      pdfLink\n    }\n  });\n}\n\nreturn output;\n"},"typeVersion":2},{"id":"a246f20c-2bb9-4319-8812-e296c87a7df0","name":"Save Results to Google Sheet","type":"n8n-nodes-base.googleSheets","position":[120,580],"parameters":{"columns":{"value":{"Topic":"={{ $('Set Research topic').item.json.Topic }}","title":"={{ $json.title }}","author":"={{ $json.author }}","abstract":"={{ $json.abstract }}","pdf link":"={{ $json.pdfLink }}"},"schema":[{"id":"Topic","type":"string","display":true,"required":false,"displayName":"Topic","defaultMatch":false,"canBeUsedToMatch":true},{"id":"title","type":"string","display":true,"required":false,"displayName":"title","defaultMatch":false,"canBeUsedToMatch":true},{"id":"author","type":"string","display":true,"required":false,"displayName":"author","defaultMatch":false,"canBeUsedToMatch":true},{"id":"abstract","type":"string","display":true,"required":false,"displayName":"abstract","defaultMatch":false,"canBeUsedToMatch":true},{"id":"pdf link","type":"string","display":true,"required":false,"displayName":"pdf link","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"append","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1sOfCFsvHS9-BeE_PQ6J_jtQofCRcOv02XS7hrmFmpxQ/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1sOfCFsvHS9-BeE_PQ6J_jtQofCRcOv02XS7hrmFmpxQ","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1sOfCFsvHS9-BeE_PQ6J_jtQofCRcOv02XS7hrmFmpxQ/edit?usp=drivesdk","cachedResultName":"Research papers from Google Scholar"}},"credentials":{"googleSheetsOAuth2Api":{"id":"r2mDaisH6e9VkwHl","name":"Google Sheets account"}},"typeVersion":4.6},{"id":"1b4a1504-4a4a-4a0d-892b-d0c3e205ed85","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1140,60],"parameters":{"color":5,"width":420,"height":720,"content":"## 🔹 **Section 1: User Input & Trigger**\n\n**🧩 Nodes: Start Scraping | Set Topic**\n📍 **Purpose:** Let users easily input the topic they want to scrape — no need to deal with complex URLs.\n\n| 🧱 Node   | ✅ New Name                   | 💡 Description                                                                                                                                                                         |\n| --------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| ⚡ Trigger | **Start Scraping (Manual)**  | This node starts the workflow when you click “Execute Workflow.” It's the entry point.                                                                                                 |\n| ✏️ Set    | **Set Topic (Manual Input)** | Instead of requiring a URL, the user will enter a topic (like \"machine learning\" or \"digital marketing\"). This topic will be used to automatically generate the URL behind the scenes. |\n\n### 🧠 How it helps:\n\n* Great for beginners: Just type the topic, hit run.\n* Keeps the interface clean and user-friendly.\n* Avoids confusion around URLs and formats.\n\n---\n\n"},"typeVersion":1},{"id":"bc56f528-6d18-4e05-942f-c06bb6e10b27","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-660,80],"parameters":{"color":6,"width":600,"height":700,"content":"## 🔸 **Section 2: Scrape & Parse Website**\n\n**🧩 Nodes: Send Request | Extract HTML | Clean Data**\n📍 **Purpose:** Uses the Bright Data proxy to access the webpage, extract raw HTML content, and clean it up into a readable format (title, author, abstract, etc.).\n\n| 🧱 Node         | ✅ New Name                            | 💡 Description                                                                                                                                                        |\n| --------------- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| 🌐 HTTP Request | **Send Topic Request to Bright Data** | This sends a request to the Bright Data API using the topic you set earlier. It uses Bright Data’s network to safely load the actual website and return HTML content. |\n| 🧱 HTML Extract | **Extract Data from Webpage**         | Parses the returned HTML to find relevant data like titles, authors, abstracts, and links.                                                                            |\n| 🔣 Code         | **Clean and Format Scraped Data**     | A custom code block that organizes the messy data into neat records. For example: title → column A, abstract → column B, etc.                                         |\n\n### 🧠 How it helps:\n\n* Makes web scraping safe and reliable by using proxies.\n* Converts unreadable HTML into structured information.\n* Beginner-friendly: No need to write a parser yourself.\n\n---\n\n"},"typeVersion":1},{"id":"2c54e5e6-011a-4562-98ac-9cc9834bc284","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[0,0],"parameters":{"color":3,"width":340,"height":780,"content":"## 🟢 **Section 3: Save to Google Sheets**\n\n**🧩 Node: Append to Google Sheets**\n📍 **Purpose:** Automatically sends the clean data into a Google Sheet for easy access, filtering, or sharing.\n\n| 🧱 Node          | ✅ New Name                            | 💡 Description                                                                                                                      |\n| ---------------- | ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |\n| 📄 Google Sheets | **Store Scraped Data in Spreadsheet** | Takes the structured output and appends it to the connected Google Sheet. Each result gets a row with title, author, abstract, etc. |\n\n### 🧠 How it helps:\n\n* No manual copy-pasting ever again!\n* Shareable and searchable format.\n* Updates automatically as you scrape more topics.\n\n---\n\n"},"typeVersion":1},{"id":"4ce90703-961e-4070-9356-c9dffc23a6c5","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[-2980,80],"parameters":{"color":4,"width":1300,"height":320,"content":"=======================================\n            WORKFLOW ASSISTANCE\n=======================================\nFor any questions or support, please contact:\n    Yaron@nofluff.online\n\nExplore more tips and tutorials here:\n   - YouTube: https://www.youtube.com/@YaronBeen/videos\n   - LinkedIn: https://www.linkedin.com/in/yaronbeen/\n=======================================\n"},"typeVersion":1},{"id":"069ddb89-f7a1-4c4b-b65d-212be3252750","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-2980,420],"parameters":{"color":4,"width":1289,"height":1878,"content":"## 🌟 Research Paper Scraper to Google Sheets\n\n**Automate extraction of data from any website based on a topic — no coding needed!**\n\n---\n\n## 🔹 **Section 1: User Input & Trigger**\n\n**🧩 Nodes: Start Scraping | Set Topic**\n📍 **Purpose:** Let users easily input the topic they want to scrape — no need to deal with complex URLs.\n\n| 🧱 Node   | ✅ New Name                   | 💡 Description                                                                                                                                                                         |\n| --------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| ⚡ Trigger | **Start Scraping (Manual)**  | This node starts the workflow when you click “Execute Workflow.” It's the entry point.                                                                                                 |\n| ✏️ Set    | **Set Topic (Manual Input)** | Instead of requiring a URL, the user will enter a topic (like \"machine learning\" or \"digital marketing\"). This topic will be used to automatically generate the URL behind the scenes. |\n\n### 🧠 How it helps:\n\n* Great for beginners: Just type the topic, hit run.\n* Keeps the interface clean and user-friendly.\n* Avoids confusion around URLs and formats.\n\n---\n\n## 🔸 **Section 2: Scrape & Parse Website**\n\n**🧩 Nodes: Send Request | Extract HTML | Clean Data**\n📍 **Purpose:** Uses the Bright Data proxy to access the webpage, extract raw HTML content, and clean it up into a readable format (title, author, abstract, etc.).\n\n| 🧱 Node         | ✅ New Name                            | 💡 Description                                                                                                                                                        |\n| --------------- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| 🌐 HTTP Request | **Send Topic Request to Bright Data** | This sends a request to the Bright Data API using the topic you set earlier. It uses Bright Data’s network to safely load the actual website and return HTML content. |\n| 🧱 HTML Extract | **Extract Data from Webpage**         | Parses the returned HTML to find relevant data like titles, authors, abstracts, and links.                                                                            |\n| 🔣 Code         | **Clean and Format Scraped Data**     | A custom code block that organizes the messy data into neat records. For example: title → column A, abstract → column B, etc.                                         |\n\n### 🧠 How it helps:\n\n* Makes web scraping safe and reliable by using proxies.\n* Converts unreadable HTML into structured information.\n* Beginner-friendly: No need to write a parser yourself.\n\n---\n\n## 🟢 **Section 3: Save to Google Sheets**\n\n**🧩 Node: Append to Google Sheets**\n📍 **Purpose:** Automatically sends the clean data into a Google Sheet for easy access, filtering, or sharing.\n\n| 🧱 Node          | ✅ New Name                            | 💡 Description                                                                                                                      |\n| ---------------- | ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |\n| 📄 Google Sheets | **Store Scraped Data in Spreadsheet** | Takes the structured output and appends it to the connected Google Sheet. Each result gets a row with title, author, abstract, etc. |\n\n### 🧠 How it helps:\n\n* No manual copy-pasting ever again!\n* Shareable and searchable format.\n* Updates automatically as you scrape more topics.\n\n---\n\n## ✅ What a Beginner Gains from This Workflow\n\n| 💡 Feature                  | 🚀 Benefit                                                                        |\n| --------------------------- | --------------------------------------------------------------------------------- |\n| Topic-based input           | You don’t need to find or understand complex URLs. Just type “AI” or “marketing.” |\n| Fully automated scraping    | You don’t need to open browsers or inspect elements.                              |\n| Ready-to-use Google Sheet   | The final data is clean and saved into a sheet you can use anywhere.              |\n| Beautiful, modular workflow | Each step is visual, editable, and reusable without coding skills.                |\n\n---\n\n## 🎯 Final Result:\n\nYou type a **topic** → Bright Data scrapes the web → It extracts content → Cleans it → Saves it into **Google Sheets**.\nEverything happens automatically. **No code. No hassle. Just data.**\n\n---\n\n"},"typeVersion":1},{"id":"a1a5e609-756a-4757-a026-1349cf388e61","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[400,0],"parameters":{"color":7,"width":380,"height":240,"content":"## I’ll receive a tiny commission if you join Bright Data through this link—thanks for fueling more free content!\n\n### https://get.brightdata.com/1tndi4600b25"},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"f931202a-3c22-495d-b775-71665bdf6c27","connections":{"Set Research topic":{"main":[[{"node":"Send Request to Bright Data API","type":"main","index":0}]]},"Send Request to Bright Data API":{"main":[[{"node":"Extract Data from HTML (Title, Author, etc.)","type":"main","index":0}]]},"Start Scraping (Manual Trigger)":{"main":[[{"node":"Set Research topic","type":"main","index":0}]]},"Clean & Structure Extracted Data":{"main":[[{"node":"Save Results to Google Sheet","type":"main","index":0}]]},"Extract Data from HTML (Title, Author, etc.)":{"main":[[{"node":"Clean & Structure Extracted Data","type":"main","index":0}]]}}}


name: Find the Best Airbnb Deals Automatically with Bright Data & n8n
author_name: Yaron Been
author_username: yaron-nofluff
nodes_used: ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest","n8n-nodes-base.code"]
categories: []
created_at: 2025-06-24T15:56:58.236Z
updated_at: 2025-06-24T15:56:58.236Z
url: https://n8n.io/workflows/5224
scraped_at: 2025-07-06 21:16:30
description:
  F

  Description

  This workflow automatically searches Airbnb for the best deals in your target locations and saves them for later reference. It helps travelers find affordable accommodations by continuously monitoring listings and identifying properties that match your budget and preferences.

  Overview

  This workflow automatically searches Airbnb for the best deals in your target locations and saves them for later reference. It uses Bright Data to scrape Airbnb listings and can filter results based on your preferences for price, amenities, and ratings.

  Tools Used

  n8n:** The automation platform that orchestrates the workflow.
  Bright Data:** For scraping Airbnb listings without being blocked.
  Spreadsheets/Databases:** For storing and comparing property deals.

  How to Install

  Import the Workflow: Download the .json file and import it into your n8n instance.
  Configure Bright Data: Add your Bright Data credentials to the Bright Data node.
  Set Up Data Storage: Configure where you want to store the Airbnb deals.
  Customize: Specify locations, date ranges, and your budget constraints.

  Use Cases

  Travelers:** Find the best accommodation deals for your trips.
  Digital Nomads:** Track affordable long-term stays in different locations.
  Property Managers:** Monitor competitor pricing in your area.

  Connect with Me

  Website:** https://www.nofluff.online
  YouTube:** https://www.youtube.com/@YaronBeen/videos
  LinkedIn:** https://www.linkedin.com/in/yaronbeen/
  Get Bright Data:** https://get.brightdata.com/1tndi4600b25 (Using this link supports my free workflows with a small commission)

  #n8n #automation #airbnb #travel #brightdata #dealhunting #vacationrentals #traveldeals #accommodationdeals #airbnbdeals #n8nworkflow #workflow #nocode #travelhacks #budgettravel #propertydeals #travelplanning #airbnbscraper #vacationplanning #bestairbnbs #travelautomation #affordableaccommodation #staydeals #traveltech #digitalnomad #accommodationfinder

workflow_json:
  {"id":"kO0kNE2AKKzesj0F","meta":{"instanceId":"60046904b104f0f72b2629a9d88fe9f676be4035769f1f08dad1dd38a76b9480"},"name":"Store_Best_Deals_on_Airbnb","tags":[],"nodes":[{"id":"3be17a72-1d6a-4bea-a36c-708125eef7ef","name":"Run Daily (9 AM)","type":"n8n-nodes-base.scheduleTrigger","position":[20,1020],"parameters":{"rule":{"interval":[{"triggerAtHour":9}]}},"typeVersion":1.2},{"id":"d47e5caa-a861-4dad-9f48-52e816fc7a71","name":"Set Search Criteria","type":"n8n-nodes-base.set","position":[240,1020],"parameters":{"options":{},"assignments":{"assignments":[{"id":"9426515e-7232-483f-ae94-09cf500c8dc4","name":"Location","type":"string","value":"Los-Angeles"},{"id":"61bc5a40-687c-4f49-b9dc-ee0f24511b6f","name":"checkin","type":"string","value":"2025-09-15"},{"id":"5bc0153f-90cc-43cc-92b0-64c87dcc4e59","name":"checkout","type":"string","value":"2025-09-20"},{"id":"e6b268f2-c05a-44ed-9303-c0def3abf4fe","name":"adults","type":"number","value":2}]}},"typeVersion":3.4},{"id":"80e8b765-0840-47d3-b591-060f82bb97c2","name":"Scrape Airbnb via Bright Data","type":"n8n-nodes-base.httpRequest","position":[500,1020],"parameters":{"url":"https://api.brightdata.com/request","method":"POST","options":{},"sendBody":true,"sendHeaders":true,"bodyParameters":{"parameters":[{"name":"zone","value":"n8n_unblocker"},{"name":"url","value":"=https://www.airbnb.com/s/{{ $json.Location }}--CA--United-States/homes?checkin={{ $json.checkin }}&checkout={{ $json.checkout }}&adults={{ $json.adults }}"},{"name":"country","value":"us"},{"name":"format","value":"raw"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE KEY"}]}},"typeVersion":4.2},{"id":"59da6712-9264-4622-a2ca-9791a892d336","name":"Extract Price & Title","type":"n8n-nodes-base.code","position":[720,1020],"parameters":{"jsCode":"// Get the HTML content from the previous node.\n// Assuming your HTTP Request node's output is named 'data'.\nconst html = items[0].json.data;\n\n// This regex finds the specific <script> tag containing the search results.\nconst regex = /<script id=\"data-deferred-state-0\"[^>]*>([\\s\\S]*?)<\\/script>/;\nconst match = html.match(regex);\n\nif (!match || !match[1]) {\n  console.log(\"Could not find the data script tag.\");\n  return [{\n    error: \"Data script tag not found. The page structure might have changed.\"\n  }];\n}\n\ntry {\n  // Parse the JSON string found inside the script tag.\n  const jsonData = JSON.parse(match[1]);\n\n  // Navigate through the complex object to find the search results array.\n  // Using optional chaining (?.) prevents errors if a key doesn't exist.\n  const searchResults = jsonData?.niobeMinimalClientData?.[0]?.[1]?.data?.presentation?.staysSearch?.results?.searchResults;\n\n  if (!searchResults || !Array.isArray(searchResults)) {\n    console.log(\"Could not find search results in the JSON data.\");\n    return [{\n      error: \"Search results not found in the JSON data. The data structure may have changed.\"\n    }];\n  }\n\n  // Map over the results to extract the title and price for each listing.\n  const listings = searchResults.map(item => {\n    const title = item.title;\n    \n    // The price can be in 'discountedPrice' or 'price', so we check for both.\n    const primaryLine = item.structuredDisplayPrice?.primaryLine;\n    let price = \"N/A\";\n    if (primaryLine) {\n      const priceValue = primaryLine.discountedPrice || primaryLine.price;\n      const qualifier = primaryLine.qualifier || '';\n      price = `${priceValue} ${qualifier}`.trim();\n    }\n\n    return {\n      title,\n      price,\n    };\n  });\n\n  // n8n expects an array of objects to be returned.\n  // Each object will become a separate item for the next node.\n  return listings;\n\n} catch (e) {\n  console.error(\"Error parsing JSON data:\", e);\n  return [{\n    error: \"Failed to parse JSON data from the script tag.\"\n  }];\n}"},"typeVersion":2},{"id":"4710e13c-3ce5-4980-bfbf-727b4a425ae3","name":"Save to Google Sheets","type":"n8n-nodes-base.googleSheets","position":[1000,1020],"parameters":{"columns":{"value":{"Price":"={{ $json.price }}","Title":"={{ $json.title }}","Adults":"={{ $('Set Search Criteria').item.json.adults }}","CheckIn":"={{ $('Set Search Criteria').item.json.checkin }}","CheckOut":"={{ $('Set Search Criteria').item.json.checkout }}","Location":"={{ $('Set Search Criteria').item.json.Location }}"},"schema":[{"id":"Location","type":"string","display":true,"required":false,"displayName":"Location","defaultMatch":false,"canBeUsedToMatch":true},{"id":"CheckIn","type":"string","display":true,"required":false,"displayName":"CheckIn","defaultMatch":false,"canBeUsedToMatch":true},{"id":"CheckOut","type":"string","display":true,"required":false,"displayName":"CheckOut","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Adults","type":"string","display":true,"required":false,"displayName":"Adults","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Price","type":"string","display":true,"required":false,"displayName":"Price","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Title","type":"string","display":true,"required":false,"displayName":"Title","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"append","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1nwNkfh8n1qr6ft5mF3PhhDTTaDXb1K_4H3gd3D-nADc/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1nwNkfh8n1qr6ft5mF3PhhDTTaDXb1K_4H3gd3D-nADc","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1nwNkfh8n1qr6ft5mF3PhhDTTaDXb1K_4H3gd3D-nADc/edit?usp=drivesdk","cachedResultName":"Rooms on Airbnb"}},"credentials":{"googleSheetsOAuth2Api":{"id":"r2mDaisH6e9VkwHl","name":"Google Sheets account"}},"typeVersion":4.6},{"id":"7e0664d1-40ce-4498-b412-6ebc60fc9a7f","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[0,0],"parameters":{"color":6,"width":380,"height":1180,"content":"## 🟢 **Section 1: 🧭 Define & Trigger the Search**\n\n### 🧩 Nodes:\n\n1. ⏰ **Run Daily**\n2. 🛠 **Set Search Criteria**\n\n---\n\n### ✨ What's Happening Here:\n\n#### ⏰ **Run Daily**\n\n* This node is your **alarm clock** ⏰.\n* It automatically **starts the workflow** based on a schedule (e.g., daily at 8:00 AM).\n* You never need to click \"Execute Workflow\" manually again — it's 100% hands-free.\n\n> *“Imagine this as your personal assistant waking up every day to go find vacation deals for you.”*\n\n#### 🛠 **Set Search Criteria**\n\n* This is where you **set your filters**: destination, travel dates, number of guests.\n* For example:\n\n  ```json\n  {\n    \"location\": \"Los Angeles\",\n    \"checkin\": \"2025-09-15\",\n    \"checkout\": \"2025-09-20\",\n    \"adults\": 2\n  }\n  ```\n* This data will be **used in the scraping URL** sent to Airbnb through Bright Data.\n\n> *“It’s like telling your assistant: ‘Look for 2-person stays in LA from Sept 15–20.’”*\n\n---\n\n"},"typeVersion":1},{"id":"b3904951-145f-44dd-947d-d99194798798","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[420,60],"parameters":{"color":3,"width":440,"height":1120,"content":"## 🌐 **Section 2: 🚀 Scrape & Extract Airbnb Data**\n\n### 🧩 Nodes:\n\n3. 🌐 **Scrape Airbnb via Bright Data**\n4. 🧠 **Extract Price & Title**\n\n---\n\n### ✨ What's Happening Here:\n\n#### 🌐 **Scrape Airbnb via Bright Data**\n\n* This node **sends a request** to Airbnb using **Bright Data Web Unlocker**.\n* Bright Data acts like a **stealth browser** 🕵️ that avoids blocks and loads the real webpage for you.\n* It fetches all the page data (even if Airbnb tries to hide it from bots).\n\n> *“Imagine Bright Data as your super-sneaky browser that can go where others can't.”*\n\n#### 🧠 **Extract Price & Title**\n\n* The raw response from Airbnb (HTML or JSON) is **parsed** in this Code node.\n* The code looks for:\n\n  * 🏷️ **Listing Title**\n  * 💰 **Price per night**\n* These are pulled out from the messy page code and transformed into clean data items.\n\n> *“It’s like using a fine-tooth comb to extract the useful info from a messy travel brochure.”*\n\n---\n\n"},"typeVersion":1},{"id":"c41d599a-6211-4d0b-a392-212d2f948612","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[900,280],"parameters":{"color":5,"width":320,"height":900,"content":"## 📄 **Section 3: 🧾 Store the Results**\n\n### 🧩 Node:\n\n5. 📄 **Save to Google Sheets**\n\n---\n\n### ✨ What's Happening Here:\n\n#### 📄 **Save to Google Sheets**\n\n* All the extracted data (titles and prices) are **stored row-by-row** in a Google Sheet.\n* Each day adds a new set of listings, creating a full **price history** over time.\n* You can use this sheet to:\n\n  * Track **price changes**\n  * Find **off-peak bargains**\n  * Compare cities or time periods\n\n> *“This is your digital notebook where every deal is neatly logged for review, comparison, or alerts.”*\n\n---\n\n"},"typeVersion":1},{"id":"6d833041-f1a3-40e4-a192-78aa903cb9e7","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[-1880,20],"parameters":{"color":4,"width":1300,"height":320,"content":"=======================================\n            WORKFLOW ASSISTANCE\n=======================================\nFor any questions or support, please contact:\n    Yaron@nofluff.online\n\nExplore more tips and tutorials here:\n   - YouTube: https://www.youtube.com/@YaronBeen/videos\n   - LinkedIn: https://www.linkedin.com/in/yaronbeen/\n=======================================\n"},"typeVersion":1},{"id":"1adeb274-de15-4f85-b198-5a235ae934a5","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-1880,360],"parameters":{"color":4,"width":1289,"height":2738,"content":"# 🌟 Automation Overview: “Find Best Airbnb Deals (Daily Tracker)”\n\nThis n8n workflow automatically scrapes Airbnb listings every day and records the **title and price** of each rental into **Google Sheets**, helping you track the best travel deals over time — perfect for deal hunters, travel bloggers, or market researchers!\n\n---\n\n## 🟢 **Section 1: 🧭 Define & Trigger the Search**\n\n### 🧩 Nodes:\n\n1. ⏰ **Run Daily**\n2. 🛠 **Set Search Criteria**\n\n---\n\n### ✨ What's Happening Here:\n\n#### ⏰ **Run Daily**\n\n* This node is your **alarm clock** ⏰.\n* It automatically **starts the workflow** based on a schedule (e.g., daily at 8:00 AM).\n* You never need to click \"Execute Workflow\" manually again — it's 100% hands-free.\n\n> *“Imagine this as your personal assistant waking up every day to go find vacation deals for you.”*\n\n#### 🛠 **Set Search Criteria**\n\n* This is where you **set your filters**: destination, travel dates, number of guests.\n* For example:\n\n  ```json\n  {\n    \"location\": \"Los Angeles\",\n    \"checkin\": \"2025-09-15\",\n    \"checkout\": \"2025-09-20\",\n    \"adults\": 2\n  }\n  ```\n* This data will be **used in the scraping URL** sent to Airbnb through Bright Data.\n\n> *“It’s like telling your assistant: ‘Look for 2-person stays in LA from Sept 15–20.’”*\n\n---\n\n## 🌐 **Section 2: 🚀 Scrape & Extract Airbnb Data**\n\n### 🧩 Nodes:\n\n3. 🌐 **Scrape Airbnb via Bright Data**\n4. 🧠 **Extract Price & Title**\n\n---\n\n### ✨ What's Happening Here:\n\n#### 🌐 **Scrape Airbnb via Bright Data**\n\n* This node **sends a request** to Airbnb using **Bright Data Web Unlocker**.\n* Bright Data acts like a **stealth browser** 🕵️ that avoids blocks and loads the real webpage for you.\n* It fetches all the page data (even if Airbnb tries to hide it from bots).\n\n> *“Imagine Bright Data as your super-sneaky browser that can go where others can't.”*\n\n#### 🧠 **Extract Price & Title**\n\n* The raw response from Airbnb (HTML or JSON) is **parsed** in this Code node.\n* The code looks for:\n\n  * 🏷️ **Listing Title**\n  * 💰 **Price per night**\n* These are pulled out from the messy page code and transformed into clean data items.\n\n> *“It’s like using a fine-tooth comb to extract the useful info from a messy travel brochure.”*\n\n---\n\n## 📄 **Section 3: 🧾 Store the Results**\n\n### 🧩 Node:\n\n5. 📄 **Save to Google Sheets**\n\n---\n\n### ✨ What's Happening Here:\n\n#### 📄 **Save to Google Sheets**\n\n* All the extracted data (titles and prices) are **stored row-by-row** in a Google Sheet.\n* Each day adds a new set of listings, creating a full **price history** over time.\n* You can use this sheet to:\n\n  * Track **price changes**\n  * Find **off-peak bargains**\n  * Compare cities or time periods\n\n> *“This is your digital notebook where every deal is neatly logged for review, comparison, or alerts.”*\n\n---\n\n## 🎯 Why This Workflow is Powerful (Even for Beginners):\n\n| Benefit 💡                   | Description                                                               |\n| ---------------------------- | ------------------------------------------------------------------------- |\n| 📆 **Fully Automated**       | No manual work — set it once and let it run every day.                    |\n| 📊 **Easy Tracking**         | Automatically builds a database of deals over time.                       |\n| 💻 **Low-Code & Expandable** | You can easily add filters, alerts (e.g., Telegram, email), or analytics. |\n| 🧰 **Bright Data-Powered**   | Avoids bot detection and ensures clean, reliable data.                    |\n\n---\n\n"},"typeVersion":1},{"id":"d309ee77-594c-40ad-b943-2ea268b0b47f","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[1300,280],"parameters":{"color":7,"width":380,"height":240,"content":"## I’ll receive a tiny commission if you join Bright Data through this link—thanks for fueling more free content!\n\n### https://get.brightdata.com/1tndi4600b25"},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"4a456006-c946-40d6-8cd8-55db7f2518a6","connections":{"Run Daily (9 AM)":{"main":[[{"node":"Set Search Criteria","type":"main","index":0}]]},"Set Search Criteria":{"main":[[{"node":"Scrape Airbnb via Bright Data","type":"main","index":0}]]},"Extract Price & Title":{"main":[[{"node":"Save to Google Sheets","type":"main","index":0}]]},"Scrape Airbnb via Bright Data":{"main":[[{"node":"Extract Price & Title","type":"main","index":0}]]}}}


name: Automated Trend Tracking with Bright Data & n8n
author_name: Yaron Been
author_username: yaron-nofluff
nodes_used: ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest","n8n-nodes-base.html"]
categories: []
created_at: 2025-06-24T15:57:17.896Z
updated_at: 2025-06-24T15:57:17.896Z
url: https://n8n.io/workflows/5225
scraped_at: 2025-07-06 21:16:30
description:
  Description

  This workflow automatically monitors and tracks trending topics across multiple platforms and websites. It helps content creators and marketers stay ahead of the curve by identifying emerging trends before they go mainstream.

  Overview

  This workflow automatically monitors and tracks trending topics across multiple platforms and websites. It uses Bright Data to scrape trend data from social media, news sites, and other sources, then compiles the information into a structured format.

  Tools Used

  n8n:** The automation platform that orchestrates the workflow.
  Bright Data:** For scraping trend data from various websites without getting blocked.
  Spreadsheets/Databases:** For storing and analyzing trend information.

  How to Install

  Import the Workflow: Download the .json file and import it into your n8n instance.
  Configure Bright Data: Add your Bright Data credentials to the Bright Data node.
  Set Up Data Storage: Configure where you want to store the trend data.
  Customize: Specify which platforms to monitor and what topics to focus on.

  Use Cases

  Content Creators:** Stay on top of trending topics for content ideas.
  Marketers:** Identify emerging trends for timely campaigns.
  Researchers:** Track the evolution of topics and conversations over time.

  Connect with Me

  Website:** https://www.nofluff.online
  YouTube:** https://www.youtube.com/@YaronBeen/videos
  LinkedIn:** https://www.linkedin.com/in/yaronbeen/
  Get Bright Data:** https://get.brightdata.com/1tndi4600b25 (Using this link supports my free workflows with a small commission)

  #n8n #automation #trends #trendtracking #brightdata #contentmarketing #trendanalysis #trendalerts #markettrends #trendmonitoring #n8nworkflow #workflow #nocode #trendresearch #emergingtrends #socialmediatrends #trendscraping #trenddata #contentideas #digitalmarketing #marketresearch #trendforecasting #trendspotting #dataanalysis #marketintelligence #trendautomation

workflow_json:
  {"id":"m4kRfWIYJxn6PoOx","meta":{"instanceId":"60046904b104f0f72b2629a9d88fe9f676be4035769f1f08dad1dd38a76b9480","templateCredsSetupCompleted":true},"name":"Trend_Tracker_via_Bright_Data","tags":[],"nodes":[{"id":"6cebc2fd-3e61-41c8-9f23-25ca5bff2a54","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[-2400,620],"parameters":{"color":4,"width":1300,"height":320,"content":"=======================================\n            WORKFLOW ASSISTANCE\n=======================================\nFor any questions or support, please contact:\n    Yaron@nofluff.online\n\nExplore more tips and tutorials here:\n   - YouTube: https://www.youtube.com/@YaronBeen/videos\n   - LinkedIn: https://www.linkedin.com/in/yaronbeen/\n=======================================\n"},"typeVersion":1},{"id":"e4b7bd42-1b24-4f7c-90a0-b7909afcdca0","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-2400,960],"parameters":{"color":4,"width":1289,"height":2258,"content":"## 🚀 **Monthly Viral Trend Tracker Workflow**\n\nThis automation helps you track viral posts on **Quora** around specific topics (like *marketing* or *design*) every month. It scrapes trending content, extracts useful data (titles, URLs, stats), and saves it into a Google Sheet for later use — perfect for trend research, reporting, or content inspiration.\n\n---\n\n### 🧠 **SECTION 1: Trend Trigger & Scraper**\n\n> **Purpose:** Automate the scraping of viral content from Quora every month.\n\n#### ⏰ `Node 1: Monthly Trend Trigger`\n\n**🔗 Type:** Cron Scheduler\n**🧩 What it does:**\nThis node is like your personal assistant — it **automatically starts the workflow on the 1st day of every month** without you lifting a finger.\n\n* 🗓 Trigger schedule: Monthly (e.g., `0 0 1 * *`)\n* 📈 Use Case: Keeps your trend tracking consistent and timely\n\n> 🧠 *Why it matters:* Instead of manually checking viral trends, this node ensures it’s **fully automated**, perfect for monthly reports or trend tracking dashboards.\n\n---\n\n#### 🌐 `Node 2: Scrape Quora Trends (Bright Data)`\n\n**🔗 Type:** HTTP Request\n**🧩 What it does:**\nThis node sends a **POST request to Bright Data** to scrape trending Quora results for a given topic (like `\"https://www.quora.com/search?q=marketing\"`).\n\n* 🔒 Uses **Bright Data Web Unlocker** to bypass restrictions\n* 🧠 Intelligent scraping with full HTML + rendering\n* 🔍 Targets specific search terms (e.g., `marketing`, `UX`, `AI in marketing`)\n\n> 💡 *Why it matters:* You can collect **real trending content** from Quora without opening your browser. Bright Data handles the hard stuff like JavaScript, proxies, and blocks.\n\n---\n\n### 🧾 **SECTION 2: Extract & Save Insights**\n\n> **Purpose:** Process the scraped data and store it in a usable format (Google Sheets).\n\n#### 🧱 `Node 3: Extract Post Titles & Stats`\n\n**🔗 Type:** HTML Extract\n**🧩 What it does:**\nTakes the raw HTML from Quora and pulls out the meaningful information you care about:\n\n* 📝 Question titles or post headlines\n* 🔗 URLs\n* 👍 Vote count or engagement\n* 🧑 Author or answer snippet (if desired)\n\nYou use **CSS Selectors or XPath** to tell n8n what to extract. For example:\n\n```css\na.q-box.qu-mb--tiny  →  Post links  \ndiv.q-relative  →  Snippets or text  \n```\n\n> 🧠 *Why it matters:* This is where raw data becomes structured. You’re now transforming messy HTML into useful, clean trend info.\n\n---\n\n#### 📊 `Node 4: Save Trends to Sheet`\n\n**🔗 Type:** Google Sheets\n**🧩 What it does:**\nTakes the structured trend data and **appends it to a Google Sheet** for archiving, analysis, or sharing.\n\n* 🔄 Keeps data centralized in Google Drive\n* 🧾 Every entry becomes part of a monthly trend log\n* 📤 Can be exported, visualized, or emailed later\n\n> 💡 *Why it matters:* This gives you a **living database of viral content** that you can reference later for reports, content ideas, social strategy, or client insights.\n\n---\n\n### 📦 **Workflow Summary**\n\n| Section                              | What's Happening                                                                  | Icons    |\n| ------------------------------------ | --------------------------------------------------------------------------------- | -------- |\n| **🧠 Section 1**<br>Trigger & Scrape | Automatically triggers each month → sends request to scrape Quora via Bright Data | ⏰ 🌐 🔍  |\n| **🧾 Section 2**<br>Extract & Store  | Parses HTML → extracts question titles, votes, links → saves to Google Sheets     | 🧾 🧪 📊 |\n\n---\n\n### 💼 How a Beginner Can Use This\n\n1. **No Code Needed:** All steps use visual nodes in n8n.\n2. **Customizable Topics:** Change `\"url\"` in the HTTP node to track any niche.\n3. **Scalable:** Duplicate the scraping node to include Reddit, Twitter, or LinkedIn later.\n4. **Google Sheets Ready:** Easy to share or use in reporting tools like Looker Studio or Excel.\n\n---\n"},"typeVersion":1},{"id":"d1595d84-94ee-4678-9ed5-ee83dc421d50","name":"Monthly Trend Trigger1","type":"n8n-nodes-base.scheduleTrigger","position":[-420,1580],"parameters":{"rule":{"interval":[{"field":"months","triggerAtHour":9}]}},"typeVersion":1.2},{"id":"5796454a-2479-450d-8e1c-b9e9344e0da0","name":"Scrape Quora Trends (Bright Data)","type":"n8n-nodes-base.httpRequest","position":[-200,1580],"parameters":{"url":"https://api.brightdata.com/request","method":"POST","options":{},"sendBody":true,"sendHeaders":true,"bodyParameters":{"parameters":[{"name":"zone","value":"n8n_unblocker"},{"name":"url","value":"https://www.quora.com/search?q=marketing"},{"name":"country","value":"us"},{"name":"format","value":"raw"},{"name":"render","value":"true"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2},{"id":"4c93f548-a848-4aa9-bdf7-d8b282d49dbb","name":"Extract Post Titles & Stats","type":"n8n-nodes-base.html","position":[80,1580],"parameters":{"options":{},"operation":"extractHtmlContent","extractionValues":{"values":[{"key":"Title","cssSelector":"<span style=\"background: none;\">What exactly is digital marketing</span>"},{"key":"Answers","cssSelector":"<a class=\"q-box qu-cursor--pointer qu-hover--textDecoration--underline b2c1r2a puppeteer_test_link\" href=\"https://www.quora.com/What-exactly-is-digital-marketing\" target=\"_blank\" style=\"box-sizing: border-box; border-radius: inherit;\">3.2K answers</a>"}]}},"typeVersion":1.2},{"id":"40bf951b-4c60-4660-a6dc-c3cd99298e94","name":"Save Trends to Sheet","type":"n8n-nodes-base.googleSheets","position":[300,1580],"parameters":{"columns":{"value":{"Title":"={{ $json.Title }}","Answer":"={{ $json.Answers }}"},"schema":[{"id":"Title","type":"string","display":true,"required":false,"displayName":"Title","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Answer","type":"string","display":true,"required":false,"displayName":"Answer","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"append","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/19j13GLmFHZUnIKH5KGgdj0ohVMx4MhOnDf5ovI0yz6Y/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"19j13GLmFHZUnIKH5KGgdj0ohVMx4MhOnDf5ovI0yz6Y","cachedResultUrl":"https://docs.google.com/spreadsheets/d/19j13GLmFHZUnIKH5KGgdj0ohVMx4MhOnDf5ovI0yz6Y/edit?usp=drivesdk","cachedResultName":"Trend tracker"}},"credentials":{"googleSheetsOAuth2Api":{"id":"r2mDaisH6e9VkwHl","name":"Google Sheets account"}},"typeVersion":4.6},{"id":"b8bff546-392a-4f88-ac67-7d3336978cc0","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-460,600],"parameters":{"color":3,"width":400,"height":1180,"content":"### 🧠 **SECTION 1: Trend Trigger & Scraper**\n\n> **Purpose:** Automate the scraping of viral content from Quora every month.\n\n#### ⏰ `Node 1: Monthly Trend Trigger`\n\n**🔗 Type:** Cron Scheduler\n**🧩 What it does:**\nThis node is like your personal assistant — it **automatically starts the workflow on the 1st day of every month** without you lifting a finger.\n\n* 🗓 Trigger schedule: Monthly (e.g., `0 0 1 * *`)\n* 📈 Use Case: Keeps your trend tracking consistent and timely\n\n> 🧠 *Why it matters:* Instead of manually checking viral trends, this node ensures it’s **fully automated**, perfect for monthly reports or trend tracking dashboards.\n\n---\n\n#### 🌐 `Node 2: Scrape Quora Trends (Bright Data)`\n\n**🔗 Type:** HTTP Request\n**🧩 What it does:**\nThis node sends a **POST request to Bright Data** to scrape trending Quora results for a given topic (like `\"https://www.quora.com/search?q=marketing\"`).\n\n* 🔒 Uses **Bright Data Web Unlocker** to bypass restrictions\n* 🧠 Intelligent scraping with full HTML + rendering\n* 🔍 Targets specific search terms (e.g., `marketing`, `UX`, `AI in marketing`)\n\n> 💡 *Why it matters:* You can collect **real trending content** from Quora without opening your browser. Bright Data handles the hard stuff like JavaScript, proxies, and blocks.\n\n---\n\n"},"typeVersion":1},{"id":"c4c10db4-b6e1-413d-9183-cd9b8fb6c0fa","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[20,720],"parameters":{"color":5,"width":400,"height":1060,"content":"### 🧾 **SECTION 2: Extract & Save Insights**\n\n> **Purpose:** Process the scraped data and store it in a usable format (Google Sheets).\n\n#### 🧱 `Node 3: Extract Post Titles & Stats`\n\n**🔗 Type:** HTML Extract\n**🧩 What it does:**\nTakes the raw HTML from Quora and pulls out the meaningful information you care about:\n\n* 📝 Question titles or post headlines\n* 🔗 URLs\n* 👍 Vote count or engagement\n* 🧑 Author or answer snippet (if desired)\n\nYou use **CSS Selectors or XPath** to tell n8n what to extract. For example:\n\n```css\na.q-box.qu-mb--tiny  →  Post links  \ndiv.q-relative  →  Snippets or text  \n```\n\n> 🧠 *Why it matters:* This is where raw data becomes structured. You’re now transforming messy HTML into useful, clean trend info.\n\n---\n\n#### 📊 `Node 4: Save Trends to Sheet`\n\n**🔗 Type:** Google Sheets\n**🧩 What it does:**\nTakes the structured trend data and **appends it to a Google Sheet** for archiving, analysis, or sharing.\n\n"},"typeVersion":1},{"id":"772bfade-22ab-46d5-aadf-9ec46d99b7f6","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[480,720],"parameters":{"color":7,"width":380,"height":240,"content":"## I’ll receive a tiny commission if you join Bright Data through this link—thanks for fueling more free content!\n\n### https://get.brightdata.com/1tndi4600b25"},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"f4efa76f-fdce-4081-aa53-54b8c36cbcfc","connections":{"Monthly Trend Trigger1":{"main":[[{"node":"Scrape Quora Trends (Bright Data)","type":"main","index":0}]]},"Extract Post Titles & Stats":{"main":[[{"node":"Save Trends to Sheet","type":"main","index":0}]]},"Scrape Quora Trends (Bright Data)":{"main":[[{"node":"Extract Post Titles & Stats","type":"main","index":0}]]}}}


