# templates

name: Smart Email Responder Workflow using AI
author_name: Ankur Parag Kulkarni
author_username: ankur
categories: []
created_at: 2025-06-09T00:42:07.675Z
updated_at: 2025-06-09T00:42:07.675Z
url: https://n8n.io/workflows/4807
scraped_at: 2025-07-06 21:16:30
description:
  This project presents an intelligent email management system powered by advanced artificial intelligence. It utilizes Google's Gemini 2.0 AI model to automatically categorize incoming emails into queries, project updates, and feedback, and generates context-specific responses in real time.

  Approach:
  The system processes emails promptly, ensuring consistent and timely communication. In addition to crafting automated replies, it streamlines workflow efficiency by sending calendar invitations for meetings without manual intervention.

  Results:
  The Smart Email Auto-Responder enhances email management by marking emails as read, applying appropriate labels, and systematically logging correspondence. This significantly reduces manual workload while improving client engagement and operational productivity.

nodes_used:
  ["n8n-nodes-base.emailSend","n8n-nodes-base.googleCalendar","n8n-nodes-base.gmail","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.lmChatGoogleGemini","@n8n/n8n-nodes-langchain.textClassifier"]

workflow_json:
  {"id":"1RHsJldA8GlWFp1E","meta":{"instanceId":"c3caf872897344ae9095ede706e2c19a32f712f120ab7f143e26125462303491","templateId":"3277","templateCredsSetupCompleted":true},"name":"Smart Email Auto-Responder","tags":[],"nodes":[{"id":"e485ab21-6c33-4cb1-9bd1-3fea3a1d431a","name":"Gmail Trigger","type":"n8n-nodes-base.gmailTrigger","position":[1480,220],"parameters":{"simple":false,"filters":{"labelIds":["Label_43975351283257832"]},"options":{},"pollTimes":{"item":[{"mode":"everyHour"}]}},"credentials":{"gmailOAuth2":{"id":"cvHi0AAN9bE3lcij","name":"Gmail account"}},"typeVersion":1.2},{"id":"d52b02ce-95aa-495f-a6b4-d5dd791f2808","name":"Text Classifier","type":"@n8n/n8n-nodes-langchain.textClassifier","position":[1820,400],"parameters":{"options":{},"inputText":"={{ $('Gmail Trigger').item.json.subject }}\n{{ $('Gmail Trigger').item.json.text }}","categories":{"categories":[{"category":"Questions","description":"Use this category when the email is asking for information about our company, products, processes, pricing, timelines, legal terms or any other general inquiry that expects a factual explanation or guidance."},{"category":"Project Update","description":"Choose this category when the sender is notifying us about progress or changes: signing the agreement, submitting or revising scripts, updating requirements, sharing evaluation results, or any status report that moves an ongoing project forward"},{"category":"Feedback","description":"Select this category when the email contains compliments, complaints, suggestions, or any qualitative feedback about our service, product, communication or overall experience"}]}},"typeVersion":1},{"id":"adfca78f-9ce5-4345-baaa-017538e433be","name":"Google Gemini Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[1840,680],"parameters":{"options":{},"modelName":"models/gemini-2.0-flash-exp"},"credentials":{"googlePalmApi":{"id":"vNACKKKe3OF1uS3Y","name":"Google Gemini(PaLM) Api account"}},"typeVersion":1},{"id":"e7c91741-20d6-4c54-8dd5-efec164c29b3","name":"Youtube Video Inquiry","type":"n8n-nodes-base.emailSend","position":[2260,580],"webhookId":"120f4cfb-cfd3-4792-b5f5-146e9f495f73","parameters":{"html":"=<!DOCTYPE html>\n<html>\n<head>\n  <style>\n    body{font-family:Arial,sans-serif;line-height:1.6;color:#333;margin:0;padding:0;}\n    .container{width:100%;max-width:600px;margin:0 auto;padding:20px;}\n    .header{background:#f4f4f4;padding:10px 20px;text-align:center;border-bottom:1px solid #ddd;}\n    .header h1{margin:0;color:#555;}\n    .content{padding:20px;}\n    .content h2{color:#555;font-size:18px;margin:20px 0 10px;}\n    .content p{margin-bottom:15px;}\n    .content ul{list-style:disc;padding-left:20px;}\n    .content ul li{margin-bottom:10px;}\n    .content a{color:#007BFF;text-decoration:none;}\n    .content a:hover{text-decoration:underline;}\n    .footer{text-align:center;font-size:12px;color:#888;margin-top:20px;}\n  </style>\n</head>\n<body>\n  <div class=\"container\">\n    <div class=\"header\">\n      <h1>Project Update Acknowledgement</h1>\n    </div>\n\n    <div class=\"content\">\n      <p>\n        Hi {{ $json.from.value[0].name || $('Gmail Trigger').item.json.headers.from.split('<')[0].trim() || 'there' }},\n      </p>\n\n      <p>\n        Thank you for your recent update on the project. We’ve reviewed the information you provided and have logged it in our system.\n      </p>\n\n      <h2>What we received:</h2>\n      <ul>\n        <li>Signed agreement / contract confirmation.</li>\n        <li>Revised requirements or scope changes.</li>\n        <li>Draft scripts or other deliverables for review.</li>\n        <li>Evaluation results or performance reports.</li>\n      </ul>\n\n      <h2>Next steps:</h2>\n      <ul>\n        <li>Our team will review the materials and integrate any changes within <strong>2–3 business days</strong>.</li>\n        <li>If clarifications are needed, we’ll reach out via email or schedule a quick call.</li>\n        <li>You’ll receive the updated project timeline once the review is complete.</li>\n      </ul>\n\n      <p>\n        If you have additional files or questions, feel free to reply directly to this email.\n      </p>\n\n      <p>\n        We appreciate your prompt communication and look forward to moving the project ahead smoothly.\n      </p>\n\n      <p>\n        Best regards,<br>\n        <strong>Sophia Mitchell</strong><br>\n        Project Coordinator | <a href=\"https://syncbricks.com\" target=\"_blank\">syncbricks.com</a><br>\n        WhatsApp: +1 &nbsp;\n      </p>\n    </div>\n\n    <div class=\"footer\">\n      © 2025 SyncBricks. All rights reserved.\n    </div>\n  </div>\n</body>\n</html>\n","options":{"appendAttribution":false},"subject":"=Re: {{ $('Gmail Trigger').item.json.subject }}","toEmail":"={{ $json.from.value[0].name }} <{{ $json.from.value[0].address }}>","fromEmail":"kulankur.work@gmail.com"},"credentials":{"smtp":{"id":"rSVeHz6kjwDIBOZ7","name":"SMTP account"}},"typeVersion":2.1},{"id":"61243957-40d1-4fb2-ad0a-6f923587c4db","name":"Send Email","type":"n8n-nodes-base.emailSend","position":[2260,760],"webhookId":"700cb9ed-bd54-4e96-8121-98a5dcffeebf","parameters":{"html":"=<!DOCTYPE html>\n<html>\n<head>\n  <style>\n    body{font-family:Arial,sans-serif;line-height:1.6;color:#333;margin:0;padding:0;}\n    .container{width:100%;max-width:600px;margin:0 auto;padding:20px;}\n    .header{background:#f4f4f4;padding:10px 20px;text-align:center;border-bottom:1px solid #ddd;}\n    .header h1{margin:0;color:#555;}\n    .content{padding:20px;}\n    .content h2{color:#555;font-size:18px;margin:20px 0 10px;}\n    .content p{margin-bottom:15px;}\n    .content ul{list-style:disc;padding-left:20px;}\n    .content ul li{margin-bottom:10px;}\n    .content a{color:#007BFF;text-decoration:none;}\n    .content a:hover{text-decoration:underline;}\n    .footer{text-align:center;font-size:12px;color:#888;margin-top:20px;}\n  </style>\n</head>\n<body>\n  <div class=\"container\">\n    <div class=\"header\">\n      <h1>Thank You for Your Feedback</h1>\n    </div>\n\n    <div class=\"content\">\n      <p>\n        Hi {{ $json.from.value?.[0]?.name || $('Gmail Trigger').item.json.headers.from.split('<')[0].trim() || 'there' }},\n      </p>\n\n      <p>\n        Thank you for taking the time to share your feedback about SyncBricks. We truly value every comment—whether a\n        compliment, suggestion, or concern—because it helps us improve.\n      </p>\n\n      <h2>What happens next:</h2>\n      <ul>\n        <li>Your message has been logged in our system&nbsp;(<strong>Reference ID:</strong>\n          {{ $json.id.slice(-6) }}).</li>\n        <li>Our team will review it within <strong>1 business day</strong>.</li>\n        <li>If an action is required, the appropriate team member will follow up directly with you.</li>\n      </ul>\n\n      <p>\n        If you need to add more details, simply reply to this email—your message wil\n","options":{"appendAttribution":false},"subject":"=Re:  {{ $('Gmail Trigger').item.json.Subject }}","toEmail":"={{ $json.from.value[0].name }} <{{ $json.from.value[0].address }}>","fromEmail":"kulankur.work@gmail.com"},"credentials":{"smtp":{"id":"rSVeHz6kjwDIBOZ7","name":"SMTP account"}},"typeVersion":2.1},{"id":"a2542d02-4018-45e5-a8f2-875e669c77a3","name":"Mark as Read","type":"n8n-nodes-base.gmail","position":[2780,460],"webhookId":"a5bea8d3-719e-4b2b-a43d-4c6248796267","parameters":{"messageId":"={{ $('Gmail Trigger').all()[0].json.id }}\n","operation":"markAsRead"},"credentials":{"gmailOAuth2":{"id":"cvHi0AAN9bE3lcij","name":"Gmail account"}},"typeVersion":2.1},{"id":"0a1d79a3-91cf-4bf6-93bb-1482549a74dd","name":"Apply Label","type":"n8n-nodes-base.gmail","position":[2960,460],"webhookId":"c3a2fc4e-d90c-463a-a356-db530e1b91b0","parameters":{"labelIds":["CATEGORY_UPDATES"],"messageId":"={{ $('Gmail Trigger').all()[0].json.id }}\n","operation":"addLabels"},"credentials":{"gmailOAuth2":{"id":"cvHi0AAN9bE3lcij","name":"Gmail account"}},"typeVersion":2.1},{"id":"28467e9f-a730-4545-89cb-7d2c629edd71","name":"Emails from Existing Contracts","type":"n8n-nodes-base.if","position":[1640,220],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"or","conditions":[{"id":"7cffe101-333d-4ec2-a822-181fe421745b","operator":{"type":"string","operation":"contains"},"leftValue":"={{ $json.headers.from }}","rightValue":"@syncbricks.com"}]}},"typeVersion":2.2},{"id":"b150ab4d-dcbb-4ae6-9503-5914e39f41ac","name":"Reply","type":"n8n-nodes-base.if","position":[1640,460],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"07a6d5e2-ffc5-41d8-b69a-abd6860879c0","operator":{"type":"string","operation":"notStartsWith"},"leftValue":"={{ $json.subject }}","rightValue":"Re:"}]}},"typeVersion":2.2},{"id":"1f043246-cbd0-466d-bbfd-b13131a66f03","name":"QuestionsReply","type":"n8n-nodes-base.emailSend","position":[2720,160],"webhookId":"ed01c3d4-1fad-4098-b431-4bc3d5e05434","parameters":{"html":"=<p>\n  Hi {{ $json.senderName }} <{{ $json.senderEmail }}>,\n</p>\n\n<p>Thanks for reaching out with your questions. I’d love to cover everything face-to-face.</p>\n\n<p><strong>Location:</strong><br>\n123 Main St<br>\nLos Angeles, CA 90089\n</p>\n\n<p>We just sent you three calendar invitations for these time slots:</p>\n\n<ul>\n  {{ $json.slotTimes.map(t => `<li>${t}</li>`).join('') }}\n</ul>\n\n<p>\n  Click <em>Yes</em> on the invite that works best for you.  \n  Google will reserve that slot automatically; the other two will stay open.\n</p>\n\n<p>\n  If none of the times work, reply with a couple of alternatives and I’ll find something that fits.\n</p>\n\n<p>Looking forward to meeting you!<br>— Corvin</p>\n","options":{"appendAttribution":false},"subject":"=Re: {{ $json.originalSub }}","toEmail":"={{ $json.senderName }} <{{ $json.senderEmail }}>","fromEmail":"kulankur.work@gmail.com"},"credentials":{"smtp":{"id":"rSVeHz6kjwDIBOZ7","name":"SMTP account"}},"typeVersion":2.1},{"id":"60d50fdc-4e7f-4ab1-a240-1be4c8ae7520","name":"Google Calendar","type":"n8n-nodes-base.googleCalendar","position":[2100,160],"parameters":{"limit":3,"options":{"query":"Available – Office Visit","orderBy":"startTime","recurringEventHandling":"expand"},"timeMax":"=","calendar":{"__rl":true,"mode":"list","value":"37f51d1c36997a7dacbba1d1470fe5f0213699c4d926e7a3104c35f1cb79cb75@group.calendar.google.com","cachedResultName":"Meeting slots"},"operation":"getAll"},"credentials":{"googleCalendarOAuth2Api":{"id":"De5XvcvX90kFuzvb","name":"Google Calendar account"}},"typeVersion":1.3},{"id":"48a8b613-54e3-4002-8830-1726a23d24aa","name":"Loop Over Items","type":"n8n-nodes-base.splitInBatches","position":[2280,160],"parameters":{"options":{}},"typeVersion":3},{"id":"de676780-43c8-476d-ab8a-a692ffe4e65f","name":"Google Calendar1","type":"n8n-nodes-base.googleCalendar","position":[2520,300],"parameters":{"eventId":"={{$json.id}}","calendar":{"__rl":true,"mode":"list","value":"37f51d1c36997a7dacbba1d1470fe5f0213699c4d926e7a3104c35f1cb79cb75@group.calendar.google.com","cachedResultName":"Meeting slots"},"operation":"update","updateFields":{"attendeesUi":{"values":{"attendees":["={{ $(\"Gmail Trigger\").item.json.from.value[0].address }}\n"]}},"sendUpdates":"all"}},"credentials":{"googleCalendarOAuth2Api":{"id":"De5XvcvX90kFuzvb","name":"Google Calendar account"}},"typeVersion":1.3},{"id":"df5552fc-910b-4b13-81fa-0c9d98ce82d7","name":"Code","type":"n8n-nodes-base.code","position":[2520,140],"parameters":{"jsCode":"const triggerJson = $('Gmail Trigger').item.json;\nconst headersFrom  = triggerJson.headers.from;      // \"Name <addr@example.com>\"\n\n// Split into name and address\nconst namePart = headersFrom.split('<')[0].replace(/^From:\\s*/i, '').trim();\nconst emailPart = headersFrom.match(/<([^>]+)>/)?.[1] || headersFrom;\n\nconst slotTimes = items.map(i =>\n  new Date(i.json.start.dateTime || i.json.start.date).toLocaleString(\n    'en-US',\n    { weekday:'short', month:'short', day:'numeric', hour:'numeric',\n      minute:'2-digit', hour12:true }\n  )\n);\n\nreturn [{\n  json: {\n    slotTimes,\n    senderName:  namePart,\n    senderEmail: emailPart,\n    originalSub: triggerJson.subject               // pass the subject along\n  }\n}];\n"},"typeVersion":2}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"2b74a94c-8a92-4a15-b0a4-5590afba0f39","connections":{"Code":{"main":[[{"node":"QuestionsReply","type":"main","index":0}]]},"Reply":{"main":[[{"node":"Text Classifier","type":"main","index":0}]]},"Send Email":{"main":[[{"node":"Mark as Read","type":"main","index":0}]]},"Mark as Read":{"main":[[{"node":"Apply Label","type":"main","index":0}]]},"Gmail Trigger":{"main":[[{"node":"Emails from Existing Contracts","type":"main","index":0}]]},"QuestionsReply":{"main":[[{"node":"Mark as Read","type":"main","index":0}]]},"Google Calendar":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Loop Over Items":{"main":[[{"node":"Code","type":"main","index":0}],[{"node":"Google Calendar1","type":"main","index":0}]]},"Text Classifier":{"main":[[{"node":"Google Calendar","type":"main","index":0}],[{"node":"Youtube Video Inquiry","type":"main","index":0}],[{"node":"Send Email","type":"main","index":0}]]},"Google Calendar1":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Youtube Video Inquiry":{"main":[[{"node":"Mark as Read","type":"main","index":0}]]},"Google Gemini Chat Model":{"ai_languageModel":[[{"node":"Text Classifier","type":"ai_languageModel","index":0}]]},"Emails from Existing Contracts":{"main":[[],[{"node":"Reply","type":"main","index":0}]]}}}


name: Save Time with AI Hiring – Automate Screening, Assessments, Alerts & Interviews
author_name: Aayushman Sharma
author_username: ajstyle0411
categories: []
created_at: 2025-06-09T11:01:53.274Z
updated_at: 2025-06-09T11:01:53.274Z
url: https://n8n.io/workflows/4813
scraped_at: 2025-07-06 21:16:30
description:
  AI Recruitment Automation Pipeline – Resume Parsing, GPT-4 Evaluation, Assessment Triggers & Interview Scheduling

  This end-to-end AI-powered HR recruitment workflow automates the entire candidate journey — from resume collection and parsing to AI-based evaluation, Talent Acquisition (TA) approvals, assessment dispatch, and interview scheduling. Built in n8n, it leverages OpenAI GPT-4, Google Sheets, Google Drive, Slack, and SMTP to reduce hiring time, improve candidate quality, and eliminate repetitive manual tasks.

  Key Features

  Smart Resume Intake Form
  Collects candidate data: name, email, phone, LinkedIn, job role, and CV (PDF).
  Custom-designed UI with branding-ready CSS.

  PDF Resume Parsing & Storage
  CV is uploaded to a dedicated Google Drive folder.
  Resume text is extracted for semantic analysis.

  AI-Based Candidate Evaluation (GPT-4 via LangChain)
  Extracts: City, Education, Job History, Skills.
  Summarizes candidate profile (100 words).
  Retrieves and summarizes job description from Google Sheets.
  Performs detailed evaluation:
    ✅ Semantic fit scoring (0–100%)
    ✅ Key matches and skill gaps
    ✅ Soft skills extraction
    ✅ Red flag detection (job-hopping, missing info)
    ✅ Final score (1–10) with rationale

  Google Sheets Integration
  Logs and updates candidate data at each stage:
    CV Submitted → Scored → Shortlisted → Assessment Sent → Interview Scheduled → Rejected

  TA Approval via Email (Send & Wait)
  TA receives evaluation summary and gives one-click approve/reject.
  ✅ Approved → Status: Resume Selected  
  ❌ Rejected → Status: Resume Rejected

  Assessment Trigger (Post Approval)
  Sends assessment link to shortlisted candidates.
  Notifies TA via Slack and Email when assessment is submitted.

  Interview Scheduling
  Sends Calendly link for self-scheduled interview booking.
  Candidate receives detailed next-step instructions.

  Status-Based Candidate Emails
  Automatically sends:
    ✔️ Shortlisting confirmation + interview setup
    ❌ Rejection email with branded message

  Business Benefits

  Save 80%+ time** spent on manual resume reviews and coordination
  Reduce cost-per-hire** by eliminating manual tasks
  Enhance hiring accuracy** with structured, AI-based decision-making
  Scalable recruitment** for 100s of candidates per week
  Improve candidate experience** with instant status updates
  Centralize data** in Google Sheets for full team visibility

  🔧 Setup Instructions

  1. Google Service Account Setup (One-Time)

  Before using Google Sheets or Google Drive in n8n:

  Go to Google Cloud Console.
  Create a Service Account under your project.
  Enable these APIs:
    Google Sheets API
    Google Drive API
  Download the JSON credentials for the service account.
  IMPORTANT:  
    Share your target Google Sheets and Docs with the service account email  
    (e.g., your-service-account@your-project.iam.gserviceaccount.com).

  Add Applicant's Details to Google Sheet

  Document**: Select the Profiles Google Sheet document.
  Sheet**: Select the Applicant's Details sheet.
  Fields to Map**:
    EMAIL: {{ $('On form submission').item.json.Email }}
    DATE: {{ $now.format('dd-MM-yyyy') }}
    NAME: {{ $('On form submission').item.json.Name }}
    LINKEDIN URL: {{ $('On form submission').item.json["LinkedIn Profile URL"] }}
    JOB PROFILE: {{ $('On form submission').item.json["Job Openings"] }}
    STATUS: CV SUBMITTED
    LAST UPDATED DATE: {{ $now.format('dd-MM-yyyy hh:mm:ss') }}

  Extract Applicant's Resume Text

  Text**:  
    {{ $('Extract from File').item.json.text }}

  Get Job Description from Google Sheet

  Document**: Profiles
  Sheet**: Job Openings
  Filter**:
  Column**: Job Profile
  Value**: {{ $('On form submission').item.json["Job Openings"] }}

  Save Evaluation Results in Google Sheets

  Document**: Profiles
  Sheet**: Applicant's Details
  Column Match On**: EMAIL
  Fields to Map**:
  EMAIL: {{ $('On form submission').item.json.Email }}
  CITY: {{ $('Applicant\'s Details').item.json.output.City }}
  EDUCATIONAL: {{ $('Applicant\'s Details').item.json.output["Educational Qualification"] }}
  JOB HISTORY: {{ $('Applicant\'s Details').item.json.output["Job History"] }}
  SKILLS: {{ $('Applicant\'s Details').item.json.output.Skills }}
  SUMMARIZE: {{ $('Summarize Applicant\'s Profile').item.json.response.text }}
  SEMANTIC FIT SCORE: {{ $json.output.semantic_fit.score }}
  KEY MATCHES: {{ $json.output.semantic_fit.key_matches.toJsonString() }}
  KEY GAPS: {{ $json.output.semantic_fit.key_gaps.toJsonString() }}
  SEMANTIC FIT CONSIDERATION: {{ $json.output.semantic_fit.consideration }}
  SOFT SKILLS: {{ $json.output.soft_skills.toJsonString() }}
  EXPERIENCE GAP DETECTED: {{ $json.output.experience_analysis.experience_gap_detected }}
  OVER QUALIFICATION DETECTED: {{ $json.output.experience_analysis.overqualification_detected }}
  EXPERIENCE ANALYSIS CONSIDERATION: {{ $json.output.experience_analysis.consideration }}
  RED FLAGS ISSUES DETECTED: {{ $json.output.red_flags.issues_detected.toJsonString() }}
  RED FLAGS CONSIDERATION: {{ $json.output.red_flags.consideration }}
  VOTE: {{ $json.output.overall_evaluation.final_vote }}
  FINAL CONSIDERATION: {{ $json.output.overall_evaluation.consideration }}
  STATUS: CV SCORED
  LAST UPDATED DATE: {{ $now.format('dd-MM-yyyy hh:mm:ss') }}

  Update Applicant Statuses

  Resume Selected

  Document**: Profiles
  Sheet**: Applicant's Details
  Column Match On**: EMAIL
  Update**:
  STATUS: RESUME SELECTED
  LAST UPDATED DATE: {{ $now.format('dd-MM-yyyy hh:mm:ss') }}

  Resume Rejected

  Update**:
  STATUS: RESUME REJECTED
  LAST UPDATED DATE: {{ $now.format('dd-MM-yyyy hh:mm:ss') }}

  Assessment Sent

  Email**: {{ $('Loop to Send Assessment Link to Each Candidate').item.json.EMAIL }}
  Update**:
  STATUS: ASSESSMENT SENT
  LAST UPDATED DATE: {{ $now.format('dd-MM-yyyy hh:mm:ss') }}

  Assessment Submitted

  Email**: {{ $json["Enter Your Email Address"] }}
  Update**:
  STATUS: ASSESSMENT SUBMITTED
  LAST UPDATED DATE: {{ $now.format('dd-MM-yyyy hh:mm:ss') }}

  Interview Booked

  Email**: {{ $json.payload.email }}
  Update**:
  STATUS: INTERVIEW BOOKED
  LAST UPDATED DATE: {{ $now.format('dd-MM-yyyy hh:mm:ss') }}

  Fetch Applicants with Specific Status

  Status: RESUME SELECTED

  Document**: Profiles
  Sheet**: Applicant's Details
  Filter**:
  Column**: STATUS
  Value**: RESUME SELECTED

  Get Assessment Form URL from Job Profile

  Document**: Profiles
  Sheet**: Job Openings
  Filter**:
  Column**: Job Profile
  Value**: {{ $json["JOB PROFILE"] }}

  Trigger on Applicant Status Update

  Document**: Profiles
  Sheet**: Applicant's Details
  Trigger Settings**:
  Columns to Watch**: STATUS

  ⚠️ Important Notes

  Always use “Select Document from List” instead of manually pasting the sheet/document ID.
  Share your Sheets/Docs with the Google Service Account email for proper access.
  Keep your date formats consistent using {{ $now.format('dd-MM-yyyy hh:mm:ss') }}.

  Add credentials for:
     Google Drive
     Google Sheets
     SMTP (for emails)
     OpenAI API Key (GPT-4)
  Replace placeholders:
     Google Sheet & Folder IDs
     Calendly Link
     Assessment Link
  (Optional) Customize GPT-4 prompts for domain-specific scoring
  (Optional) Use your Slack webhook for TA notifications

  🛠️ Tools & Integrations

  Form Trigger** – Candidate form with file upload  
  Google Drive + Extract PDF** – CV parsing  
  Google Sheets** – Database for all applicant statuses  
  LangChain GPT-4 Nodes** – AI profile + job analysis  
  Email Send & Send & Wait** – Candidate/TA communication  
  IF Node** – Logic for approve/reject  
  Slack Integration** – TA notification  
  Calendly Link** – Interview scheduling

  AI resume screening, GPT-4 recruitment workflow, automated hiring pipeline, semantic fit evaluation, LangChain for HR, resume parsing automation, AI in talent acquisition, assessment workflow automation, interview scheduling automation, candidate shortlisting automation, OpenAI HR integration, Google Sheets recruitment tracker, n8n HR automation template, self-scheduling interviews with Calendly, Slack notifications in recruitment

nodes_used:
  ["n8n-nodes-base.emailSend","n8n-nodes-base.googleSheets","n8n-nodes-base.slack","n8n-nodes-base.googleDrive","@n8n/n8n-nodes-langchain.chainSummarization","@n8n/n8n-nodes-langchain.chainLlm","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.outputParserStructured","@n8n/n8n-nodes-langchain.informationExtractor"]

workflow_json:
  {"meta":{"instanceId":"b0c38aaab6bebe08413b40e26aa2ee99136cd8edfd3a296014b1e2af1b2d5383"},"nodes":[{"id":"8a152592-2259-4884-92dc-6e23158bf58f","name":"On form submission","type":"n8n-nodes-base.formTrigger","position":[280,420],"webhookId":"2a87705d-8ba1-41f1-80ef-85f364ce253e","parameters":{},"typeVersion":2.2},{"id":"eda2a030-df56-4989-9986-2d6837b71c78","name":"Extract from File","type":"n8n-nodes-base.extractFromFile","position":[680,420],"parameters":{},"typeVersion":1},{"id":"6a848708-0a9b-4bbf-bcf7-4f7195e6196d","name":"Structured Output Parser","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[2960,560],"parameters":{},"typeVersion":1.2},{"id":"da721ba9-e799-4eb0-8d5f-d65eec959cbe","name":"Upload CV","type":"n8n-nodes-base.googleDrive","position":[680,220],"parameters":{},"typeVersion":3},{"id":"f989cbb1-4eb8-4c77-ac03-5f5703afbc76","name":"OpenAI","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[1700,780],"parameters":{},"typeVersion":1.2},{"id":"e7b5b83c-042c-445c-869d-06d18aaba7d8","name":"Applicant's Details","type":"@n8n/n8n-nodes-langchain.informationExtractor","position":[1320,420],"parameters":{},"typeVersion":1},{"id":"8a537b27-4418-406b-a204-04249295298a","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[0,280],"parameters":{"content":""},"typeVersion":1},{"id":"ca220bd7-6621-4920-b9ea-47ed338fd0e9","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[560,0],"parameters":{"content":""},"typeVersion":1},{"id":"8405dc04-3d99-45f0-a93b-2343e7ad5583","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[920,240],"parameters":{"content":""},"typeVersion":1},{"id":"e66f542e-2a8d-46ee-95df-aa2655b12be4","name":"Add Applicant's Details in Google Sheet","type":"n8n-nodes-base.googleSheets","position":[1040,420],"parameters":{},"typeVersion":4.5},{"id":"d04a0c55-546d-41aa-91c5-c9fe0941981b","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1280,240],"parameters":{"content":""},"typeVersion":1},{"id":"e90fc56b-7878-46f3-a079-e95dab695f9f","name":"Summarize Applicant's Profile","type":"@n8n/n8n-nodes-langchain.chainSummarization","position":[1680,420],"parameters":{},"typeVersion":2},{"id":"d9c3773a-daa4-4f71-970d-d4d7ea2ddbf3","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[1640,240],"parameters":{"content":""},"typeVersion":1},{"id":"22b9732c-82b9-4eba-b195-62fd08744cce","name":"Get Job Description from Google Sheets","type":"n8n-nodes-base.googleSheets","position":[2120,420],"parameters":{},"typeVersion":4.5},{"id":"664e0387-c69b-4f4a-a431-db2e9fc98d3f","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[2000,240],"parameters":{"content":""},"typeVersion":1},{"id":"e7dbb219-28da-40d4-806b-ff44be167cc4","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[2360,240],"parameters":{"content":""},"typeVersion":1},{"id":"ce417cff-854e-4e5b-8ff8-966f132fa07e","name":"Summarize Job Role Description","type":"@n8n/n8n-nodes-langchain.chainSummarization","position":[2400,420],"parameters":{},"typeVersion":2},{"id":"3c684c15-bfc4-48ca-990f-c8bb12bb809a","name":"Semantic Fit & Evaluation by HR Expert","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[2760,420],"parameters":{},"typeVersion":1.5},{"id":"6940c4b0-b6b3-4e69-9203-a5c298ed77da","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[2720,140],"parameters":{"content":""},"typeVersion":1},{"id":"c43f554f-4d28-407e-aa32-164af6be244e","name":"Update Evaluation Results in Google Sheets","type":"n8n-nodes-base.googleSheets","position":[2120,900],"parameters":{},"typeVersion":4.5},{"id":"bcde088b-7689-42e5-9cdc-7bedd070ccd8","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[2000,720],"parameters":{"content":""},"typeVersion":1},{"id":"4190f1dc-88f2-4b97-bc2d-3cbb94e687c4","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[2360,720],"parameters":{"content":""},"typeVersion":1},{"id":"0e84b074-633a-4b45-8150-c8e734adcdf6","name":"Notify TA for Approval via Email","type":"n8n-nodes-base.emailSend","position":[2480,900],"webhookId":"6941e6ef-63b6-43f9-8911-32fdd84d13fe","parameters":{},"typeVersion":2.1},{"id":"73b71de6-ea39-456b-8c39-c4debef14f5f","name":"Approval Check - IF Condition","type":"n8n-nodes-base.if","position":[2840,900],"parameters":{},"typeVersion":2.2},{"id":"aa7c8080-62a9-47e8-90e1-35594164ac7d","name":"Sticky Note10","type":"n8n-nodes-base.stickyNote","position":[2720,720],"parameters":{"content":""},"typeVersion":1},{"id":"2c6d927f-d7e2-4a61-aef1-6f0eb0273792","name":"Sticky Note11","type":"n8n-nodes-base.stickyNote","position":[3520,320],"parameters":{"content":""},"typeVersion":1},{"id":"2abddb6e-c726-4610-9cb4-3acf1f6e2b18","name":"Send Shortlist Email to Candidate","type":"n8n-nodes-base.emailSend","position":[3620,500],"webhookId":"5b12b59d-c5b3-44b4-8359-e69ce6401120","parameters":{},"typeVersion":2.1},{"id":"0adc3251-c510-4ec8-8cb3-38200ac9cfa8","name":"Send Rejection Email to Candidate","type":"n8n-nodes-base.emailSend","position":[3620,920],"webhookId":"5b12b59d-c5b3-44b4-8359-e69ce6401120","parameters":{},"typeVersion":2.1},{"id":"0eb1fa6a-f927-4dcf-90b6-82a5c75d09e5","name":"Sticky Note12","type":"n8n-nodes-base.stickyNote","position":[3520,740],"parameters":{"content":""},"typeVersion":1},{"id":"f0f37e05-5b00-42bb-aa9d-80a1855791a6","name":"Sticky Note14","type":"n8n-nodes-base.stickyNote","position":[3120,300],"parameters":{"content":""},"typeVersion":1},{"id":"72ba03a4-5dd8-4d42-b2f4-3adee73df626","name":"Update Applicant's Status as REJECTED","type":"n8n-nodes-base.googleSheets","position":[3240,920],"parameters":{},"typeVersion":4.5},{"id":"81b96523-426f-4d78-bf48-ded4df362faa","name":"Sticky Note15","type":"n8n-nodes-base.stickyNote","position":[3120,740],"parameters":{"content":""},"typeVersion":1},{"id":"cc11a04b-543d-44a7-9f24-31fe71307e2c","name":"Run Daily at 09:00 AM","type":"n8n-nodes-base.scheduleTrigger","position":[100,920],"parameters":{},"typeVersion":1.2},{"id":"bd500d66-fb06-405e-b278-dc570d7f5da5","name":"Fetch Records with Status \"Resume Selected\"","type":"n8n-nodes-base.googleSheets","position":[320,920],"parameters":{},"typeVersion":4.5},{"id":"c1c21c4b-03bc-49a9-a1a3-5bcf9d20931b","name":"Loop to Send Assessment Link to Each Candidate","type":"n8n-nodes-base.splitInBatches","position":[580,920],"parameters":{},"typeVersion":3},{"id":"7037b68b-4b0b-447f-b51f-be8039995ed7","name":"Get Assessment Form URL","type":"n8n-nodes-base.googleSheets","position":[880,940],"parameters":{},"typeVersion":4.5},{"id":"3e155bf1-b5eb-4c86-aa9b-5b7773be15eb","name":"Send Assessment Submission Email","type":"n8n-nodes-base.emailSend","position":[1160,940],"webhookId":"92dfdc70-ac6d-468d-ae75-fb2c42b8a554","parameters":{},"typeVersion":2.1},{"id":"585c6022-b645-480f-a2d9-99a114609fbc","name":"Update Status to Assessment Sent","type":"n8n-nodes-base.googleSheets","position":[1440,940],"parameters":{},"typeVersion":4.5},{"id":"9930d8fd-a3fa-43a1-9a8c-1bef8876cb61","name":"Sticky Note17","type":"n8n-nodes-base.stickyNote","position":[0,720],"parameters":{"content":""},"typeVersion":1},{"id":"7e40f8fa-df27-418e-9dc6-3cc73202feea","name":"Technical Support Engineer Assessment Trigger","type":"n8n-nodes-base.typeformTrigger","position":[140,1580],"webhookId":"5d14bba3-737d-432a-b426-ecba0826e30a","parameters":{},"typeVersion":1.1},{"id":"675b08ff-2a53-45fc-ba61-c21657b0d123","name":"Technical Project Manager Assessment Trigger","type":"n8n-nodes-base.typeformTrigger","position":[140,1360],"webhookId":"5d14bba3-737d-432a-b426-ecba0826e30a","parameters":{},"typeVersion":1.1},{"id":"c35f75d4-eac8-42b6-8a18-7e7643c4c51e","name":"Update Applicant Status to Assessment Submitted","type":"n8n-nodes-base.googleSheets","position":[420,1460],"parameters":{},"typeVersion":4.5},{"id":"f32d787a-36b6-4cbf-aee1-1e7bc261092a","name":"Notify TA via Email for Assessment Submission","type":"n8n-nodes-base.emailSend","position":[740,1360],"webhookId":"92dfdc70-ac6d-468d-ae75-fb2c42b8a554","parameters":{},"typeVersion":2.1},{"id":"1dbd8726-60ad-4367-aa61-3dbdd1868cbf","name":"Notify TA via Slack for Assessment Submission","type":"n8n-nodes-base.slack","disabled":true,"position":[740,1580],"webhookId":"39e62d5a-b2e4-4912-a8d7-be43e1fe780f","parameters":{},"typeVersion":2.3},{"id":"2ce49266-9987-4e2d-91ed-a8b570f44af2","name":"Trigger when Interview booked by applicant in calendly","type":"n8n-nodes-base.calendlyTrigger","position":[560,1880],"webhookId":"b138a41c-e292-4533-8b02-7a3fea7b73e3","parameters":{},"typeVersion":1},{"id":"1d27e489-0d47-4cb7-a4c6-6cc75f410302","name":"Update Status to Interview Booked","type":"n8n-nodes-base.googleSheets","position":[780,1880],"parameters":{},"typeVersion":4.6},{"id":"cfe93e15-863b-447d-826c-3f319fec28ba","name":"Get Triggered when Applicant Status Update in Google Sheet","type":"n8n-nodes-base.googleSheetsTrigger","position":[1240,1720],"parameters":{},"typeVersion":1},{"id":"5ff66e2e-c71d-48cc-bf66-df4d4c616569","name":"Route actions based on Status","type":"n8n-nodes-base.switch","position":[1480,1640],"parameters":{},"typeVersion":3.2},{"id":"de0fac71-bf7f-4196-8126-d612805df08f","name":"Send Interview Invite Email","type":"n8n-nodes-base.emailSend","position":[1860,1360],"webhookId":"92dfdc70-ac6d-468d-ae75-fb2c42b8a554","parameters":{},"typeVersion":2.1},{"id":"74f4cffe-d362-4aa6-984a-67dca1479186","name":"Send Assessment Failed Email","type":"n8n-nodes-base.emailSend","position":[2080,1440],"webhookId":"92dfdc70-ac6d-468d-ae75-fb2c42b8a554","parameters":{},"typeVersion":2.1},{"id":"97383a17-8065-453c-8399-e8481a6608ac","name":"Send Interview Cancelled Email","type":"n8n-nodes-base.emailSend","position":[2260,1600],"webhookId":"92dfdc70-ac6d-468d-ae75-fb2c42b8a554","parameters":{},"typeVersion":2.1},{"id":"b2735319-d17a-4eed-9385-412a1df5725c","name":"Interview Reschedule Invite Email","type":"n8n-nodes-base.emailSend","position":[2120,1740],"webhookId":"92dfdc70-ac6d-468d-ae75-fb2c42b8a554","parameters":{},"typeVersion":2.1},{"id":"c343af76-bf0c-436d-9d07-06a2049b99fe","name":"Send Interview Passed/Shortlisted Email","type":"n8n-nodes-base.emailSend","position":[1980,1860],"webhookId":"92dfdc70-ac6d-468d-ae75-fb2c42b8a554","parameters":{},"typeVersion":2.1},{"id":"9fac2c36-bcec-4a40-a68e-0d359fa1ebf8","name":"Send Interview Failed Email","type":"n8n-nodes-base.emailSend","position":[1800,1960],"webhookId":"92dfdc70-ac6d-468d-ae75-fb2c42b8a554","parameters":{},"typeVersion":2.1},{"id":"5fb01de0-215b-4d6f-ab4a-b7414c5ad24c","name":"No Operation, do nothing","type":"n8n-nodes-base.noOp","position":[880,780],"parameters":{},"typeVersion":1},{"id":"1e5241e3-cc08-487d-a82d-b8005fb73091","name":"Sticky Note16","type":"n8n-nodes-base.stickyNote","position":[0,1200],"parameters":{"content":""},"typeVersion":1},{"id":"6ed12099-5d4d-41d5-884d-c1e3723e877c","name":"Sticky Note18","type":"n8n-nodes-base.stickyNote","position":[140,1840],"parameters":{"content":""},"typeVersion":1},{"id":"636939ce-caef-4a1c-918b-5dffd681b941","name":"Sticky Note19","type":"n8n-nodes-base.stickyNote","position":[1060,1200],"parameters":{"content":""},"typeVersion":1},{"id":"e6227def-3091-4b16-a573-dbe12a02d68a","name":"Sticky Note20","type":"n8n-nodes-base.stickyNote","position":[-560,140],"parameters":{"content":""},"typeVersion":1},{"id":"fc0eabbb-0cfe-49fd-9fef-ff6d6afd4681","name":"Update Applicant's Status as RESUME SELECTED","type":"n8n-nodes-base.googleSheets","position":[3240,500],"parameters":{},"typeVersion":4.5}],"connections":{"OpenAI":{"ai_languageModel":[[{"node":"Applicant's Details","type":"ai_languageModel","index":0},{"node":"Summarize Applicant's Profile","type":"ai_languageModel","index":0},{"node":"Semantic Fit & Evaluation by HR Expert","type":"ai_languageModel","index":0},{"node":"Summarize Job Role Description","type":"ai_languageModel","index":0}]]},"Extract from File":{"main":[[{"node":"Add Applicant's Details in Google Sheet","type":"main","index":0}]]},"On form submission":{"main":[[{"node":"Upload CV","type":"main","index":0},{"node":"Extract from File","type":"main","index":0}]]},"Applicant's Details":{"main":[[{"node":"Summarize Applicant's Profile","type":"main","index":0}]]},"Run Daily at 09:00 AM":{"main":[[{"node":"Fetch Records with Status \"Resume Selected\"","type":"main","index":0}]]},"Get Assessment Form URL":{"main":[[{"node":"Send Assessment Submission Email","type":"main","index":0}]]},"Structured Output Parser":{"ai_outputParser":[[{"node":"Semantic Fit & Evaluation by HR Expert","type":"ai_outputParser","index":0}]]},"Approval Check - IF Condition":{"main":[[{"node":"Update Applicant's Status as RESUME SELECTED","type":"main","index":0}],[{"node":"Update Applicant's Status as REJECTED","type":"main","index":0}]]},"Route actions based on Status":{"main":[[{"node":"Send Interview Invite Email","type":"main","index":0}],[{"node":"Send Assessment Failed Email","type":"main","index":0}],[],[{"node":"Send Interview Cancelled Email","type":"main","index":0}],[{"node":"Interview Reschedule Invite Email","type":"main","index":0}],[{"node":"Send Interview Passed/Shortlisted Email","type":"main","index":0}],[{"node":"Send Interview Failed Email","type":"main","index":0}]]},"Summarize Applicant's Profile":{"main":[[{"node":"Get Job Description from Google Sheets","type":"main","index":0}]]},"Summarize Job Role Description":{"main":[[{"node":"Semantic Fit & Evaluation by HR Expert","type":"main","index":0}]]},"Notify TA for Approval via Email":{"main":[[{"node":"Approval Check - IF Condition","type":"main","index":0}]]},"Send Assessment Submission Email":{"main":[[{"node":"Update Status to Assessment Sent","type":"main","index":0}]]},"Update Status to Assessment Sent":{"main":[[{"node":"Loop to Send Assessment Link to Each Candidate","type":"main","index":0}]]},"Update Applicant's Status as REJECTED":{"main":[[{"node":"Send Rejection Email to Candidate","type":"main","index":0}]]},"Get Job Description from Google Sheets":{"main":[[{"node":"Summarize Job Role Description","type":"main","index":0}]]},"Semantic Fit & Evaluation by HR Expert":{"main":[[{"node":"Update Evaluation Results in Google Sheets","type":"main","index":0}]]},"Add Applicant's Details in Google Sheet":{"main":[[{"node":"Applicant's Details","type":"main","index":0}]]},"Update Evaluation Results in Google Sheets":{"main":[[{"node":"Notify TA for Approval via Email","type":"main","index":0}]]},"Fetch Records with Status \"Resume Selected\"":{"main":[[{"node":"Loop to Send Assessment Link to Each Candidate","type":"main","index":0}]]},"Technical Project Manager Assessment Trigger":{"main":[[{"node":"Update Applicant Status to Assessment Submitted","type":"main","index":0}]]},"Update Applicant's Status as RESUME SELECTED":{"main":[[{"node":"Send Shortlist Email to Candidate","type":"main","index":0}]]},"Technical Support Engineer Assessment Trigger":{"main":[[{"node":"Update Applicant Status to Assessment Submitted","type":"main","index":0}]]},"Loop to Send Assessment Link to Each Candidate":{"main":[[{"node":"No Operation, do nothing","type":"main","index":0}],[{"node":"Get Assessment Form URL","type":"main","index":0}]]},"Update Applicant Status to Assessment Submitted":{"main":[[{"node":"Notify TA via Email for Assessment Submission","type":"main","index":0},{"node":"Notify TA via Slack for Assessment Submission","type":"main","index":0}]]},"Trigger when Interview booked by applicant in calendly":{"main":[[{"node":"Update Status to Interview Booked","type":"main","index":0}]]},"Get Triggered when Applicant Status Update in Google Sheet":{"main":[[{"node":"Route actions based on Status","type":"main","index":0}]]}}}


name: Build an Image Restoration Service with n8n & Gemini AI Image Editing
author_name: Jimleuk
author_username: jimleuk
nodes_used: ["n8n-nodes-base.httpRequest","n8n-nodes-base.googleDrive"]
categories: []
created_at: 2025-06-09T12:56:20.236Z
updated_at: 2025-06-09T12:56:20.236Z
url: https://n8n.io/workflows/4815
scraped_at: 2025-07-06 21:16:30
description:
  This n8n template demonstrates how to build a simple but effective vintage image restoration service using an AI model with image editing capabilities.

  With Gemini now capable of multimodal output, it's a great time to explore this capability for image or graphics automation. Let's see how well it does for a task such as image restoration.

  Good to know
  At time of writing, each image generated will cost $0.039 USD. See Gemini Pricing for updated info.
  The model used in this workflow is geo-restricted! If it says model not found, it may not be available in your country or region.

  How it works
  Images are imported into our workflow via the HTTP node and converted to base64 strings using the Extract from file node.
  The image data is then pipelined to Gemini's Image Generation model. A prompt is provided to instruct Gemini to "restore" the image to near new condition - of course, feel free to experiment with this prompt to improve the results!
  Gemini's responds with the image as a base64 string and hence, a convert to file node is used to transform the data to binary.
  With the restored image as a binary, we can then use this with our Google Drive node to upload it to our desired folder.

  How to use
  This demonstration uses 3 random images sourced from the internet but any typical image file will work.
  Use a webhook node to allow integration from other applications.
  Use a telegram trigger for instant mobile service!

  Requirements
  Google Gemini for LLM/Image generation
  Google Drive for Upload Storage

  Customising this workflow
  AI image editing can be applied to many use-cases not just image restoration. Try using it to add watermarks, branding or modify an existing image for marketing purposes.

workflow_json:
  {"meta":{"instanceId":"408f9fb9940c3cb18ffdef0e0150fe342d6e655c3a9fac21f0f644e8bedabcd9","templateCredsSetupCompleted":true},"nodes":[{"id":"b6a5c37d-b845-4fd2-8ea3-db23aed99286","name":"When clicking ‘Execute workflow’","type":"n8n-nodes-base.manualTrigger","position":[-80,320],"parameters":{},"typeVersion":1},{"id":"1f363fc5-42cf-4e9c-ae74-496030362ed9","name":"Sample Images","type":"n8n-nodes-base.set","position":[120,320],"parameters":{"options":{},"assignments":{"assignments":[{"id":"7196d08d-dff6-48e4-a06d-0ec863a4dff3","name":"url","type":"array","value":"={{\n[\n  \"https://res.cloudinary.com/daglih2g8/image/upload/f_auto,q_auto/v1/n8n-workflows/l8b3j1sf6ejx73z0awsh\",\n  \"https://res.cloudinary.com/daglih2g8/image/upload/f_auto,q_auto/v1/n8n-workflows/htrjbmiozdrvxwdsreyt\",\n  \"https://res.cloudinary.com/daglih2g8/image/upload/f_auto,q_auto/v1/n8n-workflows/ykftgxpozp2pr4sxpuoy\"\n]\n}}"}]}},"typeVersion":3.4},{"id":"e078aba0-2f2b-47b5-90b2-c457184e6237","name":"Split Out","type":"n8n-nodes-base.splitOut","position":[320,320],"parameters":{"options":{},"fieldToSplitOut":"url"},"typeVersion":1},{"id":"a0fbf72b-d079-4777-be06-531e0e131857","name":"Download Image","type":"n8n-nodes-base.httpRequest","position":[520,320],"parameters":{"url":"={{ $json.url }}","options":{}},"typeVersion":4.2},{"id":"77f0d0c7-e6bd-4f15-beff-9cb53446fcb0","name":"Gemini Image Restoration","type":"n8n-nodes-base.httpRequest","position":[1100,320],"parameters":{"url":"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-preview-image-generation:generateContent","method":"POST","options":{},"jsonBody":"={\n  \"contents\": [\n    {\n      \"parts\": [\n        {\n          \"text\": \"You are an vintage image restoration agent. Restore the given image by removing cracks and tears and fill in missing sections of the image. Retain the dimensions, colors and camera film type of the original image.\"\n        },\n        {\n          \"inline_data\": {\n            \"mime_type\": \"{{ $('Download Image').item.binary.data.mimeType }}\",\n            \"data\": \"{{ $json.data }}\"\n          }\n        }\n      ]\n    }\n  ],\n  \"generationConfig\": {\n    \"responseModalities\": [\n      \"TEXT\",\n      \"IMAGE\"\n    ]\n  }\n}","sendBody":true,"specifyBody":"json","authentication":"predefinedCredentialType","nodeCredentialType":"googlePalmApi"},"credentials":{"googlePalmApi":{"id":"dSxo6ns5wn658r8N","name":"Google Gemini(PaLM) Api account"}},"typeVersion":4.2},{"id":"6aebcc29-a65d-4cb9-8d6a-56f24b58c7f5","name":"Extract from File","type":"n8n-nodes-base.extractFromFile","position":[720,320],"parameters":{"options":{},"operation":"binaryToPropery"},"typeVersion":1},{"id":"1c50d319-1771-408f-9015-f04bb6a3d305","name":"Get Image Contents","type":"n8n-nodes-base.set","position":[1340,320],"parameters":{"options":{},"assignments":{"assignments":[{"id":"021aad70-de11-4387-844e-7e7dfd3b1044","name":"image","type":"string","value":"={{ $json.candidates[0].content.parts.find(part => part.inlineData).inlineData.data }}"},{"id":"62877ef7-2057-4d35-a44b-1d58fa1f1769","name":"mimeType","type":"string","value":"={{ $json.candidates[0].content.parts.find(part => part.inlineData).inlineData.mimeType }}"}]}},"typeVersion":3.4},{"id":"c19074f0-45a1-42bd-b25f-966f26ef5ef5","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[2220,-200],"parameters":{"width":700,"height":320,"content":"|Original|Restored|\n|-|-|\n|![](https://res.cloudinary.com/daglih2g8/image/upload/f_auto,q_auto/v1/n8n-workflows/l8b3j1sf6ejx73z0awsh)|![](https://res.cloudinary.com/daglih2g8/image/upload/f_auto,q_auto/v1/n8n-workflows/wvmeua6tpkvxiqcd6gpf)|"},"typeVersion":1},{"id":"82e82d53-e5ff-44a2-96ca-1867058fbb65","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-140,80],"parameters":{"color":7,"width":1060,"height":460,"content":"## 1. Download Sample Images\n[Read more about the HTTP Request node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/)\n\nFor this demonstration, we'll download 3 sample vintage photographs. These images show a variety of damage such as cracks, tears and missing or obscured sections and it will be the goal of this workflow to automate the restoration.\n\nInstead of a manual trigger, use a webhook trigger instead to integrate it into apps!"},"typeVersion":1},{"id":"eb1f70d5-2d3f-4f22-badb-d49569f565c2","name":"Upload to Drive","type":"n8n-nodes-base.googleDrive","position":[1960,320],"parameters":{"name":"=file_restored_{{ $itemIndex }}.{{ $binary.data.fileExtension }}","driveId":{"__rl":true,"mode":"list","value":"My Drive"},"options":{},"folderId":{"__rl":true,"mode":"list","value":"root","cachedResultName":"/ (Root folder)"}},"credentials":{"googleDriveOAuth2Api":{"id":"yOwz41gMQclOadgu","name":"Google Drive account"}},"typeVersion":3},{"id":"4f980d9d-a993-4ec6-80fd-1a323e40822d","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[960,80],"parameters":{"color":7,"width":620,"height":460,"content":"## 2. Use Gemini LLM to Restore Damaged Images\n[Read more about Gemini's Text and Image to Image Editing](https://ai.google.dev/gemini-api/docs/image-generation#gemini-image-editing)\n\nText-and-image-to-image capability enables LLMs to become instant replacements for a lot of image and photo editing applications. Here, we can use Gemini's new Image Generation model to restore vintage photos by removing damage and filling in missing sections."},"typeVersion":1},{"id":"69f7f355-5443-4265-b2a1-901711fa93dd","name":"Convert to File","type":"n8n-nodes-base.convertToFile","onError":"continueRegularOutput","position":[1720,320],"parameters":{"options":{"mimeType":"={{ $json.mimeType }}"},"operation":"toBinary","sourceProperty":"image"},"typeVersion":1.1},{"id":"beae9111-8186-4afd-9fa6-c732f0229854","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1620,80],"parameters":{"color":7,"width":560,"height":460,"content":"## 3. Upload to Google Drive\n[Read more about Google Drive node](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.googledrive)\n\nGemini outputs the image data as a base64 string so conversion to binary is sometimes necessary such as when uploading to Google Drive. We're using Google drive here but you can upload to any destination of your choosing."},"typeVersion":1},{"id":"00aaa458-1c49-4adf-87d6-ea70309107f9","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-640,-380],"parameters":{"width":460,"height":920,"content":"## Try It Out!\n### This n8n template demonstrates how to build a simple but effective vintage image restoration service using an AI model with image editing capabilities.\n\nWith Gemini now capable of multimodal output, it's a great time to explore this capability for image or graphics automation. Let's see how well it does for a task such as image restoration.\n\n**Please note, at time of writing each image generated will cost $0.039 USD**. See Gemini Pricing for updated info.\n\n### How it works\n* Images are imported into our workflow via the HTTP node and converted to base64 strings using the Extract from file node.\n* The image data is then pipelined to Gemini's Image Generation model. A prompt is provided to instruct Gemini to \"restore\" the image to near new condition - of course, feel free to experiment with this prompt to improve the results!\n* Gemini's responds with the image as a base64 string and hence, a convert to file node is used to transform the data to binary.\n* With the restored image as a binary, we can then use this with our Google Drive node to upload it to our desired folder.\n\n### How to use\n* This demonstration uses 3 random images sourced from the internet but any typical image file will work.\n* Use a webhook node to allow integration from other applications.\n* Use a telegram trigger for instant mobile service!\n\n### Requirements\n* Google Gemini for LLM/Image generation\n* Google Drive for Upload Storage\n\n### Need Help?\nJoin the [Discord](https://discord.com/invite/XPKeKXeB7d) or ask in the [Forum](https://community.n8n.io/)!\n\nHappy Hacking!"},"typeVersion":1},{"id":"4e4b822b-983b-48d2-a319-68242b7af171","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[-640,580],"parameters":{"color":5,"width":460,"height":140,"content":"### Geo Restrictions!\nPlease note at time of writing, the Gemini Image Generation model is restricted to certain countries and regions. If you're getting model not found errors, it's possible the model may not be available in your country!"},"typeVersion":1},{"id":"24d74843-d9b5-4302-8136-159e0a7dd492","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[2220,140],"parameters":{"width":400,"height":440,"content":"|Original|Restored|\n|-|-|\n|![](https://res.cloudinary.com/daglih2g8/image/upload/f_auto,q_auto/v1/n8n-workflows/htrjbmiozdrvxwdsreyt)|![](https://res.cloudinary.com/daglih2g8/image/upload/f_auto,q_auto/v1/n8n-workflows/ibm69t8gzcqqywrruioi)|"},"typeVersion":1},{"id":"f77ed90e-70ca-4268-9c77-17e49f94a4bb","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[2640,140],"parameters":{"width":580,"height":300,"content":"|Original|Restored|\n|-|-|\n|![](https://res.cloudinary.com/daglih2g8/image/upload/f_auto,q_auto/v1/n8n-workflows/ykftgxpozp2pr4sxpuoy)|![](https://res.cloudinary.com/daglih2g8/image/upload/f_auto,q_auto/v1/n8n-workflows/iah4qyu1xpiqwgl9sbg8)|"},"typeVersion":1}],"connections":{"Split Out":{"main":[[{"node":"Download Image","type":"main","index":0}]]},"Sample Images":{"main":[[{"node":"Split Out","type":"main","index":0}]]},"Download Image":{"main":[[{"node":"Extract from File","type":"main","index":0}]]},"Convert to File":{"main":[[{"node":"Upload to Drive","type":"main","index":0}]]},"Extract from File":{"main":[[{"node":"Gemini Image Restoration","type":"main","index":0}]]},"Get Image Contents":{"main":[[{"node":"Convert to File","type":"main","index":0}]]},"Gemini Image Restoration":{"main":[[{"node":"Get Image Contents","type":"main","index":0}]]},"When clicking ‘Execute workflow’":{"main":[[{"node":"Sample Images","type":"main","index":0}]]}}}


name: Compose/Stitch Separate Images together using n8n & Gemini AI Image Editing
author_name: Jimleuk
author_username: jimleuk
nodes_used: ["n8n-nodes-base.httpRequest","n8n-nodes-base.googleDrive"]
categories: []
created_at: 2025-06-09T13:00:49.415Z
updated_at: 2025-06-09T13:00:49.415Z
url: https://n8n.io/workflows/4817
scraped_at: 2025-07-06 21:16:30
description:
  This n8n template demonstrates how to use AI to compose or "stitch" separate images together to generate a new image which retains the source assets and consistent style.

  Use cases are many: Try producing storyboard scenes with consistent characters, marketing material with existing product assets or trying on different articles on fashion!

  Good to know
  At time of writing, each image generated will cost $0.039 USD. See Gemini Pricing for updated info.
  The model used in this workflow is geo-restricted! If it says model not found, it may not be available in your country or region.

  How it works
  We'll import our required assets via our Cloud storage using the HTTP node.
  The images are then converted to base64 strings and aggregated so we can use it for our AI model.
  Gemini's image generation model is used which takes all 3 images and a prompt that we define. Our prompt instructs the model on how to compose the final image.
  Gemini generates a new image but uses the original 3 assets to do so. The consistency to the source images is very high and shows little signs of hallucinations!
  Gemini's output is base64 so we use a "Convert to file" node to convert the data to binary.
  The final binary image is then uploaded to Google Drive to complete the demonstration.

  How to use
  The manual trigger node is used as an example but feel free to replace this with other triggers such as webhook or even a form.
  Technically, you should be able to compose even more images but of course, the generation will take longer and cost more.

  Requirements
  Gemini account for LLM and Image generation
  Google drive for upload

  Customising this workflow
  AI Image editing can be used for many use-cases. Try a popular use-case such as virtual try-on for fashion or applying branding on editing image assets.

workflow_json:
  {"meta":{"instanceId":"408f9fb9940c3cb18ffdef0e0150fe342d6e655c3a9fac21f0f644e8bedabcd9"},"nodes":[{"id":"bd94ff7b-0f66-45f7-bbab-bb2be0406532","name":"When clicking ‘Execute workflow’","type":"n8n-nodes-base.manualTrigger","position":[-540,320],"parameters":{},"typeVersion":1},{"id":"fdd66c07-8168-4f94-8ff5-ba4ceed476a9","name":"Get Image Contents","type":"n8n-nodes-base.set","position":[1400,320],"parameters":{"options":{},"assignments":{"assignments":[{"id":"021aad70-de11-4387-844e-7e7dfd3b1044","name":"image","type":"string","value":"={{ $json.candidates[0].content.parts.find(part => part.inlineData).inlineData.data }}"},{"id":"62877ef7-2057-4d35-a44b-1d58fa1f1769","name":"mimeType","type":"string","value":"={{ $json.candidates[0].content.parts.find(part => part.inlineData).inlineData.mimeType }}"}]}},"typeVersion":3.4},{"id":"e23db650-d0fa-4d87-87ea-3ab2e78292d8","name":"Upload to Drive","type":"n8n-nodes-base.googleDrive","position":[2020,320],"parameters":{"name":"=file_restored_{{ $itemIndex }}.{{ $binary.data.fileExtension }}","driveId":{"__rl":true,"mode":"list","value":"My Drive"},"options":{},"folderId":{"__rl":true,"mode":"list","value":"root","cachedResultName":"/ (Root folder)"}},"credentials":{"googleDriveOAuth2Api":{"id":"yOwz41gMQclOadgu","name":"Google Drive account"}},"typeVersion":3},{"id":"0a8bd3f0-a6e9-4862-942c-20ce336ab24e","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[1020,60],"parameters":{"color":7,"width":640,"height":460,"content":"## 2. Use Gemini LLM to Compose Images Together\n[Read more about Gemini's Text and Image to Image Editing](https://ai.google.dev/gemini-api/docs/image-generation#gemini-image-editing)\n\nComposing or \"Stitching\" images together may not seem particularly exciting but with Text-and-image-to-image capability, we can instruct the AI on \"how\" to put the images together. This is incredibly powerful feature when you need to use existing imagery or graphics in new pieces of work."},"typeVersion":1},{"id":"8a87bcea-7b60-46d8-9070-380397d9d0d8","name":"Convert to File","type":"n8n-nodes-base.convertToFile","onError":"continueRegularOutput","position":[1820,320],"parameters":{"options":{"mimeType":"={{ $json.mimeType }}"},"operation":"toBinary","sourceProperty":"image"},"typeVersion":1.1},{"id":"0ea0a3bf-e4fb-4beb-8a02-405602e17558","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1700,60],"parameters":{"color":7,"width":560,"height":460,"content":"## 3. Upload to Google Drive\n[Read more about Google Drive node](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.googledrive)\n\nGemini outputs the image data as a base64 string so conversion to binary is sometimes necessary such as when uploading to Google Drive. We're using Google drive here but you can upload to any destination of your choosing."},"typeVersion":1},{"id":"f6f9410f-f3ef-4b7b-88fe-774c30fe4e29","name":"Extract from File","type":"n8n-nodes-base.extractFromFile","position":[600,320],"parameters":{"options":{},"operation":"binaryToPropery"},"typeVersion":1},{"id":"c41e5653-bd37-4b17-9226-e9edf3d58899","name":"Merge1","type":"n8n-nodes-base.merge","position":[380,320],"parameters":{"numberInputs":3},"typeVersion":3.2},{"id":"0fe5cc27-e378-4a62-8477-1b666c4dcbe6","name":"Aggregate1","type":"n8n-nodes-base.aggregate","position":[820,320],"parameters":{"options":{},"aggregate":"aggregateAllItemData"},"typeVersion":1},{"id":"cd489b5f-0447-4d3e-84d1-a22142d02708","name":"Character","type":"n8n-nodes-base.httpRequest","position":[-300,120],"parameters":{"url":"https://res.cloudinary.com/daglih2g8/image/upload/f_auto,q_auto/v1/n8n-workflows/qwitjyhejockuxfvkk5g","options":{}},"typeVersion":4.2},{"id":"74e05106-26c0-4d59-adf9-274f2a1ddd7b","name":"Dalmation","type":"n8n-nodes-base.httpRequest","position":[-180,320],"parameters":{"url":"https://res.cloudinary.com/daglih2g8/image/upload/f_auto,q_auto/v1/n8n-workflows/gxcc0xnghpbthwt8fpec","options":{}},"typeVersion":4.2},{"id":"2bd84982-3984-4c22-a3de-0c871f5bc2ea","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[2300,60],"parameters":{"width":480,"height":540,"content":"## Final Output\n![](https://res.cloudinary.com/daglih2g8/image/upload/f_auto,q_auto/v1/n8n-workflows/rrezma7shzwffosy5apn#full-width)"},"typeVersion":1},{"id":"4e3155bf-983b-46b4-b6cb-38278edc34fb","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-300,-180],"parameters":{"width":220,"height":280,"content":"## Character\n![](https://res.cloudinary.com/daglih2g8/image/upload/f_auto,q_auto/v1/n8n-workflows/qwitjyhejockuxfvkk5g#full-width)"},"typeVersion":1},{"id":"01486147-0ddf-4055-9ebf-5bc6a884852c","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-40,120],"parameters":{"height":300,"content":"## Dalmation\n![](https://res.cloudinary.com/daglih2g8/image/upload/f_auto,q_auto/v1/n8n-workflows/gxcc0xnghpbthwt8fpec#full-width)"},"typeVersion":1},{"id":"e2153852-33b3-41dc-adcf-122027ada5a6","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-180,520],"parameters":{"height":300,"content":"## Sofa\n![](https://res.cloudinary.com/daglih2g8/image/upload/f_auto,q_auto/v1/n8n-workflows/nyghscauxtcfl4dve6of#full-width)"},"typeVersion":1},{"id":"510619c4-1e9c-4466-95f1-5eaa72d6ecc5","name":"Sofa","type":"n8n-nodes-base.httpRequest","position":[100,520],"parameters":{"url":"https://res.cloudinary.com/daglih2g8/image/upload/f_auto,q_auto/v1/n8n-workflows/nyghscauxtcfl4dve6of","options":{}},"typeVersion":4.2},{"id":"522cdb05-558c-4bd4-a4af-1a400bc641f9","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[300,60],"parameters":{"color":7,"width":680,"height":460,"content":"## 1. Convert Separate Images to Base64 Strings\n[Read more about the Extract from File node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.extractfromfile)\n\nTo use our images in this workflow, we will need to convert the binary data to base64 strings. This is later passed to the Gemini API to work on."},"typeVersion":1},{"id":"ce28bdf0-a03e-486c-9dd4-2aeb0896519e","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[-1080,-220],"parameters":{"width":460,"height":960,"content":"## Try It Out!\n### This n8n template demonstrates how to use AI to compose or \"stitch\" separate images together to generate a new image which retains the source assets and consistent style.\n\nUse cases are many: Try producing storyboard scenes with consistent characters, marketing material with existing product assets or trying on different articles on fashion!\n\n### How it works\n* We'll import our required assets via our Cloud storage using the HTTP node.\n* The images are then converted to base64 strings and aggregated so we can use it for our AI model.\n* Gemini's image generation model is used which takes all 3 images and a prompt that we define. Our prompt instructs the model on how to compose the final image.\n* Gemini generates a new image but uses the original 3 assets to do so. The consistency to the source images is very high and shows little signs of hallucinations!\n* Gemini's output is base64 so we use a \"Convert to file\" node to convert the data to binary.\n* The final binary image is then uploaded to Google Drive to complete the demonstration.\n\n### How to use\n* The manual trigger node is used as an example but feel free to replace this with other triggers such as webhook or even a form.\n* Technically, you should be able to compose even more images but of course, the generation will take longer and cost more.\n\n### Requirements\n* Gemini account for LLM and Image generation\n* Google drive for upload\n\n\n### Need Help?\nJoin the [Discord](https://discord.com/invite/XPKeKXeB7d) or ask in the [Forum](https://community.n8n.io/)!\n\nHappy Hacking!"},"typeVersion":1},{"id":"086cae2e-3b21-4262-917d-9d9f261d20d6","name":"Gemini Image Compose","type":"n8n-nodes-base.httpRequest","position":[1180,320],"parameters":{"url":"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-preview-image-generation:generateContent","method":"POST","options":{},"jsonBody":"={\n  \"contents\": [\n    {\n      \"parts\": [\n        {\n          \"text\": \"The character is sitting on the sofa, and the dalmation is lying on the blanket sleeping on the floor. Retain the image style of the character image.\"\n        },\n        {\n          \"inline_data\": {\n            \"mime_type\": \"image/png\",\n            \"data\": \"{{ $json.data[0].data }}\"\n          }\n        },\n        {\n          \"inline_data\": {\n            \"mime_type\": \"image/png\",\n            \"data\": \"{{ $json.data[1].data }}\"\n          }\n        },\n        {\n          \"inline_data\": {\n            \"mime_type\": \"image/png\",\n            \"data\": \"{{ $json.data[2].data }}\"\n          }\n        }\n      ]\n    }\n  ],\n  \"generationConfig\": {\n    \"responseModalities\": [\n      \"TEXT\",\n      \"IMAGE\"\n    ]\n  }\n}","sendBody":true,"specifyBody":"json","authentication":"predefinedCredentialType","nodeCredentialType":"googlePalmApi"},"credentials":{"googlePalmApi":{"id":"dSxo6ns5wn658r8N","name":"Google Gemini(PaLM) Api account"}},"typeVersion":4.2},{"id":"48127e5f-441a-4c46-9c96-3953e26ae092","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[-1080,760],"parameters":{"color":5,"width":460,"height":140,"content":"### Geo Restrictions!\nPlease note at time of writing, the Gemini Image Generation model is restricted to certain countries and regions. If you're getting model not found errors, it's possible the model may not be available in your country!"},"typeVersion":1}],"connections":{"Sofa":{"main":[[{"node":"Merge1","type":"main","index":2}]]},"Merge1":{"main":[[{"node":"Extract from File","type":"main","index":0}]]},"Character":{"main":[[{"node":"Merge1","type":"main","index":0}]]},"Dalmation":{"main":[[{"node":"Merge1","type":"main","index":1}]]},"Aggregate1":{"main":[[{"node":"Gemini Image Compose","type":"main","index":0}]]},"Convert to File":{"main":[[{"node":"Upload to Drive","type":"main","index":0}]]},"Extract from File":{"main":[[{"node":"Aggregate1","type":"main","index":0}]]},"Get Image Contents":{"main":[[{"node":"Convert to File","type":"main","index":0}]]},"Gemini Image Compose":{"main":[[{"node":"Get Image Contents","type":"main","index":0}]]},"When clicking ‘Execute workflow’":{"main":[[{"node":"Dalmation","type":"main","index":0},{"node":"Sofa","type":"main","index":0},{"node":"Character","type":"main","index":0}]]}}}


name: Extract and Analyze Google AI Overviews with LLM for SEO Recommendations
author_name: Roman Rozenberger
author_username: romek
categories: []
created_at: 2025-06-09T15:25:17.211Z
updated_at: 2025-06-09T15:25:17.211Z
url: https://n8n.io/workflows/4822
scraped_at: 2025-07-06 21:16:30
description:
  How it works

  • Extract AI Overviews from Google Search - Receives data from browser extension via webhook
  • Convert HTML to Markdown - Automatically processes and cleans AI Overview content  
  • Store in Google Sheets - Archives all extracted AI Overviews with metadata and sources
  • Generate SEO Guidelines - AI analyzes page content vs AI Overview to suggest improvements
  • Automate Analysis - Batch process multiple URLs and schedule regular checks

  Set up steps

  • Import workflow - Load the JSON template into your n8n instance (2 minutes)
  • Configure Google Sheets - Set up OAuth connection and create spreadsheet with required columns (5 minutes)  
  • Set up AI provider - Add OpenRouter API credentials for Gemini 2.5 Pro (3 minutes)
  • Install browser extension - Deploy the companion Chrome/Firefox extension for data extraction (5 minutes)
  • Test webhook endpoint - Verify the connection between extension and n8n workflow (2 minutes)

  Total setup time: ~15 minutes

  What you'll need:
  Google account for Sheets integration
  Google Sheet template with required columns
  OpenRouter API key for Gemini 2.5 Pro model access
  Browser extension: Chrome Extension or Firefox Add-on
  n8n instance (local or cloud)

  Use cases:
  SEO agencies** - Monitor AI Overview presence for client keywords
  Content marketers** - Analyze what content gets featured in AI Overviews
  E-commerce** - Track AI Overview coverage for product-related searches
  Research** - Build datasets of AI Overview content across different topics

  The workflow comes with a free browser extension (Chrome | Firefox) that automatically extracts AI Overview content from Google Search and sends it via webhook to your n8n workflow for processing and analysis.

  GitHub Repository: https://github.com/romek-rozen/ai-overview-extractor/

  Detailed Setup Instructions - AI Overview Extractor

  Prerequisites

  n8n instance** (local or cloud) - version 1.95.3+
  Google account** for Sheets integration
  OpenRouter API account** for Gemini 2.5 Pro access
  Browser** (Chrome/Firefox) for the extension

  Step 1: Import the Workflow

  Open n8n and navigate to Workflows
  Click "Add workflow" → "Import from JSON"
  Upload the AI_OVERVIES_EXTRACTOR_TEMPLATE.json file
  Save the workflow

  Step 2: Configure Google Sheets

  Create Google Sheets Document

  Create new Google Sheet with these columns:
        extractedAt | searchQuery | sources | markdown | myURL | task | guidelines | key 
     
  Here is public google sheet template: https://docs.google.com/spreadsheets/d/15xqZ2dTiLMoyICYnnnRV-HPvXfdgVeXowr8a7kU4uHk/edit?gid=0#gid=0 


  Copy the Google Sheets URL (you'll need it for the workflow)

  Set up Google Sheets Credentials

  In n8n, go to Settings → Credentials
  Click "Add credential" → "Google Sheets OAuth2 API"
  Follow the OAuth setup to authorize n8n access to Google Sheets
  Name the credential (e.g., "Google Sheets AI Overview")

  Configure Google Sheets Nodes

  Update these nodes with your Google Sheets URL:
  Get URLs to Analyze
  Save AI Overview to Sheets 
  Save SEO Guidelines to Sheets

  In each node:
  Set documentId to your Google Sheets URL
  Set sheetName to your Google Sheets URL
  Select your Google Sheets credential

  Step 3: Configure AI Provider (OpenRouter)

  Get OpenRouter API Key

  Sign up at https://openrouter.ai/
  Generate API key in your account settings
  Add credits to your account

  Set up OpenRouter Credentials

  In n8n, go to Settings → Credentials
  Click "Add credential" → "OpenRouter API"
  Enter your API key
  Name the credential (e.g., "OpenRouter AI Overview")

  Configure OpenRouter Node

  Select the Gemini 2.5 Pro Model node
  Choose your credential from the dropdown
  Verify the model (default: google/gemini-2.5-pro-preview)

  Step 4: Install Browser Extension

  Install in Chrome

  Official Extension (Recommended)
  Visit: https://chromewebstore.google.com/detail/ai-overview-extractor/cbkdfibgmhicgnmmdanlhnebbgonhjje
  Click "Add to Chrome"

  Install in Firefox

  Official Add-on
  Visit: https://addons.mozilla.org/en-US/firefox/addon/ai-overview-extractor/
  Click "Add to Firefox"

  Step 5: Configure Webhook Connection

  Get Webhook URL

  In n8n workflow, click on the Webhook node
  Copy the webhook URL (should be like: http://localhost:5678/webhook/ai-overview-extractor-template-123456789)

  Configure Extension

  Go to Google Search and perform any search with AI Overview
  Click the browser extension button (AI Overview Extractor)
  In webhook configuration section, paste your webhook URL
  Click "Test" - should show ✅ Test successful
  Click "Save" to store the configuration

  Step 6: Activate and Test

  Activate Workflow

  In n8n, toggle the workflow to "Active" (top right switch)
  Verify all nodes are properly configured

  Test End-to-End

  Go to Google Search
  Search for something that shows AI Overview
  Use the extension to extract AI Overview
  Send via webhook - check your Google Sheets for the data
  Verify the markdown conversion worked correctly

  Optional: Batch Analysis Setup

  For SEO Analysis Features

  In your Google Sheets, add URLs in the myURL column
  Set task column to "create guidelines"
  Run the workflow manually or wait for the 15-minute scheduler
  Check guidelines column for AI-generated SEO recommendations

  Troubleshooting

  Webhook Issues
  Ensure n8n is running on port 5678
  Check if workflow is activated
  Verify webhook URL format

  Google Sheets Errors
  Confirm OAuth credentials are working
  Check sheet URL format
  Verify column names match exactly
  Ensure nodes Get URLs to Analyze, Save AI Overview to Sheets, and Save SEO Guidelines to Sheets are properly configured

  OpenRouter Issues
  Check API key validity
  Ensure sufficient account credits
  Try different models if Gemini 2.5 Pro fails
  Verify the Gemini 2.5 Pro Model node is properly connected

  Extension Problems
  Check browser console for errors
  Verify extension is properly installed
  Ensure you're on google.com/search pages
  Confirm webhook URL is correctly configured in extension

  Next Steps

  Customize AI prompts** in the Generate SEO Recommendations node for your specific needs
  Adjust scheduler frequency** (default: 15 minutes)
  Add more URL analysis** by populating Google Sheets
  Monitor usage** and API costs

  Support

  GitHub Issues**: https://github.com/romek-rozen/ai-overview-extractor/issues
  n8n Community**: https://community.n8n.io/
  Template Documentation**: Check the included README files

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

workflow_json:
  {"id":"LCD5jIxtbjApUGd6","meta":{"instanceId":"e8794a4f970040d09c64040698c632aefaa9a59e97e60424e4b5671338351753"},"name":"Extract and Analyze Google AI Overviews with LLM for SEO Recommendations","tags":[],"nodes":[{"id":"d54405a8-ce00-4f39-bcea-fae97338a27f","name":"Webhook","type":"n8n-nodes-base.webhook","position":[-120,20],"webhookId":"81d02aee-0018-48f4-b228-0716bba9bf8b","parameters":{"path":"ai-overview-extractor-template-123456789","options":{},"httpMethod":"POST","responseMode":"lastNode"},"typeVersion":2},{"id":"2853ad27-91c9-405a-b696-b077823a1021","name":"When clicking 'Execute workflow'","type":"n8n-nodes-base.manualTrigger","position":[-100,740],"parameters":{},"typeVersion":1},{"id":"9dfbb1ee-6979-49bd-8963-f1b7f339feb5","name":"Save AI Overview to Sheets","type":"n8n-nodes-base.googleSheets","notes":"Send all data to Sheets","position":[620,20],"parameters":{"columns":{"value":{"key":"={{ $json.searchQuery }} {{ $json.extractedAt }}","task":"create guidelines","sources":"={{ \"\" || $json.sources.map(item => `* ${item.title} - ${item.url.extractDomain()} - ${item.url}`).join('\\n') }}","markdown":"={{ $json.markdown }}","extractedAt":"={{ $json.extractedAt }}","searchQuery":"={{ $json.searchQuery }}"},"schema":[{"id":"extractedAt","type":"string","display":true,"removed":false,"required":false,"displayName":"extractedAt","defaultMatch":false,"canBeUsedToMatch":true},{"id":"searchQuery","type":"string","display":true,"removed":false,"required":false,"displayName":"searchQuery","defaultMatch":false,"canBeUsedToMatch":true},{"id":"sources","type":"string","display":true,"removed":false,"required":false,"displayName":"sources","defaultMatch":false,"canBeUsedToMatch":true},{"id":"markdown","type":"string","display":true,"removed":false,"required":false,"displayName":"markdown","defaultMatch":false,"canBeUsedToMatch":true},{"id":"myURL","type":"string","display":true,"removed":true,"required":false,"displayName":"myURL","defaultMatch":false,"canBeUsedToMatch":true},{"id":"task","type":"string","display":true,"removed":false,"required":false,"displayName":"task","defaultMatch":false,"canBeUsedToMatch":true},{"id":"guidelines","type":"string","display":true,"removed":true,"required":false,"displayName":"guidelines","defaultMatch":false,"canBeUsedToMatch":true},{"id":"key","type":"string","display":true,"removed":false,"required":false,"displayName":"key","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["key"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{"cellFormat":"RAW"},"operation":"appendOrUpdate","sheetName":{"__rl":true,"mode":"url","value":"https://docs.google.com/spreadsheets/d/15xqZ2dTiLMoyICYnnnRV-HPvXfdgVeXowr8a7kU4uHk/edit?gid=0#gid=0"},"documentId":{"__rl":true,"mode":"url","value":"https://docs.google.com/spreadsheets/d/15xqZ2dTiLMoyICYnnnRV-HPvXfdgVeXowr8a7kU4uHk/edit?gid=0#gid=0"}},"credentials":{"googleSheetsOAuth2Api":{"id":"yTQwBHgpFHqp2Mxw","name":"gSheets roman@ibb.media"}},"notesInFlow":true,"typeVersion":4.6},{"id":"b2453757-c908-4747-8029-2d24e5690be4","name":"myURL Exists","type":"n8n-nodes-base.filter","notes":"Only records with myURL","position":[560,840],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"feb9922a-de0c-41d8-93d7-1f92ee7398b2","operator":{"type":"string","operation":"exists","singleValue":true},"leftValue":"={{ $json.myURL }}","rightValue":""}]}},"notesInFlow":true,"typeVersion":2.2},{"id":"f48fc7a2-c6ac-4426-9986-e987e5dc9a23","name":"Extract Page Title and H1","type":"n8n-nodes-base.html","notes":"Extract meta title and h1","position":[1440,800],"parameters":{"options":{},"operation":"extractHtmlContent","extractionValues":{"values":[{"key":"title","cssSelector":"title"},{"key":"h1","cssSelector":"h1"}]}},"notesInFlow":true,"typeVersion":1.2},{"id":"d250bdc4-0b58-41f4-afa2-ba82f67d67d6","name":"Merge","type":"n8n-nodes-base.merge","notes":"merge variables by position","position":[1660,700],"parameters":{"mode":"combine","options":{},"combineBy":"combineByPosition"},"typeVersion":3.2},{"id":"67d57eb8-2edc-4592-a9e2-0a5c0bade571","name":"Fetch Page Content","type":"n8n-nodes-base.httpRequest","notes":"Fetch site","position":[1220,700],"parameters":{"url":"={{ $json.myURL }}","options":{}},"notesInFlow":true,"typeVersion":4.2},{"id":"8d816cf1-dae5-4a47-9117-ed13dc9a4590","name":"Process URLs in Batches","type":"n8n-nodes-base.splitInBatches","position":[780,840],"parameters":{"options":{}},"typeVersion":3},{"id":"d8db7f48-21e3-4f7b-a48a-6931cf397601","name":"Get Current URL Data","type":"n8n-nodes-base.set","notes":"Single item data from loop","position":[1000,700],"parameters":{"options":{},"includeOtherFields":true},"notesInFlow":true,"typeVersion":3.4},{"id":"c82ae7fe-8369-461c-8661-ebd51371138b","name":"Save SEO Guidelines to Sheets","type":"n8n-nodes-base.googleSheets","notes":"send guidelines to sheets","position":[2260,700],"parameters":{"columns":{"value":{"task":"guidelines created","guidelines":"={{ $json.text }}","row_number":"={{ $('Get Current URL Data').item.json.row_number }}"},"schema":[{"id":"extractedAt","type":"string","display":true,"removed":true,"required":false,"displayName":"extractedAt","defaultMatch":false,"canBeUsedToMatch":true},{"id":"searchQuery","type":"string","display":true,"removed":true,"required":false,"displayName":"searchQuery","defaultMatch":false,"canBeUsedToMatch":true},{"id":"sources","type":"string","display":true,"removed":true,"required":false,"displayName":"sources","defaultMatch":false,"canBeUsedToMatch":true},{"id":"markdown","type":"string","display":true,"removed":true,"required":false,"displayName":"markdown","defaultMatch":false,"canBeUsedToMatch":true},{"id":"myURL","type":"string","display":true,"removed":true,"required":false,"displayName":"myURL","defaultMatch":false,"canBeUsedToMatch":true},{"id":"task","type":"string","display":true,"removed":false,"required":false,"displayName":"task","defaultMatch":false,"canBeUsedToMatch":true},{"id":"guidelines","type":"string","display":true,"removed":false,"required":false,"displayName":"guidelines","defaultMatch":false,"canBeUsedToMatch":true},{"id":"key","type":"string","display":true,"removed":true,"required":false,"displayName":"key","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":"url","value":"https://docs.google.com/spreadsheets/d/15xqZ2dTiLMoyICYnnnRV-HPvXfdgVeXowr8a7kU4uHk/edit?gid=0#gid=0"},"documentId":{"__rl":true,"mode":"url","value":"https://docs.google.com/spreadsheets/d/15xqZ2dTiLMoyICYnnnRV-HPvXfdgVeXowr8a7kU4uHk/edit?gid=0#gid=0"}},"credentials":{"googleSheetsOAuth2Api":{"id":"yTQwBHgpFHqp2Mxw","name":"gSheets roman@ibb.media"}},"notesInFlow":true,"typeVersion":4.6},{"id":"ecd9fbfa-328f-4507-a662-0c0d6e6f620e","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[-100,940],"parameters":{"rule":{"interval":[{"field":"minutes","minutesInterval":15}]}},"typeVersion":1.2},{"id":"90c30cd2-9b88-48e0-8846-065340014f29","name":"Wait","type":"n8n-nodes-base.wait","position":[2480,840],"webhookId":"03dd000b-26dc-4905-8efb-19a7175e689e","parameters":{},"typeVersion":1.1},{"id":"e0516ed5-69cd-4543-8816-aa70579aef2a","name":"Limit","type":"n8n-nodes-base.limit","notes":"Limit to 10 items","position":[340,840],"parameters":{"maxItems":10},"notesInFlow":true,"typeVersion":1},{"id":"30c3e6fb-044b-4d8c-8da2-5e67d95f397b","name":"Get URLs to Analyze","type":"n8n-nodes-base.googleSheets","notes":"Get rows with task : \"create guidelines\" and without guidelines","position":[140,800],"parameters":{"options":{},"filtersUI":{"values":[{"lookupValue":"create guidelines","lookupColumn":"task"},{"lookupColumn":"guidelines"}]},"sheetName":{"__rl":true,"mode":"url","value":"https://docs.google.com/spreadsheets/d/15xqZ2dTiLMoyICYnnnRV-HPvXfdgVeXowr8a7kU4uHk/edit?gid=0#gid=0"},"documentId":{"__rl":true,"mode":"url","value":"https://docs.google.com/spreadsheets/d/15xqZ2dTiLMoyICYnnnRV-HPvXfdgVeXowr8a7kU4uHk/edit?gid=0#gid=0"}},"credentials":{"googleSheetsOAuth2Api":{"id":"yTQwBHgpFHqp2Mxw","name":"gSheets roman@ibb.media"}},"notesInFlow":true,"typeVersion":4.6},{"id":"2253258b-846f-445d-baa8-7cb754a32738","name":"Gemini 2.5 Pro Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenRouter","notes":"You can change model or node","position":[1880,920],"parameters":{"model":"google/gemini-2.5-pro-preview","options":{"responseFormat":"text"}},"credentials":{"openRouterApi":{"id":"cxxykvBVJ4BwAWb8","name":"openrouter nimblio"}},"notesInFlow":true,"typeVersion":1},{"id":"5eeb0cd6-7fd9-4fd0-9053-08607bdc824c","name":"Convert AI Overview to Markdown","type":"n8n-nodes-base.markdown","notes":"convert HTML to Markdown","position":[320,20],"parameters":{"html":"={{ $json.htmlContent }}","options":{},"destinationKey":"markdown"},"notesInFlow":true,"typeVersion":1},{"id":"85e2d470-f80a-44db-8166-31b2883a310b","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-200,-100],"parameters":{"width":1060,"height":320,"content":"## Get data\nThis flow get data from webhook and stores it into Google Sheets. After you get data in sheets you need paste your site url in myURL and wait for guidelines."},"typeVersion":1},{"id":"cc15d895-9211-4480-8593-97c5e7f84697","name":"Generate SEO Recommendations","type":"@n8n/n8n-nodes-langchain.chainLlm","notes":"Create Ai Overviews based guidelines ","position":[1880,700],"parameters":{"text":"=# KEYWORD:\n{{ $('Get Current URL Data').item.json.searchQuery }}\n\n# PAGE CONTENT:\n{{ $json.data }}\n\n# AI OVERVIEW CONTENT:\n{{ $('Get Current URL Data').item.json.markdown }}\n\n# Task\nDescribe exactly what I need to change in my page content, and specify where to add or modify things. Provide clear, actionable instructions so I can implement the changes quickly.\n","batching":{},"messages":{"messageValues":[{"message":"=Your name is Alice, you are a helpful assistant.\n\nThe user will provide you with:\n- KEYWORD\n- PAGE CONTENT\n- AI OVERVIEWS (Google's Overview)\n\nAlice is an expert on AI Overviews (AI Overview) results and adapting content to meet AI Overviews (AI Overview) requirements.\n\nAlice's task is to prepare the content that should be placed on the page. This content should be what is missing from the PAGE CONTENT but is present in the AI OVERVIEWS.\n\nAlice responds directly in Markdown format and provides only the answer with the information about what should be included, starting directly with the content.\n\nWhen suggesting changes or additions:\n- Focus on identifying missing information or areas for improvement in the PAGE CONTENT based on AI OVERVIEWS.\n- Provide concise, actionable instructions. For example:\n    - \"Consider adding a brief mention of [specific topic from AI Overview] in the section discussing [relevant part of PAGE CONTENT].\"\n    - \"The AI Overview highlights [key fact/detail]. You could integrate this into the paragraph starting with '...' by adding a sentence like: '[brief example sentence incorporating the fact/detail]'.\"\n    - \"To cover [new tool/concept from AI Overview], consider creating a new subsection under [existing heading] titled '[suggested subsection title]'. This subsection should briefly outline its [key feature 1] and [key feature 2].\"\n- Instead of providing fully drafted new sections or long paragraphs, suggest the key points, topics, or specific short phrases/sentences to incorporate.\n- If existing text needs modification, clearly state what needs to change and provide a concise suggestion. For example:\n  \"In the sentence: `The old sentence was like this.`, consider rephrasing to: `The new, improved sentence could be like this.` to better reflect [reason based on AI Overview].\"\n- The goal is to guide the user to make targeted updates quickly, not to rewrite large portions of their content for them. Emphasize specific, small changes.\n\nAlice does not use ``` code blocks when starting the response.\n\n<writing_guidelines>\n- Alice write regular hyphens (-) instead of en dashes (–) or em dashes (—) .\n- Alice begins with the most crucial and relevant information that directly addresses the problem.\n- Alice is specific and create useful text. Alice provides specific, useful, and actionable information without superfluous content.\n- Clarity and precision: be certain and specific. Cut the fluff. Bold important terms, definitions, and their entire explanations. For example: **No contact: This refers to completely cutting off communication with an ex-partner as a crucial step in the emotional healing process.**\n- Inclusive language: include diverse perspectives and inclusive language.\n- No summarization: do not include summarization or recapitulation.\n- Readability: ensure the text is highly readable, using short sentences, simple words, and clear, concise language.\n- Grammar and style: avoid grammatical and stylistic errors. Ensure proper punctuation and sentence structure.\n- MARKDOWN formatting: ensure all tags are properly used and closed. Do not use class or id attributes.\n- Consistency: maintain consistency in terminology and style throughout the content.\n- Expertise: demonstrate expertise and authority in the subject matter. Use reliable sources and evidence to support statements.\n- Engagement: write in an engaging manner to keep the reader interested. Use storytelling, analogies, and examples where appropriate.\n- Avoid creating subheadings\n- To create inline code, wrap with backticks ` .\n- To create a code block, either indent each line by 4 spaces, or place 3 backticks ``` on a line above and below the code block.\n</writing_guidelines>\n\n<language>\n- Use concise, clear wording.\n- Start questions with \"what,\" \"how,\" and \"should\" (but avoid overusing \"How to\").\n- Incorporate action verbs (e.g., improves, increases, prevents).\n- Focus on benefits, risks, and factual information.\n- Use specific terms related to the topic.\n- Avoid generic terms like \"Introduction\", \"Overview\", \"Complete\", \"Ultimate\", \"Definitive\".\n- Use phrases like \"What is it?\" or \"What is…\" instead of writing \"Definition\".\n- Don't use phrases like \"everything you need to know\" or \"a deep dive into\".\n- Skip words like \"essential\", \"crucial\", \"vital\".\n- Omit \"In Today's World\" or \"Modern Approach to\".\n- Avoid buzzwords/jargon unless necessary.\n- Don't start with \"understanding\" or \"exploring\".\n- Exclude filler words like \"really\", \"actually\", \"basically\".\n- Limit use of gerunds (e.g., \"understanding\", \"implementing\", \"analyzing\").\n- Don't use capital letter after \":\" sign.\n- Use the spelling, case and grammar rules for the **PAGE CONTENT** language.\n- Cover various aspects of a topic (benefits, risks, types, comparisons).\n- Include relevant numerical data.\n- Address common questions and misconceptions.\n- Provide practical advice and recommendations.\n- Don't use \"conclusion\" or \"summary\" .\n</language>\n\n<seo_nlp_optimization>\nEnsure the content aligns with SEO best practices and NLP techniques to enhance readability and search engine visibility. Highlight the most relevant information at the beginning of each section.\n</seo_nlp_optimization>\n\nStart directly with the information that needs to be added to be featured in AI Overviews. Nothing more, nothing less."},{"type":"AIMessagePromptTemplate","message":"=CONTENT TO ADD:\n"}]},"promptType":"define"},"notesInFlow":true,"typeVersion":1.7},{"id":"7443adb0-440c-4223-8362-55641f0afa21","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-200,480],"parameters":{"width":2920,"height":680,"content":"## Guidelines flow\nThis flow generates guidelines and stores it in Google Sheets"},"typeVersion":1},{"id":"5607f7b6-c6b2-4325-95ae-1d749959946b","name":"Extract Webhook Data","type":"n8n-nodes-base.set","notes":"get only necessary data from webhook","position":[100,20],"parameters":{"options":{},"assignments":{"assignments":[{"id":"c5ac7498-8037-4daf-8964-c41a9e2c0ddd","name":"htmlContent","type":"string","value":"={{ $json.body.aiOverview.htmlContent }}"},{"id":"96170e13-fed1-4f4d-a993-c1487d254b2c","name":"sources","type":"array","value":"={{ $json.body.sources }}"},{"id":"79f421d4-3da7-4817-9f38-e26c49b8bd47","name":"extractedAt","type":"string","value":"={{ $json.body.metadata.extractedAt.toDateTime()}}"},{"id":"d7129419-db99-40e7-96d2-7893f9474182","name":"searchQuery","type":"string","value":"={{ $json.body.searchQuery }}"}]}},"typeVersion":3.4},{"id":"93567700-0a9e-4a19-934e-ee6d98eb9ba6","name":"Convert Page Content to Markdown","type":"n8n-nodes-base.markdown","notes":"convert html to markdown","position":[1440,600],"parameters":{"html":"={{ $json.data }}","options":{}},"notesInFlow":true,"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"9893a353-6861-4b33-8cad-51398078889b","connections":{"Wait":{"main":[[{"node":"Process URLs in Batches","type":"main","index":0}]]},"Limit":{"main":[[{"node":"myURL Exists","type":"main","index":0}]]},"Merge":{"main":[[{"node":"Generate SEO Recommendations","type":"main","index":0}]]},"Webhook":{"main":[[{"node":"Extract Webhook Data","type":"main","index":0}]]},"myURL Exists":{"main":[[{"node":"Process URLs in Batches","type":"main","index":0}]]},"Schedule Trigger":{"main":[[{"node":"Get URLs to Analyze","type":"main","index":0}]]},"Fetch Page Content":{"main":[[{"node":"Convert Page Content to Markdown","type":"main","index":0},{"node":"Extract Page Title and H1","type":"main","index":0}]]},"Get URLs to Analyze":{"main":[[{"node":"Limit","type":"main","index":0}]]},"Extract Webhook Data":{"main":[[{"node":"Convert AI Overview to Markdown","type":"main","index":0}]]},"Gemini 2.5 Pro Model":{"ai_languageModel":[[{"node":"Generate SEO Recommendations","type":"ai_languageModel","index":0}]]},"Get Current URL Data":{"main":[[{"node":"Fetch Page Content","type":"main","index":0}]]},"Process URLs in Batches":{"main":[[],[{"node":"Get Current URL Data","type":"main","index":0}]]},"Extract Page Title and H1":{"main":[[{"node":"Merge","type":"main","index":1}]]},"Generate SEO Recommendations":{"main":[[{"node":"Save SEO Guidelines to Sheets","type":"main","index":0}]]},"Save SEO Guidelines to Sheets":{"main":[[{"node":"Wait","type":"main","index":0}]]},"Convert AI Overview to Markdown":{"main":[[{"node":"Save AI Overview to Sheets","type":"main","index":0}]]},"Convert Page Content to Markdown":{"main":[[{"node":"Merge","type":"main","index":0}]]},"When clicking 'Execute workflow'":{"main":[[{"node":"Get URLs to Analyze","type":"main","index":0}]]}}}


name: AI-Powered WhatsApp Chatbot for Text, Voice, Images, and PDF with RAG
author_name: NovaNode
author_username: thomasgpt
categories: []
created_at: 2025-06-09T22:22:54.378Z
updated_at: 2025-06-09T22:22:54.378Z
url: https://n8n.io/workflows/4827
scraped_at: 2025-07-06 21:16:30
description:
  Who is this for?
  This template is designed for internal support teams, product specialists, and knowledge managers in technology companies who want to automate ingestion of product documentation and enable AI-driven, retrieval-augmented question answering via WhatsApp.

  What problem is this workflow solving?
  Support agents often spend too much time manually searching through lengthy documentation, leading to inconsistent or delayed answers. This solution automates importing, chunking, and indexing product manuals, then uses retrieval-augmented generation (RAG) to answer user queries accurately and quickly with AI via WhatsApp messaging.

  What these workflows do

  Workflow 1: Document Ingestion & Indexing

  Manually triggered to import product documentation from Google Docs.
  Automatically splits large documents into chunks for efficient searching.
  Generates vector embeddings for each chunk using OpenAI embeddings.
  Inserts the embedded chunks and metadata into a MongoDB Atlas vector store, enabling fast semantic search.

  Workflow 2: AI-Powered Query & Response via WhatsApp

  Listens for incoming WhatsApp user messages, supporting various types:
  	Text messages: Plain text queries from users.
  	Audio messages: Voice notes transcribed into text for processing.
  	Image messages: Photos or screenshots analyzed to provide contextual answers.
  	Document messages: PDFs, spreadsheets, or other files parsed for relevant content.
  Converts incoming queries to vector embeddings and performs similarity search on the MongoDB vector store.
  Uses OpenAI’s GPT-4o-mini model with retrieval-augmented generation to produce concise, context-aware answers.
  Maintains conversation context across multiple turns using a memory buffer node.
  Routes different message types to appropriate processing nodes to maximize answer quality.

  Setup

  Setting up vector embeddings

  Authenticate Google Docs and connect your Google Docs URL containing the product documentation you want to index.
  Authenticate MongoDB Atlas and connect the collection where you want to store the vector embeddings. Create a search index on this collection to support vector similarity queries.
  Ensure the index name matches the one configured in n8n (data_index).
  See the example MongoDB search index template below for reference.

  Setting up chat

  Authenticate the WhatsApp node with your Meta account credentials to enable message receiving and sending.
  Connect the MongoDB collection containing embedded product documentation to the MongoDB Vector Search node used for similarity queries.
  Set up the system prompt in the Knowledge Base Agent node to reflect your company’s tone, answering style, and any business rules, ensuring it references the connected MongoDB collection for context retrieval.

  Make sure

  Both MongoDB nodes (in ingestion and chat workflows) are connected to the same collection with:

  An embedding field storing vector data,

  Relevant metadata fields (e.g., document ID, source), and

  The same vector index name configured (e.g., data_index).

  Search Index Example:

  {
    "mappings": {
      "dynamic": false,
      "fields": {
        "_id": { "type": "string" },
        "text": { "type": "string" },
        "embedding": {
          "type": "knnVector",
          "dimensions": 1536,
          "similarity": "cosine"
        },
        "source": { "type": "string" },
        "doc_id": { "type": "string" }
      }
    }
  }

nodes_used:
  ["n8n-nodes-base.httpRequest","n8n-nodes-base.googleDocs","n8n-nodes-base.whatsApp","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.embeddingsOpenAi","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.memoryBufferWindow","@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter","@n8n/n8n-nodes-langchain.documentDefaultDataLoader","@n8n/n8n-nodes-langchain.openAi","@n8n/n8n-nodes-langchain.vectorStoreMongoDBAtlas"]

workflow_json:
  {"meta":{"instanceId":"074f90e2bb5206c5f405a8aac6551497c72005283a5405fb08207b1b3a78c2b8","templateCredsSetupCompleted":true},"nodes":[{"id":"d1b47f60-5a4d-4629-a18d-b3c6ec0c972c","name":"Knowledge Base Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[3720,400],"parameters":{"text":"={{ $json.text }}","options":{"systemMessage":""},"promptType":"define"},"typeVersion":1.9},{"id":"c36731ce-5086-4a2f-8c3a-63be150fb8ae","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[3720,580],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"cJRah9hGPQ7eX4jd","name":"OpenAi account"}},"typeVersion":1.2},{"id":"53c2496a-0737-452c-b49c-ca0afa9c0073","name":"Embeddings OpenAI","type":"@n8n/n8n-nodes-langchain.embeddingsOpenAi","position":[4060,740],"parameters":{"options":{}},"credentials":{"openAiApi":{"id":"cJRah9hGPQ7eX4jd","name":"OpenAi account"}},"typeVersion":1.2},{"id":"54697b14-28a0-4572-b17e-328a7b52cc90","name":"When clicking \"Execute Workflow\"","type":"n8n-nodes-base.manualTrigger","position":[1380,-560],"parameters":{},"typeVersion":1},{"id":"a79b9b58-0211-4570-af84-64db8bef9de3","name":"Simple Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[3820,580],"parameters":{"sessionKey":"=memory_{{ $('WhatsApp Trigger').item.json.contacts[0].wa_id }}","sessionIdType":"customKey"},"typeVersion":1.3},{"id":"fda97aec-70be-4611-94a3-7816e384c76b","name":"MongoDB Vector Search","type":"@n8n/n8n-nodes-langchain.vectorStoreMongoDBAtlas","position":[3940,580],"parameters":{"mode":"retrieve-as-tool","options":{},"toolName":"productDocs","mongoCollection":{"__rl":true,"mode":"list","value":"n8n-template","cachedResultName":"n8n-template"},"toolDescription":"retreive documentation","vectorIndexName":"data_index"},"credentials":{"mongoDb":{"id":"7riubYENUDZsmjyK","name":"MongoDB account 2"}},"typeVersion":1.1},{"id":"8cf54cb6-7247-4036-b1e4-9a28650d700a","name":"Document Section Loader","type":"@n8n/n8n-nodes-langchain.documentDefaultDataLoader","position":[1920,-400],"parameters":{"options":{"metadata":{"metadataValues":[{"name":"doc_id","value":"={{ $json.documentId }}"}]}},"jsonData":"={{ $json.content }}","jsonMode":"expressionData"},"typeVersion":1},{"id":"4e93e3c3-1847-483a-b6a7-67ff2cff294f","name":"Document Chunker","type":"@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter","position":[1920,-260],"parameters":{"options":{"splitCode":"markdown"},"chunkSize":3000,"chunkOverlap":200},"typeVersion":1},{"id":"4f616bfc-4ec7-4c88-8a63-cb2c47655680","name":"MongoDB Vector Store Inserter","type":"@n8n/n8n-nodes-langchain.vectorStoreMongoDBAtlas","position":[1820,-560],"parameters":{"mode":"insert","options":{},"mongoCollection":{"__rl":true,"mode":"list","value":"n8n-template","cachedResultName":"n8n-template"},"vectorIndexName":"data_index"},"credentials":{"mongoDb":{"id":"7riubYENUDZsmjyK","name":"MongoDB account 2"}},"typeVersion":1.1},{"id":"cc9a0766-69a4-4745-97f5-4c4c5e156c91","name":"OpenAI Embeddings Generator","type":"@n8n/n8n-nodes-langchain.embeddingsOpenAi","position":[1820,-400],"parameters":{"options":{}},"credentials":{"openAiApi":{"id":"cJRah9hGPQ7eX4jd","name":"OpenAi account"}},"typeVersion":1.2},{"id":"a9368d23-e35f-4986-8060-30a05f3f9c05","name":"Google Docs Importer","type":"n8n-nodes-base.googleDocs","position":[1600,-560],"parameters":{"operation":"get","documentURL":"https://docs.google.com/document/d/1gvgp71e9edob8WLqFIYCdzC7kUq3pLO37VKb-a-vVW4/edit?tab=t.0"},"credentials":{"googleDocsOAuth2Api":{"id":"FNXMwqMf7vl1WUFj","name":"Google Docs account"}},"typeVersion":2},{"id":"1fb0f8a3-9113-4185-a935-0fc327f70881","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[1000,-580],"parameters":{"color":5,"content":"Run this workflow manually to import and index Google Docs product documentation into MongoDB with vector embeddings for fast search."},"typeVersion":1},{"id":"62e13275-6f92-4799-9cbe-e0064ceb5140","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[1000,360],"parameters":{"color":4,"height":280,"content":"This workflow listens for WhatsApp messages (text, audio, image, documents), converts them into embeddings, searches MongoDB, and uses GPT-4o-mini to provide context-aware answers with conversation memory."},"typeVersion":1},{"id":"d21fc408-f66d-4b07-972a-811aa420b4ce","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[2220,-580],"parameters":{"height":540,"content":"Search Index Example \n\n{\n  \"mappings\": {\n    \"dynamic\": false,\n    \"fields\": {\n      \"_id\": {\n        \"type\": \"string\"\n      },\n      \"text\": {\n        \"type\": \"string\"\n      },\n      \"embedding\": {\n        \"type\": \"knnVector\",\n        \"dimensions\": 1536,\n        \"similarity\": \"cosine\"\n      },\n      \"source\": {\n        \"type\": \"string\"\n      },\n      \"doc_id\": {\n        \"type\": \"string\"\n      }\n    }\n  }\n}\n"},"typeVersion":1},{"id":"ddc0fdb7-bacc-4f41-87bf-48bb714a404d","name":"WhatsApp Trigger","type":"n8n-nodes-base.whatsAppTrigger","position":[1380,400],"webhookId":"ab09ca3e-53b2-4079-9ddc-bccb2f69551b","parameters":{"options":{},"updates":["messages"]},"credentials":{"whatsAppTriggerApi":{"id":"eb1MSQfEla9dGghs","name":"WhatsApp OAuth account"}},"typeVersion":1},{"id":"8842d0c7-082e-4b4e-b350-a8bb8f47c390","name":"OpenAI","type":"@n8n/n8n-nodes-langchain.openAi","position":[2460,160],"parameters":{"options":{},"resource":"audio","operation":"translate"},"credentials":{"openAiApi":{"id":"cJRah9hGPQ7eX4jd","name":"OpenAi account"}},"typeVersion":1.8},{"id":"a342dc14-0ffe-41ba-a3e9-853fe043f4fb","name":"OpenAI1","type":"@n8n/n8n-nodes-langchain.openAi","position":[2460,400],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"gpt-4o-mini","cachedResultName":"GPT-4O-MINI"},"options":{"detail":"auto"},"resource":"image","inputType":"base64","operation":"analyze"},"credentials":{"openAiApi":{"id":"cJRah9hGPQ7eX4jd","name":"OpenAi account"}},"typeVersion":1.8},{"id":"b1220587-fadf-4b5b-944e-b6e60b64c141","name":"Extract from PDF","type":"n8n-nodes-base.extractFromFile","position":[3060,860],"parameters":{"options":{},"operation":"pdf"},"typeVersion":1},{"id":"b02474a0-be6a-4591-a10c-abc2f597a3e6","name":"Extract from XLS","type":"n8n-nodes-base.extractFromFile","position":[2960,1060],"parameters":{"options":{},"operation":"xls"},"typeVersion":1},{"id":"1012f8a7-9fcb-4d80-ad5f-bfaa31eddf7d","name":"Extract from XLSX","type":"n8n-nodes-base.extractFromFile","position":[2960,1220],"parameters":{"options":{},"operation":"xlsx","binaryPropertyName":"=data"},"typeVersion":1},{"id":"8891a2eb-16d6-471a-803e-df1789a336f3","name":"Map JSON","type":"n8n-nodes-base.set","position":[3200,980],"parameters":{"options":{},"assignments":{"assignments":[{"id":"72ae0d20-616a-4a65-9b14-53bf53656091","name":"data","type":"string","value":"={{ $json }}"}]}},"typeVersion":3.4},{"id":"a0920bc7-71bd-4803-bbce-4cef14cac5ee","name":"Map file extensions","type":"n8n-nodes-base.code","position":[2420,740],"parameters":{"jsCode":"let requests = $(\"Download Document\").all()\n\nrequests.forEach((request) => {\n  let mime_type = request.json.mime_type\n\n  if (\n    mime_type === \"text/calendar\" || \n    mime_type === \"application/ics\" || \n    mime_type === \"text/x-calendar\"\n  ) {\n    request.json.mime_type = \"mapped/calendar\"\n  }\n\n  if (\n    mime_type === \"application/xml\" || \n    mime_type === \"text/xml\") {\n    request.json.mime_type = \"mapped/xml\"\n  }\n\n  if (!mime_type) {\n    request.json.mime_type = $('Gets WhatsApp Document Source URL').first().json.mime_type\n  }\n})\n\nreturn requests;"},"typeVersion":2},{"id":"77302aa3-6e87-4de6-9ec7-387ddb76fc84","name":"Map document prompt","type":"n8n-nodes-base.set","position":[3440,800],"parameters":{"options":{},"assignments":{"assignments":[{"id":"da68bcca-a2a6-4676-8649-6fb1b664e44c","name":"text","type":"string","value":"=Parsed text: {{ $json.text || $json.data || $json }}\n\nCaption text: {{ $('Route Types').item.json.messages[0].document.caption }}\n\nMimeType: {{ $('Gets WhatsApp Document Source URL').item.json.mime_type }}"}]}},"typeVersion":3.4},{"id":"90821e49-c98d-4617-8289-1be6d3aeb087","name":"Map image prompt","type":"n8n-nodes-base.set","position":[2680,400],"parameters":{"options":{},"assignments":{"assignments":[{"id":"48af2dcc-4ce9-45fc-abfc-54f803930092","name":"text","type":"string","value":"=User image description: {{ $json.content }}\n\nUser image caption: {{ $('Route Types').item.json.messages[0].image.caption }}"}]}},"typeVersion":3.4},{"id":"cf603f5c-0a6e-4cdd-846b-738ed417daa2","name":"Map text prompt","type":"n8n-nodes-base.set","position":[2020,-40],"parameters":{"options":{},"assignments":{"assignments":[{"id":"38aec976-a32c-4b0e-85f4-c90adc16abc9","name":"text","type":"string","value":"={{ $json.messages[0].text.body }}"}]}},"typeVersion":3.4},{"id":"7727e89d-cf21-4440-ab7f-85594eb1ec44","name":"Gets WhatsApp Voicemail Source URL","type":"n8n-nodes-base.whatsApp","position":[2020,160],"webhookId":"bbe62f3d-8788-49d4-aae6-9e9411446d44","parameters":{"resource":"media","operation":"mediaUrlGet","mediaGetId":"={{ $json.messages[0].audio.id}}"},"credentials":{"whatsAppApi":{"id":"HuYOJ00weACKEFR6","name":"WhatsApp account"}},"typeVersion":1},{"id":"08b938a1-d32e-4aa1-958f-bdabd3dfec13","name":"Gets WhatsApp Image Source URL","type":"n8n-nodes-base.whatsApp","position":[2020,400],"webhookId":"c2982df4-1d8d-4669-a724-44ae17d11e6c","parameters":{"resource":"media","operation":"mediaUrlGet","mediaGetId":"={{ $json.messages[0].image.id }}"},"credentials":{"whatsAppApi":{"id":"HuYOJ00weACKEFR6","name":"WhatsApp account"}},"typeVersion":1},{"id":"d934ce80-cdb0-476d-8896-b8c226086933","name":"Gets WhatsApp Document Source URL","type":"n8n-nodes-base.whatsApp","position":[2020,740],"webhookId":"c2982df4-1d8d-4669-a724-44ae17d11e6c","parameters":{"resource":"media","operation":"mediaUrlGet","mediaGetId":"={{ $json.messages[0].document.id }}"},"credentials":{"whatsAppApi":{"id":"HuYOJ00weACKEFR6","name":"WhatsApp account"}},"typeVersion":1},{"id":"aad1b221-0985-43e7-bc0b-312436171abe","name":"Download Voicemail","type":"n8n-nodes-base.httpRequest","position":[2240,160],"parameters":{"url":"={{ $json.url }}","options":{},"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"VZo8qdSLzpZ3qRlq","name":"Header Auth account"}},"typeVersion":4.2},{"id":"dfd08bec-9d30-4125-b167-7feaeefd7afa","name":"Download Image","type":"n8n-nodes-base.httpRequest","position":[2240,400],"parameters":{"url":"={{ $json.url }}","options":{},"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"VZo8qdSLzpZ3qRlq","name":"Header Auth account"}},"typeVersion":4.2},{"id":"ba3d221f-ce5c-4105-82cf-fbd11c2c0e2f","name":"Download Document","type":"n8n-nodes-base.httpRequest","position":[2240,740],"parameters":{"url":"={{ $json.url }}","options":{"response":{"response":{}}},"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"VZo8qdSLzpZ3qRlq","name":"Header Auth account"}},"typeVersion":4.2},{"id":"87ecc44f-cc1f-47e0-b995-079230be118d","name":"Route Types","type":"n8n-nodes-base.switch","position":[1600,380],"parameters":{"rules":{"values":[{"outputKey":"Text","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"2fc5c912-629b-4cbe-b5e3-7e3f0651c628","operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.messages[0].type }}","rightValue":"text"}]},"renameOutput":true},{"outputKey":"Audio","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"26a3d85c-0815-48ff-85ce-713129a1107c","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.messages[0].type }}","rightValue":"audio"}]},"renameOutput":true},{"outputKey":"Image","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"840b95b8-6559-4fb7-b32c-651451d6d0d2","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.messages[0].type }}","rightValue":"image"}]},"renameOutput":true},{"outputKey":"Document","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"3e7a07f9-b785-450c-8c68-f6b276838503","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.messages[0].type }}","rightValue":"document"}]},"renameOutput":true}]},"options":{}},"typeVersion":3.2},{"id":"ce3d08ce-4445-4473-90b2-227ba065c4d8","name":"Route Document Types","type":"n8n-nodes-base.switch","position":[2680,580],"parameters":{"rules":{"values":[{"outputKey":"CSV","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"14e23243-cd44-4cb1-99bd-9e6905d511ad","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.mime_type }}","rightValue":"text/csv"}]},"renameOutput":true},{"outputKey":"HTML","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"6d7616c5-6bdd-47b7-923e-639491d15a4e","operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.mime_type }}","rightValue":"text/html"}]},"renameOutput":true},{"outputKey":"Calendar","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"a2174e02-378a-41ff-b269-61f4fc3f1de9","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.mime_type }}","rightValue":"=mapped/calendar"}]},"renameOutput":true},{"outputKey":"RTF","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"f3b406d7-362d-473e-8edd-c3e5f2d9c44c","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.mime_type }}","rightValue":"text/rtf"}]},"renameOutput":true},{"outputKey":"TXT","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"64dd4658-54e7-4453-adbc-7067dffcd555","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.mime_type }}","rightValue":"text/plain"}]},"renameOutput":true},{"outputKey":"XML","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"7540a3ab-b48e-4bec-94e9-a5dfc3d65a4c","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.mime_type }}","rightValue":"mapped/xml"}]},"renameOutput":true},{"outputKey":"PDF","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"88b618fd-9a88-491e-91dd-c5fc9efa36e3","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.mime_type }}","rightValue":"application/pdf"}]},"renameOutput":true},{"outputKey":"JSON","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"9c4d90aa-b4ea-4a63-b15e-666899c8360e","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.mime_type }}","rightValue":"application/json"}]},"renameOutput":true},{"outputKey":"XLS","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"9baa7c88-3950-4099-8498-99a4640b95e7","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.mime_type }}","rightValue":"application/vnd.ms-excel"}]},"renameOutput":true},{"outputKey":"XLSX","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"b83e540c-ba1e-42d0-ac83-f675e25e6aea","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.mime_type }}","rightValue":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}]},"renameOutput":true},{"outputKey":"ELSE","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"ea3be820-2ead-4ec2-b292-42d3c7804b55","operator":{"type":"string","operation":"exists","singleValue":true},"leftValue":"={{ $json.mime_type }}","rightValue":""}]},"renameOutput":true}]},"options":{}},"typeVersion":3.2},{"id":"18684032-23ec-4e10-88f4-e93363432a67","name":"Send Unsupported Response","type":"n8n-nodes-base.whatsApp","position":[2960,1380],"webhookId":"017d267f-4897-4726-bf03-304ef10352bf","parameters":{"textBody":"=The File type you provided is unsupported.","operation":"send","phoneNumberId":"677680658761861","additionalFields":{},"recipientPhoneNumber":"={{ $('WhatsApp Trigger').item.json.messages[0].from }}"},"credentials":{"whatsAppApi":{"id":"HuYOJ00weACKEFR6","name":"WhatsApp account"}},"typeVersion":1},{"id":"acc8e4ae-0610-42fc-a318-b9a23a38919b","name":"Send Response","type":"n8n-nodes-base.whatsApp","position":[4080,400],"webhookId":"23834751-5066-48ba-8e19-549680df2b27","parameters":{"textBody":"={{ $json.output }}","operation":"send","phoneNumberId":"677680658761861","additionalFields":{},"recipientPhoneNumber":"={{ $('WhatsApp Trigger').item.json.messages[0].from }}"},"credentials":{"whatsAppApi":{"id":"HuYOJ00weACKEFR6","name":"WhatsApp account"}},"typeVersion":1}],"connections":{"OpenAI":{"main":[[{"node":"Knowledge Base Agent","type":"main","index":0}]]},"OpenAI1":{"main":[[{"node":"Map image prompt","type":"main","index":0}]]},"Map JSON":{"main":[[{"node":"Map document prompt","type":"main","index":0}]]},"Route Types":{"main":[[{"node":"Map text prompt","type":"main","index":0}],[{"node":"Gets WhatsApp Voicemail Source URL","type":"main","index":0}],[{"node":"Gets WhatsApp Image Source URL","type":"main","index":0}],[{"node":"Gets WhatsApp Document Source URL","type":"main","index":0}]]},"Simple Memory":{"ai_memory":[[{"node":"Knowledge Base Agent","type":"ai_memory","index":0}]]},"Download Image":{"main":[[{"node":"OpenAI1","type":"main","index":0}]]},"Map text prompt":{"main":[[{"node":"Knowledge Base Agent","type":"main","index":0}]]},"Document Chunker":{"ai_textSplitter":[[{"node":"Document Section Loader","type":"ai_textSplitter","index":0}]]},"Extract from PDF":{"main":[[{"node":"Map document prompt","type":"main","index":0}]]},"Extract from XLS":{"main":[[{"node":"Map JSON","type":"main","index":0}]]},"Map image prompt":{"main":[[{"node":"Knowledge Base Agent","type":"main","index":0}]]},"WhatsApp Trigger":{"main":[[{"node":"Route Types","type":"main","index":0}]]},"Download Document":{"main":[[{"node":"Map file extensions","type":"main","index":0}]]},"Embeddings OpenAI":{"ai_embedding":[[{"node":"MongoDB Vector Search","type":"ai_embedding","index":0}]]},"Extract from XLSX":{"main":[[{"node":"Map JSON","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"Knowledge Base Agent","type":"ai_languageModel","index":0}]]},"Download Voicemail":{"main":[[{"node":"OpenAI","type":"main","index":0}]]},"Map document prompt":{"main":[[{"node":"Knowledge Base Agent","type":"main","index":0}]]},"Map file extensions":{"main":[[{"node":"Route Document Types","type":"main","index":0}]]},"Google Docs Importer":{"main":[[{"node":"MongoDB Vector Store Inserter","type":"main","index":0}]]},"Knowledge Base Agent":{"main":[[{"node":"Send Response","type":"main","index":0}]]},"Route Document Types":{"main":[[{"node":"Map document prompt","type":"main","index":0}],[{"node":"Map document prompt","type":"main","index":0}],[{"node":"Map document prompt","type":"main","index":0}],[{"node":"Map document prompt","type":"main","index":0}],[{"node":"Map document prompt","type":"main","index":0}],[{"node":"Map document prompt","type":"main","index":0}],[{"node":"Extract from PDF","type":"main","index":0}],[{"node":"Map JSON","type":"main","index":0}],[{"node":"Extract from XLS","type":"main","index":0}],[{"node":"Extract from XLSX","type":"main","index":0}],[{"node":"Send Unsupported Response","type":"main","index":0}]]},"MongoDB Vector Search":{"ai_tool":[[{"node":"Knowledge Base Agent","type":"ai_tool","index":0}]]},"Document Section Loader":{"ai_document":[[{"node":"MongoDB Vector Store Inserter","type":"ai_document","index":0}]]},"Send Unsupported Response":{"main":[[]]},"OpenAI Embeddings Generator":{"ai_embedding":[[{"node":"MongoDB Vector Store Inserter","type":"ai_embedding","index":0}]]},"Gets WhatsApp Image Source URL":{"main":[[{"node":"Download Image","type":"main","index":0}]]},"When clicking \"Execute Workflow\"":{"main":[[{"node":"Google Docs Importer","type":"main","index":0}]]},"Gets WhatsApp Document Source URL":{"main":[[{"node":"Download Document","type":"main","index":0}]]},"Gets WhatsApp Voicemail Source URL":{"main":[[{"node":"Download Voicemail","type":"main","index":0}]]}}}


name: Generate SEO Arabic Articles and Save to Notion
author_name: Mahmoud Ashraf
author_username: ashrafai
categories: []
created_at: 2025-06-09T22:27:04.645Z
updated_at: 2025-06-09T22:27:04.645Z
url: https://n8n.io/workflows/4828
scraped_at: 2025-07-06 21:16:30
description:
  This workflow automatically creates in-depth, SEO-friendly Arabic articles based on any keyword you provide. It researches the topic, generates a full article outline, writes every section in Arabic, and saves the final article directly to your Notion workspace—all in a few clicks.

  How It Works

  Step 1:** You submit a simple web form with your keyword and (optionally) an article title.
  Step 2:** The workflow researches the topic using advanced AI, gathers trending questions from Google, and creates a detailed, structured outline.
  Step 3:** Each section of the article is written in Arabic by AI, following best SEO practices and including real FAQs.
  Step 4:** The completed article is automatically formatted and saved to your Notion database, ready for review or publishing.

  Setup Instructions

  What you need:**
      An OpenAI API key (for AI-powered writing and outline generation)
      An OpenRouter API key (for research via Perplexity/Sonar AI)
      A Notion account and Notion API integration (for saving articles)
      DataForSEO account (for fetching Google "People Also Ask" questions)
  How to set up:**
      Import the workflow into your n8n instance.
      Connect your API credentials for OpenAI, OpenRouter, Notion, and (optionally) DataForSEO.
      Update your Notion database ID in the workflow settings.
      Deploy the workflow. Fill out the web form to generate your first article.
  Setup time:** 10–20 minutes if you already have your accounts.

  Tip:

  You can fully customize the outline and writing prompts for your target audience or topic. The workflow is modular—easy to adapt for different languages or content styles.

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

workflow_json:
  {"id":"695TIBUSAmJfHXun","meta":{"instanceId":"e94dfd6411fa8fc47a434fdeab7c281cde3e3370d45bbb53e91728d7acb7b968","templateCredsSetupCompleted":true},"name":"Writing Articles - New","tags":[],"nodes":[{"id":"b25624fb-0f62-4843-a895-186dcde46e98","name":"On form submission","type":"n8n-nodes-base.formTrigger","position":[-100,-280],"webhookId":"8480eaab-9d4e-47dc-bfaa-40f988f011a3","parameters":{"options":{},"formTitle":"كتابة مقال","formFields":{"values":[{"fieldLabel":"KW","requiredField":true},{"fieldLabel":"Article's Title"}]}},"typeVersion":2.2},{"id":"ecb65485-28b8-46db-94ee-d5b55ff3f101","name":"Split Out","type":"n8n-nodes-base.splitOut","position":[640,-280],"parameters":{"options":{},"fieldToSplitOut":"message.content.queries"},"typeVersion":1},{"id":"b72ea761-08c3-4c07-a149-434affefd068","name":"Aggregate","type":"n8n-nodes-base.aggregate","position":[1260,-280],"parameters":{"options":{},"fieldsToAggregate":{"fieldToAggregate":[{"fieldToAggregate":"message.content"}]}},"typeVersion":1},{"id":"bd027eb0-7179-4615-a7a0-ef93020b3bbb","name":"Prmopts For Search","type":"@n8n/n8n-nodes-langchain.openAi","position":[280,-280],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"gpt-4.1","cachedResultName":"GPT-4.1"},"options":{},"messages":{"values":[{"role":"system","content":"You are an expert content researcher.\n\nBased on the provided **keyword**, your task is to generate **three detailed research prompts**, each covering a **different informational angle** of the topic.\n\nEach prompt must be a **comprehensive, natural-language query** designed to help an AI search engine (e.g., Perplexity AI) retrieve valuable, insightful, and high-quality information for article writing.\n\nThe three prompts should be written in **clear English**, and each one should focus on a **different research angle.**\n\nAll three prompts should be written in a **logical funnel structure,** progressing from general understanding to deeper insights.\n\nReturn only the following JSON structure:\n\n```json\n{\n  \"keyword\": \"[insert keyword here]\",\n  \"queries\": [\n    \"Prompt 1\",\n    \"Prompt 2\",\n    \"Prompt 3\"\n  ]\n}\n\n```"},{"content":"=Keyword:\n\n{{ $('On form submission').item.json.KW }}\n\nArticle's Title:\n\n{{ $('On form submission').item.json['Article\\'s Title'] }}\n\nPlease Respond only in English."}]},"jsonOutput":true},"credentials":{"openAiApi":{"id":"HsaKWYEwVbgIzutr","name":"SEO - Personal"}},"typeVersion":1.8},{"id":"3ae7b855-715b-4298-a2dc-a29d24f372ca","name":"Sonar - Search","type":"@n8n/n8n-nodes-langchain.openAi","position":[880,-280],"parameters":{"modelId":{"__rl":true,"mode":"id","value":"perplexity/sonar-pro"},"options":{},"messages":{"values":[{"content":"={{ $json['message.content.queries'] }}"}]}},"credentials":{"openAiApi":{"id":"FPynE2NyYvzr0qEt","name":"openrouter"}},"typeVersion":1.8},{"id":"8b9a40a8-bbe0-42be-b46a-14a8d5686cf9","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-180,-380],"parameters":{"width":1640,"height":380,"content":"## Research\n"},"typeVersion":1},{"id":"582ce887-713a-47e3-bbe0-d0b27eb84553","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[340,480],"parameters":{"color":6,"width":860,"height":380,"content":"## Outline\n"},"typeVersion":1},{"id":"86b33453-3f7a-42ce-ba8c-f5e7b1b3733c","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[360,960],"parameters":{"color":3,"width":820,"height":320,"content":"## Writing The Article\n"},"typeVersion":1},{"id":"3f3896ad-0734-4343-918a-a444e6565415","name":"Make An Outline","type":"@n8n/n8n-nodes-langchain.openAi","position":[520,600],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"gpt-4.1","cachedResultName":"GPT-4.1"},"options":{},"messages":{"values":[{"role":"system","content":"You are an expert SEO content strategist.\n\nYour task is to generate a structured, SEO-optimized outline for an article that fully addresses the search intent behind the provided keyword.\n\nThe outline should help a writer produce high-quality content based on the structure and essential information you provide.\n\nMake the outline as detailed and comprehensive as possible. It should be suitable for writing a long-form, in-depth article, not a short or surface-level piece.\n\n---\n\n### **Methodology**\n\n### 1. Start with the Reader’s Journey\n\n- Think of the article as a **funnel** — guide the reader step by step, from awareness to understanding, to depth, and finally to action or resolution.\n- Ensure each H2 section is **logically connected** to the one before it, forming a clear, natural narrative progression.\n- The **second H2 section** after the introduction must **directly answer the primary search intent** of the keyword.\n- Each H2 section must connect narratively to the previous one. The outline should flow as a continuous reader journey — like a funnel — starting with awareness, then understanding, followed by challenges/solutions, and ending in resolution.\n\n---\n\n### **H2 Structure Guidelines**\n\n- Break the outline into **main sections (H2s)** written in **question format** (3–5 words max).\n- The first H2 must always be \"المقدمة\" and must clearly follow one of the following content strategies: PAS, AIDA, BAB, or RAD. The strategy used must be explicitly labeled inside the H2 heading (e.g., \"المقدمة (AIDA - 2 paragraphs)\").\n- Include at least one dedicated **FAQ section** and a final **Conclusion** section.\n- After each H2 heading, specify the **expected format** in parentheses (e.g., intro, 2–3 paragraphs, list + explanation, etc.).\n- Only assign a format to an H2 if it contains no H3s. If the H2 includes H3s, leave its format blank to avoid conflict.\n- Use the main keyword or its variations inside H2s for SEO performance.\n\n---\n\n### **H3 Structure Guidelines**\n\n- Add **supporting H3s** under each H2 — also in **short question format** (3–5 words max).\n- After each H3, specify the **expected format** (e.g., single paragraph, paragraph + bullet points).\n- Each H3 must focus on a unique sub-topic that directly supports the H2.\n- Ensure that each H3 is **a natural and functional sub-question** of its H2 — it must **directly break down, clarify, or expand the parent H2 topic** without shifting focus or introducing unrelated sub-themes.\n- Prioritize questions that reflect **real user queries**.\n- Avoid repeating ideas across sections.\n\n---\n\n### **Information Requirement**\n\n- Under each **H2**, include an `\"info\"` field that lists **all detailed information points** required for writing — avoid summaries or generalizations. Include **every factual detail** necessary to fully cover the section, as if you’re feeding a writer everything they need without assuming prior knowledge.\n- Each point should be **detailed, complete, and directly usable** for content generation — no summaries or simplifications.\n- These points are meant to **guide the writer** — they must be accurate, specific, and actionable, without invented or vague content.\n\n---\n\n### **General Rules**\n\n- Ensure the structure is **SEO-friendly**, clear, and skimmable.\n- Keep headings short, natural, and phrased like real search queries.\n- The full outline must read like a **guided narrative** — funneling the reader through a structured journey from intro to resolution.\n- Match the outline to the **article type**: product-based, how-to, comparison, informational, or thought leadership.\n- Avoid generic or duplicate sections.\n- WRITE your outline in Arabic and the **format in English** (like the example below).\n\n---\n\n### Final Output Format\n\n- Do not include any explanation or headers — just return the JSON.\n- The final output must be in **JSON** format with this structure (just the structure, not its content ideas):\n\n```json\n{\n  \"title\": \"عنوان المقال\",\n  \"outline\": [\n    {\n      \"h2\": \"المقدمة (2 paragraphs)\",\n      \"h3\": [],\n      \"info\": [\n        \"يُعد [الموضوع] من أبرز الأدوات الحديثة التي تلبي احتياجات مختلفة في مجالات الأعمال والتقنية.\",\n        \"أصبح هذا النظام شائعًا بفضل مرونته وسهولة استخدامه، وقد تم اعتماده في شركات عالمية مثل Google وAmazon لتحقيق نتائج تشغيلية ملموسة.\",\n        \"المقال موجه للمحترفين، مديري المشاريع، والمبتدئين الذين يبحثون عن وسيلة فعالة لتحسين أدائهم أو أتمتة أعمالهم.\",\n        \"سيتعرف القارئ على آلية عمل [الموضوع]، فوائده، تحدياته، وكيفية مقارنته بالبدائل المطروحة في السوق.\"\n      ]\n    },\n    {\n      \"h2\": \"ما هو [الموضوع]؟\",\n      \"h3\": [\n        \"كيف يعمل؟ (2 paragraphs)\",\n        \"مم يتكون؟ (bullet points + details)\"\n      ],\n      \"info\": [\n        \"[الموضوع] هو نظام أو أداة تُستخدم لأتمتة أو تسريع عمليات معينة باستخدام تقنيات الذكاء الاصطناعي أو الخوارزميات الذكية.\",\n        \"يعتمد على جمع البيانات، تحليلها، ثم تنفيذ إجراءات تلقائية مبنية على نتائج التحليل.\",\n        \"يتكون من واجهة استخدام رسومية، قاعدة بيانات، وحدة تحليل، ونظام تكامل API.\",\n        \"يدمج [الموضوع] بين تقنيات مثل تعلم الآلة والحوسبة السحابية لتحقيق أداء عالي الكفاءة.\"\n      ]\n    },\n    {\n      \"h2\": \"ما فوائد استخدام [الموضوع]؟\",\n      \"h3\": [\n        \"تحسين الإنتاجية (paragraph + data)\",\n        \"تقليل الأخطاء البشرية (1 paragraph)\",\n        \"دعم اتخاذ القرار (paragraph + example)\"\n      ],\n      \"info\": [\n        \"تشير دراسة من McKinsey إلى أن اعتماد هذا النوع من الأدوات يؤدي إلى تحسين الإنتاجية بنسبة تصل إلى 40% في فرق العمل التقنية.\",\n        \"يُقلل من تدخل الإنسان في العمليات التكرارية، ما يقلل من معدل الأخطاء بنسبة تصل إلى 60%.\",\n        \"يُمكن دمجه مع أدوات تحليل بيانات لتقديم توصيات فورية تدعم القرارات الاستراتيجية، كما تم تطبيقه بنجاح في شركة X لتحسين قرارات المبيعات.\",\n        \"يوفر الوقت ويقلل التكلفة التشغيلية بمعدل ثابت عند دمجه في العمليات اليومية.\"\n      ]\n    },\n    {\n      \"h2\": \"من يستخدم [الموضوع]؟\",\n      \"h3\": [\n        \"الشركات الناشئة (paragraph)\",\n        \"الفرق التقنية (paragraph)\",\n        \"المؤسسات التعليمية (1 paragraph)\"\n      ],\n      \"info\": [\n        \"الشركات الناشئة تعتمد عليه لأتمتة المهام المتكررة وتوفير الموارد.\",\n        \"الفرق التقنية تستخدمه لتحسين سير العمل، وتقليل الزمن اللازم لتسليم المشاريع.\",\n        \"المؤسسات التعليمية بدأت بدمج [الموضوع] في برامجها التدريبية لتأهيل الطلاب لسوق العمل الحديث.\"\n      ]\n    },\n    {\n      \"h2\": \"مقارنة بين [الموضوع] و[بديله]؟ (bullet points + details)\",\n      \"h3\": [],\n      \"info\": [\n        \"تشمل المقارنة: الميزات، التكلفة، الدعم الفني، سهولة الاستخدام، التوافق مع الأدوات الأخرى.\",\n        \"[الموضوع] يتميز بسهولة التخصيص وواجهة مرنة، بينما [البديل] أقوى في التحليلات المتقدمة.\",\n        \"من حيث التكلفة، يوفر [الموضوع] خيارًا اقتصاديًا أكثر على المدى الطويل\",\n        \"في استطلاع حديث، اختار 68% من المستخدمين [الموضوع] بسبب تجربة المستخدم الأفضل.\"\n      ]\n    },\n    {\n      \"h2\": \"ما التحديات المرتبطة باستخدام [الموضوع]؟\",\n      \"h3\": [\n        \"صعوبات التهيئة الأولية (paragraph)\",\n        \"الحاجة للتدريب (1 paragraph)\",\n        \"مشكلات التوافق التقني (paragraph + example)\"\n      ],\n      \"info\": [\n        \"يحتاج إلى إعداد تقني دقيق قبل التشغيل لضمان عدم حدوث خلل وظيفي.\",\n        \"يتطلب من الفرق التقنية أو المستخدمين النهائيين فهمًا كافيًا لطريقة عمله، ما قد يستدعي تدريب داخلي أو دورات خارجية.\",\n        \"في بعض الحالات، لا يتكامل بسهولة مع أنظمة إدارة المشاريع التقليدية، كما في مثال شركة Y التي واجهت تأخيرًا في الدمج.\"\n      ]\n    },\n    {\n      \"h2\": \"الأسئلة الشائعة حول [الموضوع] (FAQ)\",\n      \"h3\": [\n        \"هل يناسب المبتدئين؟ (1 paragraph)\",\n        \"هل هو آمن للاستخدام؟ (paragraph + data)\",\n        \"هل يحتاج لتحديث مستمر؟ (single paragraph)\"\n      ],\n      \"info\": [\n        \"[الموضوع] صُمم ليكون سهل الاستخدام حتى للمستخدمين غير التقنيين، بفضل واجهته البديهية والدعم المتكامل.\",\n        \"نسبة أمان عالية تم توثيقها في عدة اختبارات أمان رقمية أجرتها جهة مستقلة.\",\n        \"يفضل تحديثه دوريًا لضمان عمله بكفاءة وتوافقه مع أي تغييرات في بيئة العمل أو البيانات.\"\n      ]\n    },\n    {\n      \"h2\": \"الخلاصة (2 short paragraphs)\",\n      \"h3\": [],\n      \"info\": [\n        \"[الموضوع] يُعد أداة محورية في تحسين الأداء المؤسسي وتسهيل العمليات، مع نتائج ملموسة موثقة في العديد من القطاعات.\",\n        \"ينصح بدمجه بشكل تدريجي في المنظومة التشغيلية مع توفير التدريب المناسب لضمان أقصى استفادة.\"\n      ]\n    }\n  ]\n}\n\n```\n\nImportant:\n\n- The example JSON is meant to demonstrate the required structure and formatting only. The actual headings (h2, h3) and info content must be uniquely generated based on the keyword, not copied from the example.\n- All h2 and h3 items must be plain strings that include the format inside parentheses (e.g., \"ما هي الفوائد؟ (2 paragraphs)\").\n- Do not use nested objects or additional keys like \"text\" or \"format\" — only use a single string for each heading.\n- The outline must follow this structure exactly:\"h2\": string (with format in parentheses)\n- All h3 items must be written as plain strings that include the format in parentheses, like\n- Do not return h3 as objects or use keys like \"format\" — it must be a single string only.\n- Do not return keys like \"format\", \"text\", or \"content\" — just follow the format shown above."},{"content":"=Title\n{{ $('On form submission').item.json[\"Article's Title\"] }}\n\nKeyword Of The Topic:\n{{ $('On form submission').item.json.KW }}\n\nSome info To use:\n\n{{ $('Aggregate').item.json.content }}\n\nSome Q&A to use in FAQs (use the question title as written):\n{{ $json.FAQ }}"}]},"jsonOutput":true},"credentials":{"openAiApi":{"id":"HsaKWYEwVbgIzutr","name":"SEO - Personal"}},"typeVersion":1.8},{"id":"f42f70d2-a3e9-4af1-8d95-8ac7650f1816","name":"Split Out1","type":"n8n-nodes-base.splitOut","position":[940,600],"parameters":{"options":{},"fieldToSplitOut":"message.content.outline"},"typeVersion":1},{"id":"8cdef061-bae0-4bb8-b191-8b28718a901d","name":"Writing The Article","type":"@n8n/n8n-nodes-langchain.openAi","position":[640,1020],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"gpt-4.1","cachedResultName":"GPT-4.1"},"options":{},"messages":{"values":[{"role":"system","content":"You are a professional Arabic content writer.\n\nYour task is to write a complete article section based on:\n\n- The provided H2 heading\n- Its related H3 subpoints\n- The given information about the section\n\nFollow the instructions below carefully.\n\n### **Writing Methodology**\n\n1. **Structure & Flow**\n    - Start by writing the H2 title (do not change or rephrase it) (Do not mention the format), then the content, and follow the H3 subpoints one by one..\n    - Do not invent or introduce any ideas beyond what is provided.\n    - Do not create a separate introduction or conclusion for the H2 — just continue the article smoothly, your role now just to write the section needed.\n2. **Skimmability**\n    - The paragraphs should be short (2–4 lines max).\n    - The bullet points, when needed, should be used without a heading. Each bullet should be a complete sentence, not just a fragment.\n3. **SEO Optimization**\n    - Use the main keyword and related terms naturally in the text.\n    - Use semantic variations and rich vocabulary.\n    - Structure content so that it can rank for featured snippets.\n\n---\n\n### Tone & Style Guidelines\n\n- Use the plural form of \"you\" to maintain a gender-neutral and inclusive tone.\n- Keep the tone natural, human.\n- You are allowed to express the information using rich, natural language, but only using the facts and details provided. Do not create new ideas or reframe the intent.\n- Avoid overly technical, dry, or formal language.\n- Use diverse vocabulary and expressive sentence structure.\n- DO NOT use clichés or generic phrases such as:\n    - \"من الجدير بالذكر\", \"لا شك أن\", \"علاوة على ذلك\", \"الخيار الأمثل\",\n    \"في هذا الصدد\", \"في الختام\", \"نرجو أن نكون قد وُفقنا\", \"مما لا شك فيه\",\n    \"الأفضل على الإطلاق\", \"ثوري\", \"رائع للغاية\"\n    - Or any phrase that sounds like generic AI content.\n- Avoid wordiness or unnecessary repetition — every sentence must deliver clear, meaningful content.\n- Do not use filler language or vague expressions that add no real value.\n- Do not oversimplify in a way that reduces the accuracy or depth of the information — maintain a balance between clarity and substance.\n- Write In Arabic.\n\n---\n\n### **Hard Restrictions**\n\n- Do **not** add any information that isn't included in the provided data.\n- Do **not** create fake references, data, or quotes.\n- Do **not** mention sources or references in the output.\n- Do **not** change the flow of the article — respect the sequence in the outline.\n\n---\n\nFormat the output using a clean Markdown structure. Use clean Markdown:\n\n`#` for H1, `##` for H2,..etc, `-` for bullets, `1.` for numbered lists, `**bold**` for emphasis, and line breaks between items."},{"content":"=Main Keyword of The Topic:\n\n{{ $('On form submission').item.json.KW }}\n\nHere is The Section You will write and its info (just write this section):\n\nH2:\n\n{{ $json.h2 }}\nH3s:\n{{ $json.h3 }}\n\nInfo:\n{{ $json.info }}"}]}},"credentials":{"openAiApi":{"id":"HsaKWYEwVbgIzutr","name":"SEO - Personal"}},"typeVersion":1.8},{"id":"787cea83-903f-430d-ab50-d678ba2da189","name":"notion","type":"n8n-nodes-base.httpRequest","position":[860,1640],"parameters":{"url":"=https://api.notion.com/v1/blocks/{{ $('Make Notion Page').item.json.id }}/children","method":"PATCH","options":{},"jsonBody":"={{ $json}}","sendBody":true,"specifyBody":"json","authentication":"predefinedCredentialType","nodeCredentialType":"notionApi"},"credentials":{"notionApi":{"id":"MXRS54gPY53mrd7v","name":"Mahmoud"}},"retryOnFail":false,"typeVersion":4.2},{"id":"f74fd145-7d53-4770-ac82-3466840a5eac","name":"Make Notion Page","type":"n8n-nodes-base.notion","position":[120,-280],"parameters":{"title":"={{ $('On form submission').item.json.KW }}","options":{},"resource":"databasePage","databaseId":{"__rl":true,"mode":"list","value":"1dbea3c3-9af3-80ac-aba0-fdf3c18a7119","cachedResultUrl":"https://www.notion.so/1dbea3c39af380acaba0fdf3c18a7119","cachedResultName":"Articles_Tst"},"propertiesUi":{"propertyValues":[{"key":"Time|rich_text","textContent":"={{new Date().toLocaleString('en-EG', { timeZone: 'Africa/Cairo' })}}"}]}},"credentials":{"notionApi":{"id":"MXRS54gPY53mrd7v","name":"Mahmoud"}},"typeVersion":2.2},{"id":"073990ce-477c-4fc4-bbe8-aad4737678a4","name":"Edit Fields1","type":"n8n-nodes-base.set","position":[220,1620],"parameters":{"options":{},"assignments":{"assignments":[{"id":"f993ab57-326e-4a4c-a8ef-a6324bab994d","name":"content","type":"string","value":"={{ $json.message.content }}"}]}},"typeVersion":3.4},{"id":"9db38150-7bee-4066-9bdb-017775815c23","name":"Code","type":"n8n-nodes-base.code","position":[680,1620],"parameters":{"jsCode":"// Get raw text from chatInput\nconst rawText = $input.first().json.content;\nconst lines = rawText.split(\"\\n\");\n\n// Function to parse bold and links\nconst createRichText = (text) => {\n  const linkRegex = /\\[([^\\]]+)\\]\\(([^)]+)\\)/g;\n  const boldRegex = /\\*\\*(.*?)\\*\\*/g;\n  let result = [];\n  let lastIndex = 0;\n  let match;\n\n  // أولا: روابط\n  while ((match = linkRegex.exec(text)) !== null) {\n    // أي نص قبل الرابط\n    if (match.index > lastIndex) {\n      result.push(...parseBold(text.substring(lastIndex, match.index)));\n    }\n    // إضافة الرابط كـ Anchor\n    result.push({\n      type: \"text\",\n      text: { content: match[1], link: { url: match[2] } },\n      annotations: { bold: false, italic: false, strikethrough: false, underline: false, code: false, color: \"default\" },\n      plain_text: match[1],\n      href: match[2]\n    });\n    lastIndex = match.index + match[0].length;\n  }\n  // الباقي بعد آخر رابط\n  if (lastIndex < text.length) {\n    result.push(...parseBold(text.substring(lastIndex)));\n  }\n  return result.length ? result : [{ type: \"text\", text: { content: text }, annotations: { bold: false, italic: false, strikethrough: false, underline: false, code: false, color: \"default\" }, plain_text: text, href: null }];\n};\n\n// دالة bold فقط (تُستخدم داخل الدالة أعلاه)\nfunction parseBold(text) {\n  const boldRegex = /\\*\\*(.*?)\\*\\*/g;\n  let parts = [];\n  let lastIndex = 0;\n  let match;\n  while ((match = boldRegex.exec(text)) !== null) {\n    if (match.index > lastIndex) {\n      parts.push({\n        type: \"text\",\n        text: { content: text.substring(lastIndex, match.index) },\n        annotations: { bold: false, italic: false, strikethrough: false, underline: false, code: false, color: \"default\" },\n        plain_text: text.substring(lastIndex, match.index),\n        href: null\n      });\n    }\n    parts.push({\n      type: \"text\",\n      text: { content: match[1] },\n      annotations: { bold: true, italic: false, strikethrough: false, underline: false, code: false, color: \"default\" },\n      plain_text: match[1],\n      href: null\n    });\n    lastIndex = match.index + match[0].length;\n  }\n  if (lastIndex < text.length) {\n    parts.push({\n      type: \"text\",\n      text: { content: text.substring(lastIndex) },\n      annotations: { bold: false, italic: false, strikethrough: false, underline: false, code: false, color: \"default\" },\n      plain_text: text.substring(lastIndex),\n      href: null\n    });\n  }\n  return parts.length ? parts : [{ type: \"text\", text: { content: text }, annotations: { bold: false, italic: false, strikethrough: false, underline: false, code: false, color: \"default\" }, plain_text: text, href: null }];\n}\n\n// Block constructors\nconst createHeading = (text, level = 1) => ({\n  object: \"block\",\n  type: `heading_${level}`,\n  [`heading_${level}`]: { rich_text: createRichText(text) }\n});\n\nconst createParagraph = (text) => ({\n  object: \"block\",\n  type: \"paragraph\",\n  paragraph: { rich_text: createRichText(text) }\n});\n\nconst createBulletListItem = (text) => ({\n  object: \"block\",\n  type: \"bulleted_list_item\",\n  bulleted_list_item: { rich_text: createRichText(text) }\n});\n\nconst createNumberedListItem = (text) => {\n  let cleanedText = text.replace(/^\\d+\\.\\s*/, \"\").trim();\n  return {\n    object: \"block\",\n    type: \"numbered_list_item\",\n    numbered_list_item: { rich_text: createRichText(cleanedText) }\n  };\n};\n\n// Main parsing\nlet blocks = [];\nlet paragraphContent = [];\n\nfor (let line of lines) {\n  line = line.trim();\n\n  if (line.startsWith(\"# \")) {\n    if (paragraphContent.length > 0) {\n      blocks.push(createParagraph(paragraphContent.join(\"\\n\\n\")));\n      paragraphContent = [];\n    }\n    blocks.push(createHeading(line.replace(\"# \", \"\"), 1));\n  }\n  else if (line.startsWith(\"## \")) {\n    if (paragraphContent.length > 0) {\n      blocks.push(createParagraph(paragraphContent.join(\"\\n\\n\")));\n      paragraphContent = [];\n    }\n    blocks.push(createHeading(line.replace(\"## \", \"\"), 2));\n  }\n  else if (line.startsWith(\"### \")) {\n    if (paragraphContent.length > 0) {\n      blocks.push(createParagraph(paragraphContent.join(\"\\n\\n\")));\n      paragraphContent = [];\n    }\n    blocks.push(createHeading(line.replace(\"### \", \"\"), 3));\n  }\n  else if (line.match(/^\\d+\\./)) {\n    if (paragraphContent.length > 0) {\n      blocks.push(createParagraph(paragraphContent.join(\"\\n\\n\")));\n      paragraphContent = [];\n    }\n    blocks.push(createNumberedListItem(line));\n  }\n  else if (line.startsWith(\"- \")) {\n    if (paragraphContent.length > 0) {\n      blocks.push(createParagraph(paragraphContent.join(\"\\n\\n\")));\n      paragraphContent = [];\n    }\n    blocks.push(createBulletListItem(line.replace(\"- \", \"\").trim()));\n  }\n  else if (line.length > 0) {\n    paragraphContent.push(line);\n  }\n  else if (line.length === 0 && paragraphContent.length > 0) {\n    blocks.push(createParagraph(paragraphContent.join(\"\\n\\n\")));\n    paragraphContent = [];\n  }\n}\n\n// في نهاية الملف: إذا فيه محتوى متراكم لم يُدفع بعد\nif (paragraphContent.length > 0) {\n  blocks.push(createParagraph(paragraphContent.join(\"\\n\\n\")));\n}\n\n// **النقطة المهمة:**\n// في n8n يجب أن يكون الخرج مصفوفة من الكائنات، كل كائن يُمثل بند (block)\n// مثال: [{json: {...}}, {json: {...}}, ...]\nreturn [{ json: { children: blocks } }];"},"typeVersion":2},{"id":"c48f41d3-e3f6-4c17-9056-89669032fdb5","name":"Form","type":"n8n-nodes-base.form","position":[1000,1440],"webhookId":"e0df8b70-97d9-46c0-8975-339ccd473e2a","parameters":{"operation":"completion","resumeUnit":"minutes","redirectUrl":"={{ $('Make Notion Page').item.json.url }}","respondWith":"redirect","resumeAmount":2,"limitWaitTime":true},"typeVersion":1},{"id":"bb916a02-687f-4e8f-bad8-92e342f5c40d","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-20,1400],"parameters":{"color":4,"width":1400,"height":460,"content":"## Saving The Article\n\n"},"typeVersion":1},{"id":"f2179207-c5d1-457d-bbf5-54d636fe3715","name":"Loop Over Items","type":"n8n-nodes-base.splitInBatches","position":[440,1560],"parameters":{"options":{}},"typeVersion":3},{"id":"f37f4950-eda7-42cf-a788-eb2903ad303a","name":"People_Also_Ask","type":"n8n-nodes-base.httpRequest","position":[440,200],"parameters":{"url":"https://api.dataforseo.com/v3/serp/google/organic/live/advanced","method":"POST","options":{},"jsonBody":"=[\n  {\n    \"language_code\": \"ar\",\n    \"location_code\": 2682,\n    \"keyword\": \"{{ $('On form submission').item.json.KW }}\"\n  }\n] ","sendBody":true,"specifyBody":"json","authentication":"genericCredentialType","genericAuthType":"httpBasicAuth"},"credentials":{"httpBasicAuth":{"id":"UH5Ctju6gOKe9sFI","name":"DataForSEO"}},"typeVersion":4.2},{"id":"543eeb8a-d160-4865-a057-6495db437cf3","name":"Filter_Q&A","type":"n8n-nodes-base.code","position":[660,200],"parameters":{"jsCode":"const items = $json.tasks[0].result[0].items;\nconst paa = items.find(item => item.type === 'people_also_ask');\n\n// تأكد من وجود البيانات\nif (!paa || !paa.items) {\n  return [];\n}\n\n// ضُم السؤال والإجابة في String واحد\nreturn paa.items.map(el => {\n  const question = el.title || \"\";\n  const answer = (el.expanded_element && el.expanded_element[0]) ? el.expanded_element[0].description : \"\";\n  return { \n    FAQ: `سؤال: ${question} | إجابة: ${answer}` \n  };\n});\n"},"typeVersion":2},{"id":"18d9ce34-71e8-469a-b2df-40953477b38a","name":"Gather_Q&A","type":"n8n-nodes-base.aggregate","position":[880,200],"parameters":{"options":{},"fieldsToAggregate":{"fieldToAggregate":[{"fieldToAggregate":"FAQ"}]}},"typeVersion":1},{"id":"27064bd4-e37b-48e2-b005-c9b1221882cb","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[300,100],"parameters":{"width":880,"height":280,"content":"## FAQs From People_Also_Ask"},"typeVersion":1},{"id":"397bedb5-665b-4ef6-b997-6e95c045cb1f","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-1160,-360],"parameters":{"color":5,"width":820,"height":2240,"content":"### 🔸 On form submission (Form Trigger)\n\n- **Purpose:** Starts the workflow when a user submits the article-writing form.\n\n• **Details:**\n\n- Collects \"KW\" (keyword) and optionally \"Article's Title\".\n- Triggered by a webhook; initiates the rest of the automation.\n    \n    • **Tip:** Edit form fields here if you want to collect additional info from users.\n    \n\n---\n\n### 🔸 Make Notion Page (Notion)\n\n- **Purpose:** Creates a new page in your Notion database to store the article.\n\n• **Details:**\n\n- Uses the keyword as the page title.\n- Adds the current date/time as a property.\n- Requires Notion API credentials and a database ID.\n    \n    • **Tip:** Ensure Notion database properties match what's used in this node.\n    \n\n---\n\n### 🔸 Prmopts For Search (OpenAI GPT4.1)\n\n- **Purpose:** Generates three deep research prompts about the keyword to guide AI-powered research.\n\n• **Details:**\n\n- Uses a structured system message to get prompts from GPT, each from a different angle.\n- Prompts are written in English for Perplexity/Sonar AI research.\n    \n    • **Tip:** The quality of these prompts directly impacts the article depth; edit the system message to customize research angles.\n    \n\n---\n\n### 🔸 Split Out (Split Out Node)\n\n- **Purpose:** Splits out each individual research prompt from the list for processing.\n\n• **Details:**\n\n- Ensures each prompt can be handled by subsequent nodes one at a time.\n\n---\n\n### 🔸 Sonar - Search (Perplexity/Sonar)\n\n- **Purpose:** Conducts AI-powered research for each generated prompt.\n\n• **Details:**\n\n- Sends the prompt to Perplexity/Sonar (via OpenRouter) and gets back detailed answers.\n- Requires OpenRouter API key.\n    \n    • **Tip:** Change model or provider here for different research results.\n    \n\n---\n\n### 🔸 Aggregate (Aggregate Node)\n\n- **Purpose:** Collects all research responses into a single structured object for use in outlining.\n\n• **Details:**\n\n- Aggregates content from all Sonar research responses.\n\n---\n\n### 🔸 People_Also_Ask (HTTP Request - DataForSEO)\n\n- **Purpose:** Gathers related questions (People Also Ask) from Google for the keyword.\n\n• **Details:**\n\n- Sends keyword to DataForSEO API (Arabic, Saudi location) and retrieves related FAQ.\n- Requires DataForSEO account and API credentials.\n    \n    • **Tip:** You can modify location/language codes to target different audiences.\n    \n\n---\n\n### 🔸 Filter_Q&A (Code Node)\n\n- **Purpose:** Extracts questions and answers from the People Also Ask API response.\n\n• **Details:**\n\n- Parses API JSON and creates a neat array of Q&A pairs for the article’s FAQ section.\n\n---\n\n### 🔸 Gather_Q&A (Aggregate Node)\n\n- **Purpose:** Combines all Q&A pairs into one structure for easier use in the outline and article.\n\n• **Details:**\n\n- Makes sure all extracted FAQs are grouped for easy reference.\n\n---\n\n### 🔸 Make An Outline (OpenAI GPT4.1)\n\n- **Purpose:** Uses all research and FAQ data to generate a complete SEO-optimized article outline in Arabic.\n\n• **Details:**\n\n- Provides a JSON outline: H2/H3 structure, detailed info for each section, and FAQ integration.\n- Strongly guided by system prompt for consistent structure.\n    \n    • **Tip:** Editing the prompt here lets you control article structure or depth.\n    \n\n---\n\n### 🔸 Split Out1 (Split Out Node)\n\n- **Purpose:** Splits the JSON outline so each section (H2/H3/info) can be handled individually.\n\n• **Details:**\n\n- Enables article writing to proceed section-by-section.\n\n---\n\n### 🔸 Writing The Article (OpenAI GPT4.1)\n\n- **Purpose:** Writes each article section in Arabic using the H2/H3/info for that section only.\n\n• **Details:**\n\n- Enforces structure and SEO, strictly using only provided facts (no invented info).\n- Tone and style rules included in the system prompt.\n    \n    • **Tip:** Modify the system prompt to adjust tone, voice, or writing guidelines.\n    \n\n---\n\n### 🔸 Edit Fields1 (Set Node)\n\n- **Purpose:** Prepares the AI-written content for formatting and saving.\n\n• **Details:**\n\n- Maps the content into a new field (\"content\") for further processing.\n\n---\n\n### 🔸 Loop Over Items (Split In Batches)\n\n- **Purpose:** Loops through each article section for batch processing and saving.\n\n• **Details:**\n\n- Ensures every section is sent in order and can be processed reliably.\n\n---\n\n### 🔸 Code (Rich Text → Notion Blocks)\n\n- **Purpose:** Converts AI-generated Markdown into Notion’s structured block format (headings, bullets, paragraphs).\n\n• **Details:**\n\n- Parses Markdown and creates rich Notion block objects, supporting bold text and links.\n- Handles special formatting for lists and headings.\n\n---\n\n### 🔸 notion (HTTP Request - Notion API PATCH)\n\n- **Purpose:** Appends the formatted article blocks to the existing Notion page.\n\n• **Details:**\n\n- Sends all blocks as children to the page created earlier.\n- Requires Notion API credentials.\n\n---\n\n### 🔸 Form (End/Redirect)\n\n- **Purpose:** Ends the workflow and redirects the user back to their Notion page to view the final article.\n\n• **Details:**\n\n- Waits for saving to complete, then sends the user to the Notion page URL.\n    \n    • **Tip:** You can change this to redirect elsewhere or display a success message if needed.\n    \n\n---\n\n### **General Assumptions and Warnings:**\n\n- **Credentials:** All external API nodes (OpenAI, Notion, DataForSEO, OpenRouter) require valid credentials set up in n8n.\n- **Language:** The core workflow is for Arabic content but is customizable for other languages with prompt and setting tweaks."},"typeVersion":1}],"active":true,"settings":{"executionOrder":"v1"},"versionId":"ca8fd388-8194-4185-9a84-8a1842c2fbec","connections":{"Code":{"main":[[{"node":"notion","type":"main","index":0}]]},"notion":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Aggregate":{"main":[[{"node":"People_Also_Ask","type":"main","index":0}]]},"Split Out":{"main":[[{"node":"Sonar - Search","type":"main","index":0}]]},"Filter_Q&A":{"main":[[{"node":"Gather_Q&A","type":"main","index":0}]]},"Gather_Q&A":{"main":[[{"node":"Make An Outline","type":"main","index":0}]]},"Split Out1":{"main":[[{"node":"Writing The Article","type":"main","index":0}]]},"Edit Fields1":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Sonar - Search":{"main":[[{"node":"Aggregate","type":"main","index":0}]]},"Loop Over Items":{"main":[[{"node":"Form","type":"main","index":0}],[{"node":"Code","type":"main","index":0}]]},"Make An Outline":{"main":[[{"node":"Split Out1","type":"main","index":0}]]},"People_Also_Ask":{"main":[[{"node":"Filter_Q&A","type":"main","index":0}]]},"Make Notion Page":{"main":[[{"node":"Prmopts For Search","type":"main","index":0}]]},"On form submission":{"main":[[{"node":"Make Notion Page","type":"main","index":0}]]},"Prmopts For Search":{"main":[[{"node":"Split Out","type":"main","index":0}]]},"Writing The Article":{"main":[[{"node":"Edit Fields1","type":"main","index":0}]]}}}


name: Automate LinkedIn Profile Search & Cold Email Outreach with OpenAI and Hunter
author_name: Abhijay Vuyyuru
author_username: abhijayvuyyuru
categories: []
created_at: 2025-06-10T01:46:22.975Z
updated_at: 2025-06-10T01:46:22.975Z
url: https://n8n.io/workflows/4831
scraped_at: 2025-07-06 21:16:30
description:
  Problem

  🚨 LinkedIn search is BROKEN. 


  I waste hours on LinkedIn manually filtering profiles, reading summaries, hoping they’d reply—tedious, frustrating, inefficient.

  I wish LinkedIn had built an agent that would get me to the right profile with one click!

  If only I could just type:
  "Product managers working on YouTube Shorts' generative AI features."

  and seconds later, have LinkedIn URLs, names, emails, and full context about them.

  Introducing LinkGPT, a LinkedIn Agent, an automated agentic workflow powered by n8n.

  Prerequisites: 
  Required accounts/API keys for Hunter.io, Google, and OpenAI.

  This would be helpful for:

  🎯 Job Seekers: Skip ATS, email hiring managers directly ( I wish I had this when I was recruiting!)

  🎯 Recruiters: Reach your dream candidates first

  🎯 Founders & Sales Teams: Share your demos with customers directly (this does NOT use the expensive Sales Navigator API)

  Step-by-step workflow:

  Takes 5-10 minutes to setup.

  Generate a Boolean search string for LinkedIn profiles.
  Perform authenticated Google searches using your query.
  Extract LinkedIn URLs and workplace context from the search results.
  Use OpenAI to extract first name, last name, and domain name from the context.
  Use Hunter.io to find emails of the contacts.
  Append all results to your connected Google Sheet. Columns: first_name, last_name, domain_name, email, context



  I put together a clear, step-by-step guide on setting this up yourself.

  Sample Query

  Sample:

  Input: "I am headed to NYC later this month, whom should I meet with that works in product management for gen AI products?"

  Output: List of 10 contacts with first name, last name, workplace, email address and context about them so you can email them. 

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

workflow_json:
  {"id":"3hkkh26rGduY5nsP","meta":{"instanceId":"7b22476bf9699de09fe66fed92056e8ae798418cc9901fa9bd85bb46439116b8"},"name":"LinkGPT","tags":[{"id":"V4LdVOYIGIbfdqvb","name":"linkedin","createdAt":"2025-06-11T18:52:18.612Z","updatedAt":"2025-06-11T18:52:18.612Z"},{"id":"yt7Z3T0SDl1Coo7S","name":"hunter","createdAt":"2025-06-11T18:52:25.423Z","updatedAt":"2025-06-11T18:52:25.423Z"},{"id":"qlvLkg4Mxoeos0VK","name":"cold email","createdAt":"2025-06-11T18:52:31.368Z","updatedAt":"2025-06-11T18:52:31.368Z"}],"nodes":[{"id":"95580f35-3039-49e0-9dde-2218080c6c1d","name":"Wait","type":"n8n-nodes-base.wait","position":[760,880],"webhookId":"eadafb7f-61bf-4648-bcdf-b1ffec403f85","parameters":{},"typeVersion":1.1},{"id":"e7ccc8dc-a658-499a-ab69-beed20b418c2","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[440,400],"webhookId":"1fed76d2-a19a-4c44-aa3d-1bd0aef788bb","parameters":{},"typeVersion":1.1},{"id":"634d67e1-d251-4f9e-994b-642c3346734e","name":"Create a new sheet","type":"n8n-nodes-base.googleSheets","position":[1120,400],"parameters":{},"typeVersion":4.5},{"id":"94a6bc5b-39a7-477b-81ef-ffea2e62284c","name":"Add columns to new sheet","type":"n8n-nodes-base.googleSheets","position":[760,640],"parameters":{},"typeVersion":4.5},{"id":"260d8a51-0708-484b-98ed-9872f110bc2c","name":"set page number for google search","type":"n8n-nodes-base.code","position":[1060,640],"parameters":{},"typeVersion":2},{"id":"92461c5c-1c76-4c0e-b235-f41f952af35e","name":"Google Boolean Search","type":"n8n-nodes-base.httpRequest","position":[1080,880],"parameters":{},"typeVersion":4.2},{"id":"91016b0f-78f2-44a3-900a-c072d7e9ff53","name":"If desired results not reached","type":"n8n-nodes-base.if","position":[400,900],"parameters":{},"typeVersion":2.2},{"id":"235a74ca-b58a-46f4-8de4-a08a83424efc","name":"Appends the results to the sheet","type":"n8n-nodes-base.googleSheets","position":[740,1360],"parameters":{},"typeVersion":4.5},{"id":"3e24720c-39a8-4329-ae6e-c6e01b61b435","name":"Code","type":"n8n-nodes-base.code","position":[4960,600],"parameters":{},"typeVersion":2},{"id":"1db7dcd7-cf17-47f0-b44f-cd612797c88b","name":"Extracts fname, lname, domainname","type":"n8n-nodes-base.code","position":[1080,1140],"parameters":{},"typeVersion":2},{"id":"18bd422d-6fc0-4442-9b2f-a34cd14d45e8","name":"Extracts all linkedin urls and workplace context from the google http response","type":"n8n-nodes-base.code","position":[400,1140],"parameters":{},"typeVersion":2},{"id":"a2c6a9e3-3136-40cc-a58e-23c0b5e78999","name":"Adds 10 to start - Go to next page","type":"n8n-nodes-base.code","position":[100,900],"parameters":{},"typeVersion":2},{"id":"52918647-57a2-4d1c-903c-4cb35429eb4c","name":"Hunter","type":"n8n-nodes-base.hunter","position":[380,1360],"parameters":{},"executeOnce":true,"typeVersion":1},{"id":"140bc853-3ed4-4403-8e98-e24899401633","name":"Generate a Boolean Search String","type":"@n8n/n8n-nodes-langchain.openAi","position":[740,400],"parameters":{},"retryOnFail":false,"typeVersion":1.8},{"id":"85e4341c-50a0-4123-b17f-072898de528a","name":"Extract Contact Details","type":"@n8n/n8n-nodes-langchain.openAi","position":[680,1140],"parameters":{},"typeVersion":1.8},{"id":"79559a98-f857-4c24-a351-0856afa88932","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[1240,880],"parameters":{"content":""},"typeVersion":1},{"id":"e56703f5-b316-41e1-861f-ec4835155df8","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[660,1060],"parameters":{"content":""},"typeVersion":1},{"id":"185dc39c-4c61-445d-9981-30edcc10149a","name":"Columns to add: linkedin_url, first_name, last_name, email, context, domain","type":"n8n-nodes-base.code","position":[420,640],"parameters":{},"typeVersion":2},{"id":"c54825fe-cda7-48af-9d9d-5307ac51bbad","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[720,300],"parameters":{"content":""},"typeVersion":1},{"id":"fa062c54-bdf5-4518-8300-7876657de377","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[640,820],"parameters":{"content":""},"typeVersion":1},{"id":"42eb75e5-6c9e-4890-9248-7051a514ccae","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[60,760],"parameters":{"content":""},"typeVersion":1},{"id":"b180f392-9809-45a8-97f4-3c9a3c0368e1","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[180,1280],"parameters":{"content":""},"typeVersion":1}],"active":true,"settings":{},"versionId":"19a94125-3580-413b-83dd-3ec7a769e021","connections":{"Code":{"main":[[]]},"Wait":{"main":[[{"node":"Google Boolean Search","type":"main","index":0}]]},"Hunter":{"main":[[{"node":"Appends the results to the sheet","type":"main","index":0}]]},"Create a new sheet":{"main":[[{"node":"Columns to add: linkedin_url, first_name, last_name, email, context, domain","type":"main","index":0}]]},"Google Boolean Search":{"main":[[{"node":"Extracts all linkedin urls and workplace context from the google http response","type":"main","index":0}]]},"Extract Contact Details":{"main":[[{"node":"Extracts fname, lname, domainname","type":"main","index":0}]]},"Add columns to new sheet":{"main":[[{"node":"set page number for google search","type":"main","index":0}]]},"When chat message received":{"main":[[{"node":"Generate a Boolean Search String","type":"main","index":0}]]},"If desired results not reached":{"main":[[{"node":"Wait","type":"main","index":0}],[]]},"Appends the results to the sheet":{"main":[[{"node":"Adds 10 to start - Go to next page","type":"main","index":0}]]},"Generate a Boolean Search String":{"main":[[{"node":"Create a new sheet","type":"main","index":0}]]},"Extracts fname, lname, domainname":{"main":[[{"node":"Hunter","type":"main","index":0}]]},"set page number for google search":{"main":[[{"node":"If desired results not reached","type":"main","index":0}]]},"Adds 10 to start - Go to next page":{"main":[[{"node":"If desired results not reached","type":"main","index":0}]]},"Columns to add: linkedin_url, first_name, last_name, email, context, domain":{"main":[[{"node":"Add columns to new sheet","type":"main","index":0}]]},"Extracts all linkedin urls and workplace context from the google http response":{"main":[[{"node":"Extract Contact Details","type":"main","index":0}]]}}}


name: Multiple Websites Monitoring with Notifications including Phone Calls
author_name: InfyOm Technologies
author_username: infyom
categories: []
created_at: 2025-06-10T05:10:57.984Z
updated_at: 2025-06-10T05:10:57.984Z
url: https://n8n.io/workflows/4833
scraped_at: 2025-07-06 21:16:30
description:
  ✅ What problem does this workflow solve?
  Automatically monitor multiple websites every 5 minutes, log downtime, notify your team instantly via multiple channels, and track uptime/downtime in a Google Sheet—without relying on expensive monitoring tools.

  ⚙️ What does this workflow do?

  Triggers every 5 minutes to monitor website health.
  Fetches a list of website URLs from a Google Sheet.
  Checks the status of each website one by one.
  Sends instant alerts if a website is down (Email, Slack, Telegram, Voice Call).
  Logs downtime events in Google Sheets.
  Tracks when websites are back up and updates the log.
  Sends recovery notifications when a site is live again (Email, Slack, Telegram).

  🔧 Setup

  📄 Google Sheets Setup
  Sheet 1: List of website URLs to monitor.
  Sheet 2: Log to store uptime/downtime records.
  Sample Format: https://docs.google.com/spreadsheets/d/1_VVpkIvpYQigw5q0KmPXUAC2aV2rk1nRQLQZ7YK2KwY/edit?usp=sharing

  ✉️ Gmail, Slack & Telegram Setup
  Connect Gmail, Slack, and Telegram to n8n.
  Configure each service with proper credentials or OAuth.

  📞 Vapi (Voice Call) Setup
  Create a Vapi account.
  Generate an API key.
  Configure API Parameters (vapi_api_key, assistant_id, number, phone_number_id) on VAPI Node.
  Insert the First Message specified in the Workflow.

  🧠 How it Works

  ⏱ 1. Scheduled Monitoring
  A Schedule Trigger runs the workflow every 5 minutes. It reads the list of URLs from the Google Sheet and loops through each one.

  🌍 2. Website Health Check
  Each website is pinged to check if it’s online.

  🔴 3. If Website is Down:
  It verifies if a downtime record already exists.
  If not, it:
    Adds a new row in the Google Sheet with the timestamp.
    Sends notifications via:
      📧 Email
      💬 Slack
      📲 Telegram
      📞 Voice Call via Vapi

  🟢 4. If Website is Back Up:
  It fetches the matching downtime record.
  Updates the sheet with:
    ✅ Uptime timestamp
    ⏱ Total downtime duration
  Sends recovery notifications via:
    📧 Email
    💬 Slack
    📲 Telegram  
  (No phone call is made for uptime.)

  👤 Who can use it?

  This is perfect for:
  🚀 Startups
  👨‍💻 Freelance Developers
  🛠 SaaS Product Owners
  🖥 IT/DevOps Teams

  If you're looking to replace tools like UptimeRobot, Pingdom, or StatusCake, this no-code solution gives you full control, customization, and cost-efficiency.

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

workflow_json:
  {"id":"Cki3H3LKIaoXKG1r","meta":{"instanceId":"fcb622cbd5234c565b9b78babeaf0ea2455df9d2aad0d1adff7c1ef99583e685","templateCredsSetupCompleted":true},"name":"Website Down Time Monitoring for n8n","tags":[],"nodes":[{"id":"89285dd4-89d7-4726-b2d5-70b919d1738a","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[-1120,2425],"parameters":{"rule":{"interval":[{}]}},"typeVersion":1.2},{"id":"f624f586-07eb-4e5e-b748-9e5605e2b102","name":"Loop Over Items","type":"n8n-nodes-base.splitInBatches","position":[-680,2425],"parameters":{"options":{}},"typeVersion":3},{"id":"4bf3a7b5-62a1-402d-bf22-3222d1767a67","name":"Check website status","type":"n8n-nodes-base.httpRequest","position":[-460,1900],"parameters":{"url":"={{ $json['Website URL'] }}","options":{"timeout":5000,"response":{"response":{"fullResponse":true}}}},"typeVersion":4.2},{"id":"6f17ae5e-5451-4b78-99b1-20fa16255ead","name":"Website URLs","type":"n8n-nodes-base.googleSheets","position":[-900,2425],"parameters":{"options":{},"sheetName":{"__rl":true,"mode":"list","value":959117872,"cachedResultUrl":"https://docs.google.com/spreadsheets/d/1_VVpkIvpYQigw5q0KmPXUAC2aV2rk1nRQLQZ7YK2KwY/edit#gid=959117872","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1_VVpkIvpYQigw5q0KmPXUAC2aV2rk1nRQLQZ7YK2KwY","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1_VVpkIvpYQigw5q0KmPXUAC2aV2rk1nRQLQZ7YK2KwY/edit?usp=drivesdk","cachedResultName":"Website Moniter"}},"credentials":{"googleSheetsOAuth2Api":{"id":"AjFU8eA6fXFRo47v","name":"Google Sheets account"}},"executeOnce":false,"typeVersion":4.6},{"id":"9a429a0a-06f0-49ca-9d6a-d2bfa55a996c","name":"Get Active Down Record","type":"n8n-nodes-base.googleSheets","position":[-20,1800],"parameters":{"options":{},"filtersUI":{"values":[{"lookupValue":"={{ $('Loop Over Items').item.json['Website URL'] }}","lookupColumn":"Website URL"},{"lookupColumn":"Up Time"}]},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1_VVpkIvpYQigw5q0KmPXUAC2aV2rk1nRQLQZ7YK2KwY/edit#gid=0","cachedResultName":"Sheet2"},"documentId":{"__rl":true,"mode":"list","value":"1_VVpkIvpYQigw5q0KmPXUAC2aV2rk1nRQLQZ7YK2KwY","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1_VVpkIvpYQigw5q0KmPXUAC2aV2rk1nRQLQZ7YK2KwY/edit?usp=drivesdk","cachedResultName":"Website Moniter"}},"credentials":{"googleSheetsOAuth2Api":{"id":"AjFU8eA6fXFRo47v","name":"Google Sheets account"}},"executeOnce":false,"typeVersion":4.6,"alwaysOutputData":true},{"id":"57f054ee-8f40-45a9-9da9-3befd1ac489c","name":"Update Uptime and Total Downtime","type":"n8n-nodes-base.googleSheets","position":[420,1800],"parameters":{"columns":{"value":{"Up Time":"={{ new Date().toLocaleTimeString('en-GB', { hour12: false }) }}","row_number":"={{ $json.row_number }}","Website URL":"={{ $json['Website URL'] }}","Total downtime":"={{(() => {\n  const downTimeStr = $input.first().json['Down Time'];\n\n  // Get current time in HH:MM:SS format\n  const now = new Date();\n  const upTimeStr = now.toLocaleTimeString('en-GB', { hour12: false });\n\n  function parseTime(timeStr) {\n    const [h, m, s] = timeStr.split(\":\").map(Number);\n    const date = new Date();\n    date.setHours(h, m, s, 0);\n    return date;\n  }\n\n  const downTime = parseTime(downTimeStr);\n  const upTime = parseTime(upTimeStr);\n\n  // Handle overnight scenario\n  if (upTime < downTime) {\n    upTime.setDate(upTime.getDate() + 1);\n  }\n\n  const diffMs = upTime - downTime;\n  const totalMinutes = Math.floor(diffMs / 60000);\n  const hours = Math.floor(totalMinutes / 60);\n  const minutes = totalMinutes % 60;\n  const seconds = Math.floor((diffMs % 60000) / 1000);\n\n  return `${hours}h ${minutes}m ${seconds}s`;\n})()}}"},"schema":[{"id":"Website URL","type":"string","display":true,"removed":false,"required":false,"displayName":"Website URL","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Down Time","type":"string","display":true,"removed":true,"required":false,"displayName":"Down Time","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Up Time","type":"string","display":true,"removed":false,"required":false,"displayName":"Up Time","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Total downtime","type":"string","display":true,"removed":false,"required":false,"displayName":"Total downtime","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/1_VVpkIvpYQigw5q0KmPXUAC2aV2rk1nRQLQZ7YK2KwY/edit#gid=0","cachedResultName":"Sheet2"},"documentId":{"__rl":true,"mode":"list","value":"1_VVpkIvpYQigw5q0KmPXUAC2aV2rk1nRQLQZ7YK2KwY","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1_VVpkIvpYQigw5q0KmPXUAC2aV2rk1nRQLQZ7YK2KwY/edit?usp=drivesdk","cachedResultName":"Website Moniter"}},"credentials":{"googleSheetsOAuth2Api":{"id":"AjFU8eA6fXFRo47v","name":"Google Sheets account"}},"executeOnce":false,"typeVersion":4.6,"alwaysOutputData":true},{"id":"e6575156-1a32-429a-9ee7-deef3c4f863d","name":"Find Existing Record","type":"n8n-nodes-base.code","position":[200,2200],"parameters":{"jsCode":"let hasIncompleteRecord = false;\n\nfor (const item of $input.all()) {\n  const url = item.json['Website URL']?.trim();\n  const downTime = item.json['Down Time']?.trim();\n  const upTime = item.json['Up Time']?.trim();\n  const totalDowntime = item.json['Total downtime']?.trim();\n\n  if (url && downTime && (!upTime || !totalDowntime)) {\n    hasIncompleteRecord = true;\n  }\n}\n\nreturn [\n  {\n    json: {\n      status: hasIncompleteRecord ? \"yes\" : \"no\",\n      websites: $input.first().json['Website URL']\n    }\n  }\n];\n"},"typeVersion":2},{"id":"220717dd-659a-44af-98f8-3e03aa0021ea","name":"Add Downtime Record","type":"n8n-nodes-base.googleSheets","position":[640,2200],"parameters":{"columns":{"value":{"Down Time":"={{ new Date().toLocaleTimeString('en-GB', { hour12: false }) }}","Website URL":"={{ $('Loop Over Items').item.json[\"Website URL\"] }}"},"schema":[{"id":"Website URL","type":"string","display":true,"removed":false,"required":false,"displayName":"Website URL","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Down Time","type":"string","display":true,"removed":false,"required":false,"displayName":"Down Time","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Up Time","type":"string","display":true,"removed":true,"required":false,"displayName":"Up Time","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Total downtime","type":"string","display":true,"removed":true,"required":false,"displayName":"Total downtime","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":["Website URL"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"append","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1_VVpkIvpYQigw5q0KmPXUAC2aV2rk1nRQLQZ7YK2KwY/edit#gid=0","cachedResultName":"Sheet2"},"documentId":{"__rl":true,"mode":"list","value":"1_VVpkIvpYQigw5q0KmPXUAC2aV2rk1nRQLQZ7YK2KwY","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1_VVpkIvpYQigw5q0KmPXUAC2aV2rk1nRQLQZ7YK2KwY/edit?usp=drivesdk","cachedResultName":"Website Moniter"}},"credentials":{"googleSheetsOAuth2Api":{"id":"AjFU8eA6fXFRo47v","name":"Google Sheets account"}},"executeOnce":false,"typeVersion":4.6},{"id":"59d163f7-771e-40e6-bf5f-e091de3233a9","name":"Notify over Phone Call","type":"n8n-nodes-base.httpRequest","position":[860,2580],"parameters":{"url":"https://api.vapi.ai/call","method":"POST","options":{},"jsonBody":"={\n  \"assistantId\": \"assistant_id\",\n  \"assistantOverrides\": {\n    \"variableValues\": {\n    \"name\":\"John\",\n    \"web_domain\":\"{{ $json['Website URL'] }}\"\n    }\n  },\n  \"customer\": {\n    \"number\": \"+919999999999\"\n  },\n  \"phoneNumberId\": \"phone_number_id\"\n}","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2,"alwaysOutputData":true},{"id":"5345ee2f-55bf-4211-bd40-286fbf522af0","name":"Check Downtime Exists","type":"n8n-nodes-base.if","position":[420,2200],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"9e5df4d3-c9fd-4311-ae97-c06fcbcc1c97","operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"yes"}]}},"typeVersion":2.2},{"id":"ef94a17c-ddd7-48f2-88a1-a0dd3790e20b","name":"Email Notification for Down","type":"n8n-nodes-base.gmail","position":[860,1975],"webhookId":"01059553-6361-4349-99c0-d6e467198e19","parameters":{"sendTo":"example@gmail.com","message":"=Hi there,\n\nThe Website {{ $json['Website URL'] }} is Down. Please take the required action as soon as possible.","options":{},"subject":"=Your site is down!!"},"credentials":{"gmailOAuth2":{"id":"IXi1kkbb2nCpoTSR","name":"Gmail account"}},"typeVersion":2.1},{"id":"e79a52cd-7ea4-41fc-80e3-82ac947d4d1f","name":"Slack Notification for Down","type":"n8n-nodes-base.slack","position":[860,2175],"webhookId":"379f0487-218b-4137-9a89-02c29f9ab48f","parameters":{"text":"=🚨 Alert:| Hi there, The {{ $json['Website URL'] }} website is currently down. Kindly look into this issue and take necessary action as soon as possible.  Thank you.","user":{"__rl":true,"mode":"list","value":"U08QEDH1YVB","cachedResultName":"mail"},"select":"user","otherOptions":{"includeLinkToWorkflow":false},"authentication":"oAuth2"},"credentials":{"slackOAuth2Api":{"id":"zPPPZzCjzqdYPosb","name":"Slack account 2"}},"typeVersion":2.3},{"id":"8203750f-b83b-4f7e-9982-69bf88e3ccb2","name":"Telegram Notification for Down","type":"n8n-nodes-base.telegram","position":[860,2375],"webhookId":"b76cf08e-146f-4dce-8b55-0467b6130b5c","parameters":{"text":"=🚨 Alert: Hi there, | The {{ $json['Website URL'] }} website is currently down. Kindly look into this issue and take necessary action as soon as possible.  Thank you.","chatId":"-1002286661825","additionalFields":{}},"credentials":{"telegramApi":{"id":"LXHr60rCVMuiROdo","name":"Telegram account 2"}},"typeVersion":1.2},{"id":"5a86f273-6c29-47c8-9c88-9f36bd56cfba","name":"Email Notification for Up","type":"n8n-nodes-base.gmail","position":[640,1600],"webhookId":"01059553-6361-4349-99c0-d6e467198e19","parameters":{"sendTo":"example@gmail.com","message":"=Hi there,\n\nWe're excited to announce that the {{ $('Website URLs').item.json['Website URL'] }} is now live!\nFeel free to visit and explore.","options":{},"subject":"=Site is now working fine."},"credentials":{"gmailOAuth2":{"id":"IXi1kkbb2nCpoTSR","name":"Gmail account"}},"typeVersion":2.1},{"id":"19a35cc4-9477-476b-973c-02ccbe4746a4","name":"Slack Notification for Up","type":"n8n-nodes-base.slack","position":[640,1800],"webhookId":"379f0487-218b-4137-9a89-02c29f9ab48f","parameters":{"text":"We're excited to announce that the {{ $('Website URLs').item.json['Website URL'] }} is now live! Feel free to visit and explore.","user":{"__rl":true,"mode":"list","value":"U08QEDH1YVB","cachedResultName":"mail"},"select":"user","otherOptions":{"includeLinkToWorkflow":false},"authentication":"oAuth2"},"credentials":{"slackOAuth2Api":{"id":"zPPPZzCjzqdYPosb","name":"Slack account 2"}},"typeVersion":2.3},{"id":"5465b80d-c302-4931-988e-f36ac48bcdef","name":"Telegram Notification for Up","type":"n8n-nodes-base.telegram","position":[640,2000],"webhookId":"b76cf08e-146f-4dce-8b55-0467b6130b5c","parameters":{"text":"We're excited to announce that the {{ $('Website URLs').item.json['Website URL'] }} is now live! Feel free to visit and explore.","chatId":"-1002286661825","additionalFields":{}},"credentials":{"telegramApi":{"id":"LXHr60rCVMuiROdo","name":"Telegram account 2"}},"typeVersion":1.2},{"id":"ddcd8c3d-a22e-4ae7-bf00-3677c6a9a10c","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-340,1460],"parameters":{"width":560,"height":280,"content":"### Website downtime monitoring with logging\nSample Sheet: https://docs.google.com/spreadsheets/d/1_VVpkIvpYQigw5q0KmPXUAC2aV2rk1nRQLQZ7YK2KwY/edit?usp=sharing\n- Sheet 1 - Add domain list for monitoring.\n- Sheet 2 - Store all downtime logs.\n\n\nCreate new assistant in Vapi and set First message as below.\n- Hello {{name}}, I'm Website Monitoring Assistant. This is a system alert. The {{web_domain}} is currently down. Please take immediate action to investigate and resolve the issue. Thank you.\n\n\n"},"typeVersion":1},{"id":"1a4b919f-6e78-48f3-968d-0caae9fe56f4","name":"If Down Record Exist","type":"n8n-nodes-base.if","position":[200,1800],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"1337beb6-7974-45ab-9fa0-93f5ce0ee7b7","operator":{"type":"boolean","operation":"false","singleValue":true},"leftValue":"={{(() => {   const data = $json;   return Object.keys(data).length === 0; })()}}","rightValue":""}]}},"typeVersion":2.2},{"id":"c60f06ef-ab17-40d1-91b7-1ed1683c9c42","name":"If Site Up","type":"n8n-nodes-base.if","position":[-240,1900],"parameters":{"conditions":{"number":[{"value1":"={{$json[\"statusCode\"]}}","value2":400,"operation":"equal"}]}},"typeVersion":1},{"id":"08a21aa6-89c6-406b-becd-43688b793b2c","name":"Get Existing Down Records","type":"n8n-nodes-base.googleSheets","position":[-20,2200],"parameters":{"options":{},"filtersUI":{"values":[{"lookupValue":"={{ $('Loop Over Items').item.json['Website URL'] }}","lookupColumn":"Website URL"}]},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1_VVpkIvpYQigw5q0KmPXUAC2aV2rk1nRQLQZ7YK2KwY/edit#gid=0","cachedResultName":"Sheet2"},"documentId":{"__rl":true,"mode":"list","value":"1_VVpkIvpYQigw5q0KmPXUAC2aV2rk1nRQLQZ7YK2KwY","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1_VVpkIvpYQigw5q0KmPXUAC2aV2rk1nRQLQZ7YK2KwY/edit?usp=drivesdk","cachedResultName":"Website Moniter"}},"credentials":{"googleSheetsOAuth2Api":{"id":"AjFU8eA6fXFRo47v","name":"Google Sheets account"}},"typeVersion":4.6,"alwaysOutputData":true}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"da032169-3ed0-4c4b-a5a9-bef39dd9bf55","connections":{"If Site Up":{"main":[[{"node":"Get Active Down Record","type":"main","index":0}],[{"node":"Get Existing Down Records","type":"main","index":0}]]},"Website URLs":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Loop Over Items":{"main":[[],[{"node":"Check website status","type":"main","index":0}]]},"Schedule Trigger":{"main":[[{"node":"Website URLs","type":"main","index":0}]]},"Add Downtime Record":{"main":[[{"node":"Email Notification for Down","type":"main","index":0},{"node":"Slack Notification for Down","type":"main","index":0},{"node":"Telegram Notification for Down","type":"main","index":0},{"node":"Notify over Phone Call","type":"main","index":0}]]},"Check website status":{"main":[[{"node":"If Site Up","type":"main","index":0}]]},"Find Existing Record":{"main":[[{"node":"Check Downtime Exists","type":"main","index":0}]]},"If Down Record Exist":{"main":[[{"node":"Update Uptime and Total Downtime","type":"main","index":0}],[{"node":"Loop Over Items","type":"main","index":0}]]},"Check Downtime Exists":{"main":[[{"node":"Loop Over Items","type":"main","index":0}],[{"node":"Add Downtime Record","type":"main","index":0}]]},"Get Active Down Record":{"main":[[{"node":"If Down Record Exist","type":"main","index":0}]]},"Notify over Phone Call":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Get Existing Down Records":{"main":[[{"node":"Find Existing Record","type":"main","index":0}]]},"Email Notification for Down":{"main":[[]]},"Slack Notification for Down":{"main":[[]]},"Telegram Notification for Up":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Telegram Notification for Down":{"main":[[]]},"Update Uptime and Total Downtime":{"main":[[{"node":"Email Notification for Up","type":"main","index":0},{"node":"Slack Notification for Up","type":"main","index":0},{"node":"Telegram Notification for Up","type":"main","index":0}]]}}}


name: Automate Gym Lead Nurturing with Facebook Ads, WhatsApp & Google Sheets Tracking
author_name: mourya
author_username: chaitanya
nodes_used: ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest"]
categories: []
created_at: 2025-06-10T06:17:05.257Z
updated_at: 2025-06-10T06:17:05.257Z
url: https://n8n.io/workflows/4834
scraped_at: 2025-07-06 21:16:30
description:
  📌 What it does:

  Captures leads from Facebook Ads

  Sends instant WhatsApp to leads

  Waits & checks for bookings

  If booked anytime during 5-day nurturing, it stops the follow-ups and sends confirmations to both lead & gym owner

  If not booked, continues to nurture daily for 5 days with reminders

workflow_json:
  {"id":"jjh7DW2zjntkc8HX","meta":{"instanceId":"7b96b092d810c2802f78805c0ebb75731d1fee5ea94ed15e682859bc5660ae38"},"name":"My workflow","tags":[],"nodes":[{"id":"a7c57dfd-6b66-49cc-9e43-133b32bf378f","name":"FB Lead Webhook","type":"n8n-nodes-base.webhook","position":[0,0],"webhookId":"68d72cbe-1ea1-4f4d-8253-aa85f9650cae","parameters":{"path":"fb-lead-webhook","options":{},"httpMethod":"POST"},"typeVersion":1},{"id":"5a625a58-bb3b-41fe-90fa-26418d322c42","name":"Add to Google Sheets","type":"n8n-nodes-base.googleSheets","position":[200,0],"parameters":{"range":"Sheet1!A:E","options":{},"sheetId":"YOUR_SHEET_ID","operation":"append"},"typeVersion":1},{"id":"3dc92c8a-3a0a-4df6-9123-2710761c112c","name":"Send WhatsApp to Lead","type":"n8n-nodes-base.httpRequest","position":[460,0],"parameters":{"url":"https://api.ultramsg.com/instanceXXXX/messages/chat","options":{},"jsonParameters":true},"typeVersion":1},{"id":"5aa94b38-440e-4d5f-b201-2d7b7f061e91","name":"Check Booking Status","type":"n8n-nodes-base.googleSheets","position":[1480,480],"parameters":{"range":"Sheet1!A:E","options":{},"sheetId":"YOUR_SHEET_ID","operation":"lookup","lookupValue":"={{$json[\"phone\"]}}","lookupColumn":"B"},"typeVersion":1},{"id":"5bb1f128-bb64-48c8-831d-4ef6cb729d35","name":"If Booked?","type":"n8n-nodes-base.if","position":[740,0],"parameters":{"conditions":{"string":[{"value1":"={{$json[\"3\"]}}","value2":"Booked","operation":"equals"}]}},"typeVersion":1},{"id":"60f0284b-74da-41de-9720-561923a838e5","name":"Send Confirmation to Lead","type":"n8n-nodes-base.httpRequest","position":[1860,180],"parameters":{"url":"https://api.ultramsg.com/instanceXXXX/messages/chat","options":{},"jsonParameters":true},"typeVersion":1},{"id":"a6de4bb6-8886-41f4-93ff-c293415077fc","name":"Notify Gym Owner","type":"n8n-nodes-base.httpRequest","position":[1820,640],"parameters":{"url":"https://api.ultramsg.com/instanceXXXX/messages/chat","options":{},"jsonParameters":true},"typeVersion":1},{"id":"c85a9561-c906-4c33-a12b-4e857ff10a90","name":"Check Booking Day 1","type":"n8n-nodes-base.googleSheets","position":[340,260],"parameters":{"range":"Sheet1!A:F","options":{},"sheetId":"your-google-sheet-id"},"typeVersion":1},{"id":"5c068bec-391d-4b70-af1e-2eca290357c2","name":"Send WhatsApp Day 1","type":"n8n-nodes-base.httpRequest","position":[560,260],"parameters":{"url":"https://api.twilio.com/2010-04-01/Accounts/YOUR_ACCOUNT_SID/Messages.json","options":{},"authentication":"basicAuth","jsonParameters":true},"typeVersion":1},{"id":"aec0b5b2-8c27-44dc-ac06-aa9706703bbe","name":"Wait Day 2","type":"n8n-nodes-base.wait","position":[80,500],"webhookId":"658b194e-3b67-4766-8fb0-a9ab7c626207","parameters":{"unit":"days"},"typeVersion":1},{"id":"73c855b2-87f9-4d54-9f35-af73571e5b22","name":"Check Booking Day 2","type":"n8n-nodes-base.googleSheets","position":[320,500],"parameters":{"range":"Sheet1!A:F","options":{},"sheetId":"your-google-sheet-id"},"typeVersion":1},{"id":"571bd904-1611-40f9-a70b-3d3d91d59ee3","name":"Send WhatsApp Day 2","type":"n8n-nodes-base.httpRequest","position":[620,500],"parameters":{"url":"https://api.twilio.com/2010-04-01/Accounts/YOUR_ACCOUNT_SID/Messages.json","options":{},"authentication":"basicAuth","jsonParameters":true},"typeVersion":1},{"id":"30a971b2-17e3-47fe-ba52-75582f6a4a7f","name":"Wait Day 3","type":"n8n-nodes-base.wait","position":[80,720],"webhookId":"176f47b4-3ffe-4c69-b983-4c4e1349d998","parameters":{"unit":"days"},"typeVersion":1},{"id":"db4ad905-1231-4aaa-a368-18aa3866add0","name":"Check Booking Day 3","type":"n8n-nodes-base.googleSheets","position":[320,720],"parameters":{"range":"Sheet1!A:F","options":{},"sheetId":"your-google-sheet-id"},"typeVersion":1},{"id":"24a82e04-81fa-44f9-9c24-7e51a6b5c4b6","name":"Send WhatsApp Day 3","type":"n8n-nodes-base.httpRequest","position":[620,720],"parameters":{"url":"https://api.twilio.com/2010-04-01/Accounts/YOUR_ACCOUNT_SID/Messages.json","options":{},"authentication":"basicAuth","jsonParameters":true},"typeVersion":1},{"id":"be16b0d3-b481-45f7-9f0e-1bd9e3705605","name":"Wait Day 4","type":"n8n-nodes-base.wait","position":[160,940],"webhookId":"a540fa94-5543-42a4-9be2-6f4d473d2b37","parameters":{"unit":"days"},"typeVersion":1},{"id":"ab72df9e-14c9-49e7-ab10-4c53ddd29bb1","name":"Check Booking Day 4","type":"n8n-nodes-base.googleSheets","position":[380,940],"parameters":{"range":"Sheet1!A:F","options":{},"sheetId":"your-google-sheet-id"},"typeVersion":1},{"id":"de3c3a76-197a-4274-8525-68beb27a91ac","name":"Send WhatsApp Day 4","type":"n8n-nodes-base.httpRequest","position":[600,940],"parameters":{"url":"https://api.twilio.com/2010-04-01/Accounts/YOUR_ACCOUNT_SID/Messages.json","options":{},"authentication":"basicAuth","jsonParameters":true},"typeVersion":1},{"id":"191b0875-9ca0-4c02-9d43-062ce9a17de9","name":"Wait Day 5","type":"n8n-nodes-base.wait","position":[160,1180],"webhookId":"edf9f6e6-5205-496a-a77d-3380f78f6032","parameters":{"unit":"days"},"typeVersion":1},{"id":"24675fcf-9b88-4663-95bd-e3ac42a18765","name":"Check Booking Day 5","type":"n8n-nodes-base.googleSheets","position":[380,1180],"parameters":{"range":"Sheet1!A:F","options":{},"sheetId":"your-google-sheet-id"},"typeVersion":1},{"id":"7b9bce28-6e9f-46c7-9c90-bcffe602d953","name":"Send WhatsApp Day 5","type":"n8n-nodes-base.httpRequest","position":[600,1180],"parameters":{"url":"https://api.twilio.com/2010-04-01/Accounts/YOUR_ACCOUNT_SID/Messages.json","options":{},"authentication":"basicAuth","jsonParameters":true},"typeVersion":1},{"id":"406301d8-19bb-4a18-bc97-0872c5ebe96b","name":"Wait 2 hrs","type":"n8n-nodes-base.wait","position":[100,260],"webhookId":"069a166b-fc80-487d-bfd0-07418a3c1e72","parameters":{"unit":"hours","amount":2},"typeVersion":1.1},{"id":"a8ff777f-fc0b-406c-aecd-717dfcadc4bf","name":"If","type":"n8n-nodes-base.if","position":[840,720],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"456fa536-42df-4d4e-9164-91088adaf382","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"","rightValue":""}]}},"typeVersion":2.2},{"id":"2e7f867a-c6ce-4ed6-a6ea-221971163c0f","name":"If1","type":"n8n-nodes-base.if","position":[820,500],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"456fa536-42df-4d4e-9164-91088adaf382","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"","rightValue":""}]}},"typeVersion":2.2},{"id":"aa00dcd3-a3a5-4441-af94-76df1ae11b1c","name":"If2","type":"n8n-nodes-base.if","position":[780,260],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"456fa536-42df-4d4e-9164-91088adaf382","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"","rightValue":""}]}},"typeVersion":2.2},{"id":"68b645f7-88cb-4275-9ea8-51aa667a1762","name":"If3","type":"n8n-nodes-base.if","position":[840,940],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"456fa536-42df-4d4e-9164-91088adaf382","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"","rightValue":""}]}},"typeVersion":2.2}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"9d8245cf-5e53-456e-9858-7b85fb51ad4c","connections":{"If":{"main":[[{"node":"Check Booking Status","type":"main","index":0}],[{"node":"Wait Day 4","type":"main","index":0}]]},"If1":{"main":[[{"node":"Check Booking Status","type":"main","index":0}],[{"node":"Wait Day 3","type":"main","index":0}]]},"If2":{"main":[[{"node":"Check Booking Status","type":"main","index":0}],[{"node":"Wait Day 2","type":"main","index":0}]]},"If3":{"main":[[{"node":"Check Booking Status","type":"main","index":0}],[{"node":"Wait Day 5","type":"main","index":0}]]},"If Booked?":{"main":[[{"node":"Check Booking Status","type":"main","index":0}],[{"node":"Wait 2 hrs","type":"main","index":0}]]},"Wait 2 hrs":{"main":[[{"node":"Check Booking Day 1","type":"main","index":0}]]},"Wait Day 2":{"main":[[{"node":"Check Booking Day 2","type":"main","index":0}]]},"Wait Day 3":{"main":[[{"node":"Check Booking Day 3","type":"main","index":0}]]},"Wait Day 4":{"main":[[{"node":"Check Booking Day 4","type":"main","index":0}]]},"Wait Day 5":{"main":[[{"node":"Check Booking Day 5","type":"main","index":0}]]},"FB Lead Webhook":{"main":[[{"node":"Add to Google Sheets","type":"main","index":0}]]},"Check Booking Day 1":{"main":[[{"node":"Send WhatsApp Day 1","type":"main","index":0}]]},"Check Booking Day 2":{"main":[[{"node":"Send WhatsApp Day 2","type":"main","index":0}]]},"Check Booking Day 3":{"main":[[{"node":"Send WhatsApp Day 3","type":"main","index":0}]]},"Check Booking Day 4":{"main":[[{"node":"Send WhatsApp Day 4","type":"main","index":0}]]},"Check Booking Day 5":{"main":[[{"node":"Send WhatsApp Day 5","type":"main","index":0}]]},"Send WhatsApp Day 1":{"main":[[{"node":"If2","type":"main","index":0}]]},"Send WhatsApp Day 2":{"main":[[{"node":"If1","type":"main","index":0}]]},"Send WhatsApp Day 3":{"main":[[{"node":"If","type":"main","index":0}]]},"Send WhatsApp Day 4":{"main":[[{"node":"If3","type":"main","index":0}]]},"Add to Google Sheets":{"main":[[{"node":"Send WhatsApp to Lead","type":"main","index":0}]]},"Check Booking Status":{"main":[[{"node":"Send Confirmation to Lead","type":"main","index":0},{"node":"Notify Gym Owner","type":"main","index":0}]]},"Send WhatsApp to Lead":{"main":[[{"node":"If Booked?","type":"main","index":0}]]}}}


name: Search Business Prospects with Natural Language using Claude AI and Explorium MCP
author_name: explorium
author_username: explorium
categories: []
created_at: 2025-06-10T06:55:38.377Z
updated_at: 2025-06-10T06:55:38.377Z
url: https://n8n.io/workflows/4840
scraped_at: 2025-07-06 21:16:30
description:
  Explorium Prospects Search Chatbot

  Template

  Download the following json file and import it to a new n8n workflow:

  mcp\_to\_prospects\_to\_csv.json

  Overview

  This n8n workflow creates a chatbot that understands natural language requests for finding business prospects and automatically:

  Interprets your query using AI (Claude Sonnet 3.7)
  Converts it to proper Explorium API filters
  Validates the API request structure
  Fetches prospect data from Explorium
  Exports results as a downloadable CSV file

  Perfect for sales teams, recruiters, and business development professionals who need to quickly find and export targeted prospect lists without learning complex API syntax.

  Key Features

  Natural Language Interface**: Simply describe who you're looking for in plain English
  Smart Query Translation**: AI converts your request to valid API parameters
  Built-in Validation**: Ensures API calls meet Explorium's requirements
  Error Recovery**: Automatically retries with corrections if validation fails
  Pagination Support**: Handles large result sets automatically
  CSV Export**: Clean, formatted output ready for CRM import
  Conversation Memory**: Maintains context for follow-up queries

  Example Queries

  The chatbot understands queries like:

  "Find marketing directors at SaaS companies in New York with 50-200 employees"
  "Get me CTOs from fintech startups in California"
  "Show me sales managers at healthcare companies with revenue over $10M"
  "Find engineers at Microsoft with 3-5 years experience"
  "Get customer service leads from e-commerce companies in Europe"

  Prerequisites

  Before setting up this workflow, ensure you have:

  n8n instance with chat interface enabled
  Anthropic API key for Claude
  Explorium API credentials (Bearer token) - Get explorium api key
  Basic understanding of n8n chat workflows

  Supported Filters

  The chatbot can search using these criteria:

  Company Filters

  Size**: 1-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10001+ employees
  Revenue**: Ranges from $0-500K up to $10T+
  Age**: 0-3, 3-6, 6-10, 10-20, 20+ years
  Location**: Countries, regions, cities
  Industry**: Google categories, NAICS codes, LinkedIn categories
  Name**: Specific company names

  Prospect Filters

  Job Level**: CXO, VP, Director, Manager, Senior, Entry, etc.
  Department**: Sales, Marketing, Engineering, Finance, HR, etc.
  Experience**: Total months and current role duration
  Location**: Country and region codes
  Contact Info**: Filter by email/phone availability

  Installation & Setup

  Step 1: Import the Workflow

  Copy the workflow JSON from the template
  In n8n: Workflows → Add Workflow → Import from File
  Paste the JSON and click Import

  Step 2: Configure Anthropic Credentials

  Click on the Anthropic Chat Model1 node
  Under Credentials, click Create New
  Add your Anthropic API key
  Name: "Anthropic API"
  Save credentials

  Step 3: Configure Explorium Credentials

  You'll need to set up Explorium credentials in two places:

  For MCP Client:

  Click on the MCP Client node
  Under Credentials, create new Header Auth
  Add your authentication header (usually Authorization: Bearer YOUR_TOKEN)
  Save credentials

  For API Calls:

  Click on the Prospects API Call node
  Use the same Header Auth credentials created above
  Verify the API endpoint is correct

  Step 4: Activate the Workflow

  Save the workflow
  Click the Active toggle to enable it
  The chat interface will now be available

  Step 5: Access the Chat Interface

  Click on the When chat message received node
  Copy the webhook URL
  Access this URL in your browser to start chatting

  How It Works

  Workflow Architecture

  Chat Trigger: Receives natural language queries from users
  Memory Buffer: Maintains conversation context
  AI Agent: Interprets queries and generates API parameters
  Validation: Checks API structure against Explorium requirements
  API Call: Fetches prospect data with pagination
  Data Processing: Formats results for CSV export
  File Conversion: Creates downloadable CSV file

  Processing Flow

  User Query → AI Interpretation → Validation → API Call → CSV Export
       ↑                                  ↓
       └──── Error Correction Loop ←──────┘

  Validation Rules

  The workflow validates:

  Filter keys are allowed by Explorium API
  Values match expected formats (e.g., valid country codes)
  Range filters have proper gte/lte values
  No duplicate values in arrays
  Required structure is maintained

  Usage Guide

  Basic Conversation Flow

  Start with your query:
        "Find me VPs of Sales at software companies in the US"
     
  Bot processes and responds:
     Generates API filters
     Validates the structure
     Fetches data
     Returns CSV download link

  Refine if needed:
        "Can you also include directors and filter for companies with 100+ employees?"
  Query Tips

  Be specific**: Include job titles, departments, company details
  Use standard terms**: "CTO" instead of "Chief Technology Officer"
  Specify locations**: Use country names or standard codes
  Include size/revenue**: Helps narrow results effectively

  Advanced Queries

  Combine multiple criteria:

  "Find engineering managers and senior engineers at B2B SaaS companies 
  in New York and California with 50-500 employees and revenue over $5M 
  who have been in their role for at least 1 year"

  Output Format

  The CSV file includes:

  Prospect ID
  Name (first, last, full)
  Location (country, region, city)
  LinkedIn profile
  Experience summary
  Skills and interests
  Company details
  Job information
  Business ID

  Troubleshooting

  Common Issues

  "Validation failed" errors

  Check that your query uses supported filter values
  Ensure location names are spelled correctly
  Verify company sizes/revenues match allowed ranges

  No results returned

  Broaden your search criteria
  Check if the company exists in Explorium's database
  Verify filter combinations aren't too restrictive

  Chat not responding

  Ensure workflow is activated
  Check all credentials are properly configured
  Verify webhook URL is accessible

  Large result sets timing out

  Try adding more specific filters
  Limit results by location or company size
  Use the size parameter (max 10,000)

  Error Messages

  The bot provides clear feedback:

  Invalid filters**: Shows which filters aren't supported
  Value errors**: Lists correct options for each field
  API failures**: Explains connection or authentication issues

  Performance Optimization

  Best Practices

  Start broad, then narrow: Begin with basic criteria and add filters
  Use business IDs: When targeting specific companies
  Limit by contact info: Add has_email: true for actionable leads
  Batch by location: Process regions separately for large searches

  API Limits

  Maximum 10,000 results per search
  Pagination handles up to 100 records per page
  Rate limits apply based on your Explorium subscription

  Customization Options

  Modify AI Behavior

  Edit the AI Agent system message to:

  Change response format
  Add custom filters
  Adjust interpretation logic
  Include additional instructions

  Extend Functionality

  Add nodes to:

  Send results via email
  Import directly to CRM
  Schedule recurring searches
  Create custom reports

  Integration Ideas

  Connect to Slack for team queries
  Add to CRM workflows
  Create lead scoring systems
  Build automated outreach campaigns

  Security Considerations

  API credentials are stored securely in n8n
  Chat sessions are isolated
  No prospect data is stored permanently
  CSV files are generated on-demand

  Support Resources

  For issues with:

  n8n platform**: Check n8n documentation
  Explorium API**: Contact Explorium support
  Anthropic/Claude**: Refer to Anthropic docs
  Workflow logic**: Review node configurations

nodes_used:
  ["n8n-nodes-base.httpRequest","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatAnthropic","@n8n/n8n-nodes-langchain.memoryBufferWindow","@n8n/n8n-nodes-langchain.outputParserStructured","@n8n/n8n-nodes-langchain.mcpClientTool"]

workflow_json:
  {"meta":{"instanceId":"0a70652f43c1b29dd16c35b61a38fd31c8004f58bc7e723bf43262a797407c77","templateCredsSetupCompleted":true},"name":"My workflow 5","tags":[],"nodes":[{"id":"850d04e5-6cad-4a35-96cf-47478ae7b91f","name":"Convert to File","type":"n8n-nodes-base.convertToFile","position":[880,0],"parameters":{"options":{}},"typeVersion":1.1},{"id":"a7f50841-af97-4127-a4f1-a0ce4352759e","name":"Simple Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[-880,270],"parameters":{"contextWindowLength":100},"typeVersion":1.3},{"id":"b30bbfbc-747c-4ba7-8ae5-737bb13bb6a3","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[-1440,175],"webhookId":"36280bdf-bc14-42f0-86f8-281ce2885df6","parameters":{"options":{}},"typeVersion":1.1},{"id":"d3a27151-8278-4c72-aa76-a1a31095a240","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[-908,50],"parameters":{"text":"={{ $json.combinedInput }}","options":{"maxIterations":100,"systemMessage":"=You are an expert in interpreting natural language queries and converting them into structured JSON requests for the Explorium MCP API.\n\nYour task is to generate the **`data` portion** of a `fetch_prospects` API request, using only Explorium MCP-compatible filters and parameters. Adjust the filters based on both the query and the MCP specifications—not all filters are relevant for every query.\n\n**You may also be asked to revise a previous response that failed validation due to incorrect filters or formatting.** In such cases, carefully review the error message and regenerate the JSON accordingly.\n\nYour response must be a **single JSON object** with this structure:\n\n```json\n{\n  \"mode\": \"full\",\n  \"size\": 10000,\n  \"page_size\": 100,\n  \"page\": 1,\n  \"filters\": {\n    \"has_email\": { \"value\": true },\n    \"has_phone_number\": { \"value\": true },\n    \"job_level\": { \"values\": [...] },\n    \"job_department\": { \"values\": [...] },\n    \"business_id\": { \"values\": [...] },\n    ...\n  }\n}\n```\n\n### Required Structure:\n\n* The fields `mode`, `size`, `page_size`, and `page` must appear **before** the `filters` object.\n* Default values:\n\n  * `mode`: `\"full\"`\n  * `size`: `10000` (unless otherwise specified by the user; must remain between 1 and 10000)\n  * `page_size`: `100` (**must always be less or equal to `size`**)\n  * `page`: `1`\n  * `has_email`: always `{ \"value\": true }`, unless explicitly requested otherwise\n\n---\n\n### Allowed Filters & Valid Values:\n\nIf any of the following filters appear in your output, their values **must strictly match** these lists:\n\n* **`company_size`**: `'1-10'`, `'11-50'`, `'51-200'`, `'201-500'`, `'501-1000'`, `'1001-5000'`, `'5001-10000'`, `'10001+'`\n* **`company_age`**: `'0-3'`, `'3-6'`, `'6-10'`, `'10-20'`, `'20+'`\n* **`number_of_locations`**: `'0-1'`, `'2-5'`, `'6-20'`, `'21-50'`, `'51-100'`, `'101-1000'`, `'1001+'`\n* **`company_revenue`**: `'0-500K'`, `'500K-1M'`, `'1M-5M'`, `'5M-10M'`, `'10M-25M'`, `'25M-75M'`, `'75M-200M'`, `'200M-500M'`, `'500M-1B'`, `'1B-10B'`, `'10B-100B'`, `'100B-1T'`, `'1T-10T'`, `'10T+'`\n* **`job_level`**: `'director'`, `'manager'`, `'vp'`, `'partner'`, `'cxo'`, `'non-managerial'`, `'senior'`, `'entry'`, `'training'`, `'unpaid'`\n* **`job_department`**: `'customer service'`, `'design'`, `'education'`, `'engineering'`, `'finance'`, `'general'`, `'health'`, `'human resources'`, `'legal'`, `'marketing'`, `'media'`, `'operations'`, `'public relations'`, `'real estate'`, `'sales'`, `'trades'`, `'unknown'`\n* **`country_code`** and **`company_country_code`**: Must be valid **2-letter ISO Alpha-2 codes** (e.g., `us`, `gb`, `de`, etc.)\n* **`total_experience_months`** and **`current_role_months`**: These must be objects with both a `gte` and `lte` key where `gte <= lte`, for example:\n\n```json\n\"total_experience_months\": { \"gte\": 3, \"lte\": 6 }\n```\n\nand\n\n```json\n\"current_role_months\": { \"gte\": 1, \"lte\": 10 }\n```\n\n* If a company name is mentioned (e.g., \"Microsoft\"), include its `business_id` (use a placeholder like `\"abc123\"` if unknown)\n\n---\n\n### Interpretation & Mapping:\n\n* Extract job levels from descriptions like:\n\n  * “executives” or “leadership” → `\"cxo\"`\n  * “heads” or “vice presidents” → `\"vp\"`\n* Map department-like terms (e.g., “sales”, “marketing”) to the `job_department` field.\n* Don’t include filters with empty or unrecognized values.\n* Use plural logic: if the query includes a phrase like “finance and marketing,” return both departments.\n\n---\n\n### Off-topic Handling:\n\nIf the request is unrelated to B2B data intelligence or the MCP use cases, return the following message verbatim:\n\n> I’m the Explorium MCP Playground assistant, built to explore company & prospect intelligence.\n> Example queries:\n> • Find SaaS firms in New York with 50‑200 employees\n> • Show Microsoft’s technology stack\n> • Get marketing‑director contacts at healthcare companies\n> • Compare funding rounds of fintech startups\n> How would you like to explore Explorium’s data?"},"promptType":"define","hasOutputParser":true},"retryOnFail":true,"typeVersion":1.7},{"id":"24b27ab1-ba9e-4e43-924f-819a1505cdba","name":"Extract \"data\"","type":"n8n-nodes-base.splitOut","position":[440,0],"parameters":{"options":{},"fieldToSplitOut":"data"},"typeVersion":1},{"id":"8cc673a5-d6cf-4e64-9d99-01d0320429fa","name":"Merge All Pages","type":"n8n-nodes-base.code","position":[220,0],"parameters":{"jsCode":"// Initialize a single array to hold all data items\nconst mergedData = [];\n\n// Loop over all input items\nfor (const item of $input.all()) {\n  if (item.json.data && Array.isArray(item.json.data)) {\n    mergedData.push(...item.json.data); // Spread and merge the data arrays\n  }\n}\n\n// Return a single item with the combined data array\nreturn [\n  {\n    json: {\n      data: mergedData\n    }\n  }\n];"},"typeVersion":2},{"id":"e9173b61-010d-42f9-83d9-1ce724ca9fb9","name":"Prepare for CSV","type":"n8n-nodes-base.code","position":[660,0],"parameters":{"jsCode":"const items = [];\n\nfor (const item of $input.all()) {\n  items.push({\n    prospect_id: item.json.prospect_id ?? null,\n    first_name: item.json.first_name ?? null,\n    last_name: item.json.last_name ?? null,\n    full_name: item.json.full_name ?? null,\n    country_name: item.json.country_name ?? null,\n    region_name: item.json.region_name ?? null,\n    city: item.json.city ?? null,\n    linkedin: item.json.linkedin ?? null,\n    experience: Array.isArray(item.json.experience) ? item.json.experience.join('; ') : null,\n    skills: Array.isArray(item.json.skills) ? item.json.skills.join(', ') : null,\n    interests: Array.isArray(item.json.interests) ? item.json.interests.join(', ') : item.json.interests ?? null,\n    company_name: item.json.company_name ?? null,\n    company_website: item.json.company_website ?? null,\n    company_linkedin: item.json.company_linkedin ?? null,\n    job_department: item.json.job_department ?? null,\n    job_seniority_level: Array.isArray(item.json.job_seniority_level) ? item.json.job_seniority_level.join(', ') : null,\n    job_title: item.json.job_title ?? null,\n    business_id: item.json.business_id ?? null,\n  });\n}\n\nreturn items;"},"typeVersion":2},{"id":"6ce4650b-b267-4642-9104-0e47568ee049","name":"API Call Validation","type":"n8n-nodes-base.code","position":[-440,50],"parameters":{"jsCode":"const allowedFilters = [\n  \"country_code\",\n  \"region_country_code\",\n  \"company_country_code\",\n  \"company_region_country_code\",\n  \"company_size\",\n  \"company_revenue\",\n  \"company_age\",\n  \"google_category\",\n  \"naics_category\",\n  \"linkedin_category\",\n  \"company_name\",\n  \"number_of_locations\",\n  \"city_region_country\",\n  \"website_keywords\",\n  \"has_email\",\n  \"has_phone_number\",\n  \"job_level\",\n  \"job_department\",\n  \"job_title\",\n  \"business_id\",\n  \"total_experience_months\",\n  \"current_role_months\"\n];\n\nconst validCompanySizes = ['1-10', '11-50', '51-200', '201-500', '501-1000', '1001-5000', '5001-10000', '10001+'];\nconst validAges = ['0-3', '3-6', '6-10', '10-20', '20+'];\nconst validLocations = ['0-1', '2-5', '6-20', '21-50', '51-100', '101-1000', '1001+'];\nconst validRevenue = [\n  \"0-500K\", \"500K-1M\", \"1M-5M\", \"5M-10M\", \"10M-25M\", \"25M-75M\", \"75M-200M\", \"200M-500M\",\n  \"500M-1B\", \"1B-10B\", \"10B-100B\", \"100B-1T\", \"1T-10T\", \"10T+\"\n];\nconst validJobLevel = [\"director\", \"manager\", \"vp\", \"partner\", \"cxo\", \"non-managerial\", \"senior\", \"entry\", \"training\", \"unpaid\"];\nconst validDepartment = [\n  \"customer service\", \"design\", \"education\", \"engineering\", \"finance\", \"general\", \"health\", \"human resources\",\n  \"legal\", \"marketing\", \"media\", \"operations\", \"public relations\", \"real estate\", \"sales\", \"trades\", \"unknown\"\n];\n\nconst countryCodeRegex = /^(aw|af|ao|ai|ax|al|ad|ae|ar|am|as|aq|tf|ag|au|at|az|bi|be|bj|bq|bf|bd|bg|bh|bs|ba|bl|by|bz|bm|bo|br|bb|bn|bt|bv|bw|cf|ca|cc|ch|cl|cn|ci|cm|cd|cg|ck|co|km|cv|cr|cu|cw|cx|ky|cy|cz|de|dj|dm|dk|do|dz|ec|eg|er|eh|es|ee|et|fi|fj|fk|fr|fo|fm|ga|gb|ge|gg|gh|gi|gn|gp|gm|gw|gq|gr|gd|gl|gt|gf|gu|gy|hk|hm|hn|hr|ht|hu|id|im|in|io|ie|ir|iq|is|il|it|jm|je|jo|jp|kz|ke|kg|kh|ki|kn|kr|kw|la|lb|lr|ly|lc|li|lk|ls|lt|lu|lv|mo|mf|ma|mc|md|mg|mv|mx|mh|mk|ml|mt|mm|me|mn|mp|mz|mr|ms|mq|mu|mw|my|yt|na|nc|ne|nf|ng|ni|nu|nl|no|np|nr|nz|om|pk|pa|pn|pe|ph|pw|pg|pl|pr|kp|pt|py|ps|pf|qa|re|ro|ru|rw|sa|sd|sn|sg|gs|sh|sj|sb|sl|sv|sm|so|pm|rs|ss|st|sr|sk|si|se|sz|sx|sc|sy|tc|td|tg|th|tj|tk|tm|tl|to|tt|tn|tr|tv|tw|tz|ug|ua|um|uy|us|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|xk|ye|za|zm|zw)$/;\n\nconst item = $input.first().json;\nconst output = item.output || {};\nconst filters = output.filters || {};\nconst errors = [];\n\nfor (const key of Object.keys(filters)) {\n  const filter = filters[key];\n\n  if (!allowedFilters.includes(key)) {\n    errors.push(`Invalid filter key: '${key}'`);\n    continue;\n  }\n\n  if ('value' in filter) {\n    if (typeof filter.value !== 'boolean') {\n      errors.push(`Filter '${key}' has a 'value' but it's not a boolean.`);\n    }\n    continue;\n  }\n\n  if ('values' in filter) {\n    if (!Array.isArray(filter.values) || filter.values.length === 0) {\n      errors.push(`Filter '${key}' must contain a non-empty 'values' array.`);\n      continue;\n    }\n\n    // Normalize to lowercase for fields that require it\n    if ([\"job_level\", \"job_department\", \"country_code\", \"region_country_code\", \"company_country_code\", \"company_region_country_code\"].includes(key)) {\n      filter.values = filter.values.map(v => typeof v === 'string' ? v.toLowerCase() : v);\n    }\n\n    const validateValues = (validList, keyName) => {\n      const invalid = filter.values.filter(v => !validList.includes(v));\n      if (invalid.length > 0) {\n        errors.push(`Invalid ${keyName} values: ${invalid.join(', ')}. Valid values are: ${validList.join(', ')}`);\n      }\n    };\n\n    switch (key) {\n      case 'company_size':\n        validateValues(validCompanySizes, 'company_size');\n        break;\n      case 'company_age':\n        validateValues(validAges, 'company_age');\n        break;\n      case 'number_of_locations':\n        validateValues(validLocations, 'number_of_locations');\n        break;\n      case 'company_revenue':\n        validateValues(validRevenue, 'company_revenue');\n        break;\n      case 'job_level':\n        validateValues(validJobLevel, 'job_level');\n        break;\n      case 'job_department':\n        validateValues(validDepartment, 'job_department');\n        break;\n      case 'country_code':\n        const invalid = filter.values.filter(v => !countryCodeRegex.test(v));\n        if (invalid.length > 0) {\n          errors.push(`Invalid country_code values: ${invalid.join(', ')}. Must be ISO 3166-1 alpha-2 codes.`);\n        }\n        break;\n    }\n\n    const unique = new Set(filter.values);\n    if (unique.size < filter.values.length) {\n      errors.push(`Duplicate values found in filter '${key}'`);\n    }\n\n    continue;\n  }\n\n  // Handle total_experience_months and current_role_months as a range objects\n  if (key === 'total_experience_months' || key === 'current_role_months') {\n  const range = filter;\n  \n  if (!('gte' in range) && !('lte' in range)) {\n    errors.push(`Filter '${key}' must include at least 'gte' or 'lte'.`);\n    continue;\n  }\n\n  if ('gte' in range && typeof range.gte !== 'number') {\n    errors.push(`Filter '${key}' has a non-numeric 'gte' value.`);\n  }\n\n  if ('lte' in range && typeof range.lte !== 'number') {\n    errors.push(`Filter '${key}' has a non-numeric 'lte' value.`);\n  }\n\n  if ('gte' in range && 'lte' in range && range.gte > range.lte) {\n    errors.push(`Filter '${key}' has 'gte' greater than 'lte'.`);\n  }\n\n  continue;\n}\n\n  errors.push(`Filter '${key}' must include either 'value', 'values', or a valid range.`);\n}\n\nreturn [\n  {\n    json: {\n      ...item,\n      isValid: errors.length === 0,\n      validationErrors: errors\n    }\n  }\n];\n"},"typeVersion":2},{"id":"fdfc7b79-9dbe-4fcb-89c0-4b83d9c11915","name":"Validation Prompter","type":"n8n-nodes-base.code","position":[0,275],"parameters":{"jsCode":"const sessionId = $('When chat message received').first().json.sessionId;\nconst userQuery = $('When chat message received').first().json.chatInput;\nconst aiOutput = $('AI Agent').first().json.output;\nconst validationErrors = $('API Call Validation').first().json.validationErrors;\n\n// Safely stringify output and errors\nconst formattedOutput = typeof aiOutput === 'object' ? JSON.stringify(aiOutput, null, 2) : aiOutput;\nconst formattedErrors = Array.isArray(validationErrors) ? validationErrors.join('\\n- ') : validationErrors;\n\nreturn [\n  {\n    sessionId,\n    action: \"sendMessage\",\n    source: \"validation\",\n    errorInput: \n`Your response did not pass validation.\n\n📝 **User Query**:\n${userQuery}\n\n🤖 **Your Output**:\n${formattedOutput}\n\n⚠️ **Validation Errors**:\n- ${formattedErrors}\n\n🔧 Please review the validation errors and regenerate a corrected output. \nEnsure that all values strictly match the allowed formats and valid categories.\n\nReformulate your response accordingly.`\n  }\n];"},"typeVersion":2},{"id":"60425530-b675-4389-9712-f86071453d58","name":"Is API Call Valid?","type":"n8n-nodes-base.if","position":[-220,50],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"9b2c3127-07c4-47d0-8dc3-44daa2a2d6e7","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ $json.isValid }}","rightValue":"true"}]}},"typeVersion":2.2},{"id":"436aff8c-046d-4060-9a26-00b259e2ffbf","name":"Chat or Refinement","type":"n8n-nodes-base.code","position":[-1220,175],"parameters":{"jsCode":"const chat = $json.chatInput;\nconst error = $json.errorInput;\n\nreturn [\n  {\n    json: {\n      ...$json,\n      combinedInput: error ?? chat\n    }\n  }\n];"},"typeVersion":2},{"id":"7e0953ff-683c-4b6d-8f7d-abb80abd15ad","name":"Anthropic Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatAnthropic","position":[-1000,270],"parameters":{"model":{"__rl":true,"mode":"list","value":"claude-sonnet-4-20250514","cachedResultName":"Claude Sonnet 4"},"options":{"thinking":false}},"credentials":{"anthropicApi":{"id":"zb4GaoxVQ7gIbD2A","name":"Anthropic account 3"}},"typeVersion":1.3},{"id":"8554cc57-0118-4af4-96d0-ac2a9a7c7f2c","name":"Explorium MCP","type":"@n8n/n8n-nodes-langchain.mcpClientTool","position":[-760,270],"parameters":{"sseEndpoint":"https://mcp-auth.explorium.ai/sse","authentication":"headerAuth"},"credentials":{"httpHeaderAuth":{"id":"85mkGmNNdK1951hF","name":"Header Auth Connection"}},"typeVersion":1},{"id":"e6c05002-29c1-4716-bc14-20361fb28e56","name":"Output Parser","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[-640,270],"parameters":{"jsonSchemaExample":"{\n  \"mode\": \"full\",\n  \"size\": 10000,\n  \"page_size\": 100,\n  \"page\": 1,\n  \"filters\": {\n    \"has_email\": {\n      \"value\": true\n    },\n    \"has_phone_number\": {\n      \"value\": true\n    },\n    \"job_level\": {\n      \"values\": [\n        \"cxo\",\n        \"manager\"\n      ]\n    },\n    \"job_department\": {\n      \"values\": [\n        \"Customer service\",\n        \"Engineering\"\n      ]\n    },\n    \"business_id\": {\n      \"values\": [\n    \"8adce3ca1cef0c986b22310e369a0793\"\n      ]\n    },\n    \"total_experience_months\": {\n      \"gte\": 1,\n      \"lte\": 20\n    },\n    \"country_code\": {\n      \"values\": [\n        \"us\",\n        \"dk\",\n        \"uk\"\n      ]\n    },\n    \"region_country_code\": {\n      \"values\": [\n        \"us-ca\",\n        \"us-ny\"\n      ]\n    },\n    \"current_role_months\": {\n      \"gte\": 1,\n      \"lte\": 200\n    },\n    \"company_size\": {\n      \"values\": [\n        \"5001-10000\"\n      ]\n    },\n    \"company_revenue\": {\n      \"values\": [\n        \"500K-1M\",\n        \"5M-10M\"\n      ]\n    },\n    \"google_category\": {\n      \"values\": [\n        \"construction\"\n      ]\n    },\n    \"naics_category\": {\n      \"values\": [\n        \"541512\"\n      ]\n    },\n    \"linkedin_category\": {\n      \"values\": [\n        \"retail\",\n        \"software development\"\n      ]\n    },\n    \"job_title\": {\n      \"values\": [\n        \"Software Engineer\"\n      ]\n    },\n    \"company_country_code\": {\n      \"values\": [\n        \"us\",\n        \"jp\"\n      ]\n    },\n    \"company_region_country_code\": {\n      \"values\": [\n        \"us-ca\"\n      ]\n    },\n    \"city_region_country\": {\n      \"values\": [\n        \"Paris, FR\"\n      ]\n    },\n    \"company_name\": {\n      \"values\": [\n        \"Microsoft\"\n      ]\n    }\n  }\n}"},"typeVersion":1.2},{"id":"e1e4391e-f199-4669-b62f-1d2f3f93aeff","name":"Explorium Prospects API Call","type":"n8n-nodes-base.httpRequest","position":[0,0],"parameters":{"url":"=https://api.explorium.ai/v1/prospects","method":"POST","options":{"pagination":{"pagination":{"parameters":{"parameters":[{"name":"page","type":"body","value":"={{$response.body.page + 1}}"}]},"limitPagesFetched":true,"completeExpression":"={{$response.body.data.length === 0}}","paginationCompleteWhen":"other"}}},"jsonBody":"={{ $json.output }}","sendBody":true,"sendHeaders":true,"specifyBody":"json","authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","headerParameters":{"parameters":[{"name":"accept","value":"application/json"}]}},"credentials":{"httpHeaderAuth":{"id":"85mkGmNNdK1951hF","name":"Header Auth Connection"}},"typeVersion":4.2}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"","connections":{"AI Agent":{"main":[[{"node":"API Call Validation","type":"main","index":0}]]},"Explorium MCP":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"Output Parser":{"ai_outputParser":[[{"node":"AI Agent","type":"ai_outputParser","index":0}]]},"Simple Memory":{"ai_memory":[[{"node":"AI Agent","type":"ai_memory","index":0}]]},"Extract \"data\"":{"main":[[{"node":"Prepare for CSV","type":"main","index":0}]]},"Merge All Pages":{"main":[[{"node":"Extract \"data\"","type":"main","index":0}]]},"Prepare for CSV":{"main":[[{"node":"Convert to File","type":"main","index":0}]]},"Chat or Refinement":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"Is API Call Valid?":{"main":[[{"node":"Explorium Prospects API Call","type":"main","index":0}],[{"node":"Validation Prompter","type":"main","index":0}]]},"API Call Validation":{"main":[[{"node":"Is API Call Valid?","type":"main","index":0}]]},"Validation Prompter":{"main":[[{"node":"Chat or Refinement","type":"main","index":0}]]},"Anthropic Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"When chat message received":{"main":[[{"node":"Chat or Refinement","type":"main","index":0}]]},"Explorium Prospects API Call":{"main":[[{"node":"Merge All Pages","type":"main","index":0}]]}}}


name: Generate Sales Emails Based on Business Events with Explorium MCP & Claude
author_name: explorium
author_username: explorium
categories: []
created_at: 2025-06-10T06:56:57.172Z
updated_at: 2025-06-10T06:56:57.172Z
url: https://n8n.io/workflows/4841
scraped_at: 2025-07-06 21:16:30
description:
  Explorium Event-Triggered Outreach

  This n8n and agent-based workflow automates outbound prospecting by monitoring Explorium event data (e.g. product launches, new office opening, new investment and more), researching companies, identifying key contacts, and generating tailored sales emails leveraging the Explorium MCP server.

  Template

  Workflow Overview

  Node 1: Webhook Trigger

  Purpose: Listens for real-time product launch events pushed from Explorium's webhook system.

  How it works:

  Explorium sends HTTP POST requests containing event data
  The webhook payload includes company name, business ID, domain, product name, and event type
  Pay attention: Product launch is just one example. You can easily enroll to many more meaningful events.
  to learn about events and how to enroll to events, visit the events documentation.

  Node 2: Company Research Agent

  Agent Type: Tools Agent

  Purpose: Enrich company data after an event occurs.

  How it works:

  Uses Explorium MCP via the MCP Client tool to gather additional company data
  Uses Anthropic Claude (Chat Model) to process and interpret company information for downstream personalization

  Node 3: Employee Data Retrieval

  Purpose: Retrieve prospect-level data for targeting.

  How it works:

  Uses HTTP Request node to call Explorium's fetch_prospects endpoint
  Filters prospects by:
    Company business_id
    Departments: Product, R&D, etc...
    Seniority levels: owner, cxo, vp, director, senior, manager, partner, etc...
    Pay Attention: Follow our fetch prospect documentation for the full list of filter and best practice.
  Limits results to top 5 relevant employees
  Code nodes handle:
    Filtering logic
    Cleaning API response
    Formatting data for downstream agents

  Node 4: Conditional Branch - Prospect Data Check

  If Node: Checks whether prospect data was successfully retrieved

  Logic:

  If prospects found → personalized emails per person
  If no prospects → fallback to company-level general email

  Node 5A: Email Writer #1 (No Prospect Data)

  Agent Type: Tools Agent

  Purpose: Write generic outbound email using only company-level research and event info.

  Powered by: Anthropic Chat Model

  Node 5B: Loop Over Prospects → Email Writer #2 (Personalized)

  Agent Type: Tools Agent

  Purpose: Write highly personalized email for each identified employee.

  How it works:

  Loops through each individual prospect
  Passes company research + employee data to LLM agent
  Generates customized emails referencing:
    Prospect's title & department
    Product launch
    Role-relevant Explorium value proposition

  Node 6: Slack Notifications

  Purpose: Posts completed emails to internal Slack channel for review or testing before final deployment.

  Future State: Can be swapped with an email sequencing platform in production.

  Setup Requirements

  Explorium API Access

  MCP Client credentials for company enrichment and prospect fetching
  Registered webhook for event listening

  Get explorium api key

  n8n Configuration

  Secure environment variables for API keys & webhook secret
  Code nodes configured for JSON transformation, filtering & signature validation

  Customization Options

  Personalization Logic

  Update LLM prompt instructions to reflect ICP priorities
  Modify email templates based on role, department, or tenure logic
  Adjust fallback behavior when prospect data is unavailable

  API Request Tuning

  Adjust page_size for number of prospects retrieved
  Fine-tune seniority and department filters to match evolving targeting

  Future Expansion

  Swap Slack notifications for outbound email automation
  Integrate call task assignment directly into CRM
  Introduce engagement scoring feedback loop (opens, clicks, replies)

  Troubleshooting Tips

  Validate webhook signature matching to prevent unauthorized requests
  Ensure correct business_id is passed to prospect fetching endpoint
  Confirm business enrichment returns sufficient data for company researcher agents
  Review agent LLM responses for correct output structure and parsing consistency

nodes_used:
  ["n8n-nodes-base.httpRequest","n8n-nodes-base.slack","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatAnthropic","@n8n/n8n-nodes-langchain.mcpClientTool"]

workflow_json:
  {"meta":{"instanceId":"0a70652f43c1b29dd16c35b61a38fd31c8004f58bc7e723bf43262a797407c77"},"name":"Automated Sales Outreach with Slack","tags":[],"nodes":[{"id":"1b7537b1-0b43-43ac-b50a-5df61641043d","name":"Anthropic Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatAnthropic","position":[-1220,560],"parameters":{"model":{"__rl":true,"mode":"list","value":"claude-3-7-sonnet-20250219","cachedResultName":"Claude 3.7 Sonnet"},"options":{}},"credentials":{"anthropicApi":{"id":"FQdE6twB8nCJNoxV","name":"Anthropic account"}},"typeVersion":1.3},{"id":"1eb46a9e-5b03-42a2-8132-ccda3f42b453","name":"Loop Over Items","type":"n8n-nodes-base.splitInBatches","position":[632,540],"parameters":{"options":{"reset":false},"batchSize":"={{ 1 }}"},"typeVersion":3},{"id":"4965a3e2-fa71-4680-b0bd-6db416edbc25","name":"Company Researcher","type":"@n8n/n8n-nodes-langchain.agent","position":[-1220,390],"parameters":{"text":"={{ $json.body.data }}","options":{"maxIterations":12,"systemMessage":"=You are a research analyst helping a sales agent write a highly personalized outbound email. Your job is to generate a detailed research brief that explains:\n\n1. **What the company does**\n2. **What the recent business event is**, and why it's significant\n3. **How the event might reflect on the company’s priorities, pain points, or growth goals**\n4. Any additional company context that might be useful for crafting a relevant sales message\n\n## Guidelines:\n- Your response should be **detailed, structured, and accurate**\n- You are writing **for another AI**, so don't hold back on context — more is better\n- You can assume the user already passed in the full event details (like a trigger type, a short summary, etc.)\n- Focus more on **interpreting** the event and **linking it to the company**\n- Write in **natural language**, using clear, concise, informative sentences — not marketing fluff or speculation\n- Keep your tone objective and analytical\n- Avoid repeating generic phrases like “the company is innovative” unless supported by facts\n\n## Inputs:\n- Business ID: {{ $json.body.business_id }}\n- Event: {{ $json.body.data }}\n\n## Output Structure:\nReturn your findings in 2-3 clear paragraphs. The first paragraph should describe the **event in detail** and explain why it may be relevant. The second should summarize what the **company does** and any other useful GTM signals (size, growth stage, recent changes, priorities, etc.).\n\nNow generate the research summary.\n"},"promptType":"define"},"typeVersion":1.9},{"id":"d0af2b0e-80c5-43b8-af7d-8f8039c90883","name":"Email Writer ( YES prospect data)","type":"@n8n/n8n-nodes-langchain.agent","position":[852,415],"parameters":{"text":"=prospect_data: contact info:{{ $json.email }}, expereince:{{ $json.experience }},skills:{{ $json.skills }}.\ncompany data:{{ $('Company Researcher').first().json.output }}\nevent data: {{ $('Webhook - Product Launch').first().json.body }}\n\n","options":{"systemMessage":"=You are a B2B outbound sales email generator.\n\nYour task is to write a short and effective cold outbound email (under 150 words) to a specific prospect at a company. The goal is to be relevant, concise, and persuasive, while introducing Explorium in a way that aligns with the prospect’s role and current company context.\n\n## Prospect Data\n{prospect_data}\n\n## Company \n{company_data}\n\n## Event Data\n{event_data}\n\n## About Explorium (Use this to inform the email — do not paste directly):\nExplorium is a data-powered intelligence platform on a mission to unlock the full potential of external data for the agent era. We serve as the infrastructure backbone for intelligent systems — helping go-to-market teams enrich company and prospect data, tap into real-time signals, and dynamically prioritize their best-fit accounts. Our platform fuels the agents and AI products that are redefining the future of sales and marketing.\n\n## MCP Playground (Link to include):\nInvite the prospect to explore Explorium’s capabilities hands-on via our [MCP Playground](https://www.explorium.ai/mcp-playground/), a public environment to experience the power of enriched external data.\n\n## Output Instructions:\n- Personalize the email using the provided prospect, company, and event information\n- Tailor the message to the prospect’s title, department, or function\n- Weave in how Explorium could support their work or goals based on what the company is focused on\n- The email should feel like it’s written by a real SDR — confident, relevant, and human\n- End the email with a soft CTA inviting them to check out the MCP Playground link but dont forget to also ask to set up a meeting / call\n- At the top of the email, output the selected email address to use. Choose the prospect’s **professional email** if available, or fallback to the next best alternative (personal, current, etc.)\n\nNow write the email.\n"},"promptType":"define"},"typeVersion":1.9},{"id":"f7e3faae-1353-4570-bdca-f1055c4b5c5b","name":"Email Writer (NO prospect data)","type":"@n8n/n8n-nodes-langchain.agent","position":[-404,140],"parameters":{"text":"=company data:{{ $('Company Researcher').first().json.output }}\nevent data: {{ $('Webhook - Product Launch').first().json.body }}\n","options":{"systemMessage":"=You are a B2B outbound email assistant.\n\nYour task is to write a short, personalized outbound email (under 120 words) that connects Explorium to a recent business event or trigger at a target company. This email will be sent to a general marketing, growth, or data contact — no specific prospect information is available.\n\n## Context Provided:\n- Company Information: {company_data}\n- Event Information: {event_data}\n\n## About Explorium (Use as context — DO NOT paste directly):\nExplorium is on a mission to unlock the full potential of data for the agent era. From day one, we’ve been driven to be the data and infrastructure backbone that powers intelligent systems and delivers real business growth.\n\nWe partner with smart, driven teams to turn raw external data into actionable insight—fueling agents, AI products, and GTM strategies for the future of sales and marketing.\n\nIf relevant, you may mention that they can explore Explorium’s capabilities themselves via our [MCP Playground](https://www.explorium.ai/mcp-playground/), a public demo environment showcasing the power of enriched data. \n\ndont forget to always end with a call to action in setting up some sort of call or meeting to talk further\n\n## Instructions:\n- Reference the event to establish relevance and timing\n- Briefly describe what the company does (from the input)\n- Weave in Explorium’s value if it's applicable to their business priorities\n- If appropriate, suggest checking out the MCP Playground link\n- End with a warm, soft CTA\n\nNow write the email.\n"},"promptType":"define"},"typeVersion":1.9},{"id":"5012126e-241d-4c5b-8c53-42452933e0a7","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1220,220],"parameters":{"width":260,"content":"## Reaserch\nThis agent uses the Explorium MCP to research the company that just had an event"},"typeVersion":1},{"id":"11fafba4-861d-4766-b334-51f745bcd8bb","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-760,220],"parameters":{"height":140,"content":"## Crossroads \n\nif we cant find data about the company's employees, we fork up, to write a general email "},"typeVersion":1},{"id":"e7a4cf37-325b-485a-aef7-e23c1ec4fac8","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-400,20],"parameters":{"height":100,"content":"## email writer #1\nGiven the research, this agents writes an email"},"typeVersion":1},{"id":"6b29ded5-fb0a-4c29-8b35-a1a3726dacc3","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[140,400],"parameters":{"height":120,"content":"##  Employee Data \nGather data about the 5 employees we will write emails to."},"typeVersion":1},{"id":"5ba21e97-46f0-4786-8de0-2b06cd2aeed3","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[860,260],"parameters":{"height":140,"content":"## Email Writer #2\nGiven both data about the email and the employee, the agent will write a highly personalized email to each employee\n"},"typeVersion":1},{"id":"5363bc7a-b066-4fad-a5be-3fc9924aff55","name":"Explorium MCP","type":"@n8n/n8n-nodes-langchain.mcpClientTool","position":[-1020,560],"parameters":{"sseEndpoint":"mcp.explorium.ai/sse","authentication":"bearerAuth"},"credentials":{"httpBearerAuth":{"id":"aPjJXei6qDSctHNW","name":"Bearer YOUR_TOKEN_HERE account"}},"typeVersion":1},{"id":"c88fe320-1a7b-4c37-a799-52a06445245a","name":"Webhook - Product Launch","type":"n8n-nodes-base.webhook","position":[-1440,390],"webhookId":"09d12e26-7fb0-492f-913f-119f627de19b","parameters":{"path":"https://lievi.app.n8n.cloud/webhook-test/product-launch","options":{},"httpMethod":"POST"},"typeVersion":2},{"id":"3f116b08-0ba1-45da-89c8-5ebf494fc48d","name":"Explorium Prospects API Call","type":"n8n-nodes-base.httpRequest","position":[-844,390],"parameters":{"url":"https://api.explorium.ai/v1/prospects","method":"POST","options":{},"jsonBody":"={\n  \"mode\": \"full\",\n  \"page\": 1,\n  \"size\": 5,\n  \"page_size\": 5,\n  \"filters\": {\n    \"has_email\": { \"value\": true },\n    \"job_level\": {\n      \"values\": [\"owner\", \"cxo\", \"vp\", \"director\", \"manager\", \"senior\"]\n    },\n    \"job_department\": {\n      \"values\": [\"Marketing\"]\n    },\n    \"business_id\": {\n      \"values\": [\"{{ $('Webhook - Product Launch').item.json.body.business_id }}\"]\n    }\n  }\n}\n","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"accept","value":"application/json"},{"name":"content-type","value":"application/json"},{"name":"api_key","value":""}]}},"typeVersion":4.2},{"id":"3414b8fd-6410-4faa-a81b-f8352abb2f73","name":"Is there data on the company?","type":"n8n-nodes-base.if","position":[-624,390],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"loose"},"combinator":"and","conditions":[{"id":"8627133a-68d0-4907-b8ca-d8deba93089d","operator":{"type":"number","operation":"equals"},"leftValue":"={{ $json.data.length }}\n","rightValue":"=0"}]},"looseTypeValidation":true},"typeVersion":2.2},{"id":"93f5ca4d-b537-4e58-90c3-8fa85a9edf9e","name":"Claude","type":"@n8n/n8n-nodes-langchain.lmChatAnthropic","position":[-316,360],"parameters":{"model":{"__rl":true,"mode":"list","value":"claude-sonnet-4-20250514","cachedResultName":"Claude Sonnet 4"},"options":{}},"credentials":{"anthropicApi":{"id":"FQdE6twB8nCJNoxV","name":"Anthropic account"}},"typeVersion":1.3},{"id":"f0bcac46-cdd7-481b-8d51-b76f2382f0d5","name":"Code - Format Object","type":"n8n-nodes-base.code","position":[-326,540],"parameters":{"jsCode":"const candidates = $input.first().json.data;\n\nif (!Array.isArray(candidates) || candidates.length === 0) {\n  throw new Error(\"No candidates found in data.\");\n}\n\nconst result = candidates.map(candidate => {\n  return {\n    json: {\n      prospect_id: candidate.prospect_id,  \n      full_name: candidate.full_name,\n      first_name: candidate.first_name,\n      last_name: candidate.last_name,\n      title: candidate.job_title,\n      department: candidate.job_department,\n      seniority: candidate.job_seniority_level?.join(', ') || '',\n      company: candidate.company_name,\n      location: `${candidate.city}, ${candidate.region_name}, ${candidate.country_name}`,\n      linkedin: candidate.linkedin,\n      email: candidate.professional_email_hashed || '',\n      experience: candidate.experience?.join(' | ') || '',\n      skills: candidate.skills?.join(', ') || '',\n      interests: candidate.interests?.join(', ') || '',\n      business_id: candidate.business_id\n    }\n  };\n});\n\nreturn result;\n"},"typeVersion":2},{"id":"5122152e-4667-481e-899e-804feae479a2","name":"Code - Get prospect_ids","type":"n8n-nodes-base.code","position":[-28,540],"parameters":{"jsCode":"const prospectIds = $input.all()\n  .map(item => String(item.json.prospect_id).trim()) // Force string and trim whitespace\n  .filter(Boolean); // remove empty/null\n\nreturn [{\n  json: {\n    prospect_ids: prospectIds\n  }\n}];\n"},"typeVersion":2},{"id":"57258b5d-9040-40d0-89d5-4fa9723fe2aa","name":"Send Slack Message","type":"n8n-nodes-base.slack","position":[-28,240],"webhookId":"3bd7b28e-1c59-49a8-bdd0-cb2e314daee6","parameters":{"text":"={{ $json.output }}","user":{"__rl":true,"mode":"list","value":"U08KUURMK2S","cachedResultName":"itamar.levi"},"select":"user","otherOptions":{},"authentication":"oAuth2"},"credentials":{"slackOAuth2Api":{"id":"eOfca8yNWglvt3Ib","name":"Slack account"}},"typeVersion":2.3},{"id":"c47f81d1-fa89-4a69-adb0-b239c5faa526","name":"Explorium Contacts Information API Call","type":"n8n-nodes-base.httpRequest","position":[192,540],"parameters":{"url":"https://api.explorium.ai/v1/prospects/contacts_information/bulk_enrich","method":"POST","options":{},"jsonBody":"={{ JSON.stringify({ prospect_ids: $json.prospect_ids }) }}\n\n","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"accept","value":"application/json"},{"name":"content-type","value":"application/json"},{"name":"api_key","value":""}]}},"typeVersion":4.2},{"id":"58f5da0c-9205-48cc-8965-ccb3c52973f0","name":"Code - Merge profile with email info","type":"n8n-nodes-base.code","position":[412,540],"parameters":{"jsCode":"// Get full profile data from the HTTP Request node\nconst profiles = $('Explorium Prospects API Call').first().json.data;\n\n// Get contact enrichment data from the current input\nconst contactEnrichments = $input.first().json.data;\n\n// Step 1: Create a lookup table for enriched contact info\nconst contactMap = {};\nfor (const contact of contactEnrichments) {\n  contactMap[contact.prospect_id] = contact.data;\n}\n\n// Step 2: Merge profile with email info\nconst result = profiles.map(profile => {\n  const contact = contactMap[profile.prospect_id];\n\n  // Determine the best email\n  let email = profile.email || \"\";\n  if (contact) {\n    email = contact.professions_email ||\n            (contact.emails?.find(e => e.type === \"professional\")?.address) ||\n            (contact.emails?.[0]?.address) ||\n            \"\";\n  }\n\n  return {\n    json: {\n      ...profile,\n      email // now includes enriched email if found\n    }\n  };\n});\n\nreturn result;\n"},"typeVersion":2},{"id":"a3c17adf-18fc-4f93-8324-784c8e18590b","name":"Anthropic - Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatAnthropic","position":[860,580],"parameters":{"model":{"__rl":true,"mode":"list","value":"claude-3-7-sonnet-20250219","cachedResultName":"Claude 3.7 Sonnet"},"options":{}},"credentials":{"anthropicApi":{"id":"FQdE6twB8nCJNoxV","name":"Anthropic account"}},"typeVersion":1.3},{"id":"ede07723-80d0-4de2-90c5-12c45bfbed56","name":"Send Slack","type":"n8n-nodes-base.slack","position":[1228,540],"webhookId":"5d5bb3f1-0bc6-494b-8705-f108ee11b313","parameters":{"text":"={{ $json.output }}","select":"channel","channelId":{"__rl":true,"mode":"list","value":"C08U1DDTQ7Q","cachedResultName":"evergreen-outbound-campaign"},"otherOptions":{},"authentication":"oAuth2"},"credentials":{"slackOAuth2Api":{"id":"eOfca8yNWglvt3Ib","name":"Slack account"}},"typeVersion":2.3}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"","connections":{"Claude":{"ai_languageModel":[[{"node":"Email Writer (NO prospect data)","type":"ai_languageModel","index":0}]]},"Send Slack":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Explorium MCP":{"ai_tool":[[{"node":"Company Researcher","type":"ai_tool","index":0}]]},"Loop Over Items":{"main":[[],[{"node":"Email Writer ( YES prospect data)","type":"main","index":0}]]},"Company Researcher":{"main":[[{"node":"Explorium Prospects API Call","type":"main","index":0}]]},"Anthropic Chat Model":{"ai_languageModel":[[{"node":"Company Researcher","type":"ai_languageModel","index":0}]]},"Code - Format Object":{"main":[[{"node":"Code - Get prospect_ids","type":"main","index":0}]]},"Anthropic - Chat Model":{"ai_languageModel":[[{"node":"Email Writer ( YES prospect data)","type":"ai_languageModel","index":0}]]},"Code - Get prospect_ids":{"main":[[{"node":"Explorium Contacts Information API Call","type":"main","index":0}]]},"Webhook - Product Launch":{"main":[[{"node":"Company Researcher","type":"main","index":0}]]},"Explorium Prospects API Call":{"main":[[{"node":"Is there data on the company?","type":"main","index":0}]]},"Is there data on the company?":{"main":[[{"node":"Email Writer (NO prospect data)","type":"main","index":0}],[{"node":"Code - Format Object","type":"main","index":0}]]},"Email Writer (NO prospect data)":{"main":[[{"node":"Send Slack Message","type":"main","index":0}]]},"Email Writer ( YES prospect data)":{"main":[[{"node":"Send Slack","type":"main","index":0}]]},"Code - Merge profile with email info":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Explorium Contacts Information API Call":{"main":[[{"node":"Code - Merge profile with email info","type":"main","index":0}]]}}}


name: Automate Glassdoor Job Search with Bright Data Scraping & Google Sheets Storage
author_name: Bright Data
author_username: bright-data
nodes_used: ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest"]
categories: []
created_at: 2025-06-10T07:48:33.357Z
updated_at: 2025-06-10T07:48:33.357Z
url: https://n8n.io/workflows/4843
scraped_at: 2025-07-06 21:16:30
description:
  🔍 Glassdoor Job Finder: Bright Data Scraping + Keyword-Based Automation

  A comprehensive n8n automation that scrapes Glassdoor job listings using Bright Data's web scraping service based on user-defined keywords, location, and country parameters, then automatically stores the results in Google Sheets.

  📋 Overview

  This workflow provides an automated job search solution that extracts job listings from Glassdoor using form-based inputs and stores organized results in Google Sheets. Perfect for recruiters, job seekers, market research, and competitive analysis.

  Workflow Description: Automates Glassdoor job searches using Bright Data's web scraping capabilities. Users submit keywords, location, and country via form trigger. The workflow scrapes job listings, extracts company details, ratings, and locations, then automatically stores organized results in Google Sheets for easy analysis and tracking.

  ✨ Key Features

  🎯 Form-Based Input: Simple web form for job type, location, and country
  🔍 Glassdoor Integration: Uses Bright Data's Glassdoor dataset for accurate job data
  📊 Smart Data Processing: Automatically extracts key job information
  📈 Google Sheets Storage: Organized data storage with automatic updates
  🔄 Status Monitoring: Built-in progress tracking and retry logic
  ⚡ Fast & Reliable: Professional scraping with error handling
  🎯 Keyword Flexibility: Search any job type with location filters
  📝 Structured Output: Clean, organized job listing data

  🎯 What This Workflow Does

  Input
  Job Keywords:** Job title or role (e.g., "Software Engineer", "Marketing Manager")
  Location:** City or region for job search
  Country:** Target country for job listings

  Processing
  Form Submission
  Data Scraping via Bright Data
  Status Monitoring
  Data Extraction
  Data Processing
  Sheet Update

  Output Data Points

  | Field | Description | Example |
  |-------|-------------|---------|
  | Job Title | Position title from listing | Senior Software Engineer |
  | Company Name | Employer name | Google Inc. |
  | Location | Job location | San Francisco, CA |
  | Rating | Company rating score | 4.5 |
  | Job Link | Direct URL to listing | https://glassdoor.com/job/... |

  🚀 Setup Instructions

  Prerequisites
  n8n instance (self-hosted or cloud)
  Google account with Sheets access
  Bright Data account with Glassdoor scraping dataset access
  5–10 minutes for setup

  Step 1: Import the Workflow
  Copy the JSON workflow code from the provided file
  In n8n: Workflows → + Add workflow → Import from JSON
  Paste JSON and click Import

  Step 2: Configure Bright Data
  Set up Bright Data credentials in n8n
  Ensure access to dataset: gd_lpfbbndm1xnopbrcr0
  Update API tokens in:
     "Scrape Job Data" node
     "Check Delivery Status of Snap ID" node
     "Getting Job Lists" node

  Step 3: Configure Google Sheets Integration
  Create a new Google Sheet (e.g., "Glassdoor Job Tracker")
  Set up Google Sheets OAuth2 credentials in n8n
  Prepare columns:
     Column A: Job Title
     Column B: Company Name
     Column C: Location
     Column D: Rating
     Column E: Job Link

  Step 4: Update Workflow Settings
  Update "Update Job List" node with your Sheet ID and credentials
  Test the form trigger and webhook URL

  Step 5: Test & Activate
  Submit test data (e.g., "Software Engineer" in "New York")
  Activate the workflow
  Verify Google Sheet updates and field extraction

  📖 Usage Guide

  Submitting Job Searches
  Navigate to your workflow's webhook URL
  Fill in:
     Search Job Type
     Location
     Country
  Submit the form

  Reading the Results
  Real-time job listing data
  Company ratings and reviews
  Direct job posting links
  Location-specific results
  Processing timestamps

  🔧 Customization Options
  More Data Points:** Add job descriptions, salary, company size, etc.
  Search Parameters:** Add filters for salary, experience, remote work
  Data Processing:** Add validation, deduplication, formatting

  🚨 Troubleshooting
  Bright Data connection failed:** Check API credentials and dataset access
  No job data extracted:** Validate search terms and location format
  Google Sheets permission denied:** Re-authenticate and check sharing
  Form submission failed:** Check webhook URL and form config
  Workflow execution failed:** Check logs, add retry logic

  Advanced Troubleshooting
  Check execution logs in n8n
  Test individual nodes
  Verify data formats
  Monitor rate limits
  Add error handling

  📊 Use Cases & Examples
  Recruitment Pipeline:** Track job postings, build talent database
  Market Research:** Analyze job trends, hiring patterns
  Career Development:** Monitor opportunities, salary trends
  Competitive Intelligence:** Track competitor hiring activity

  ⚙️ Advanced Configuration
  Batch Processing:** Accept multiple keywords, loop logic, delays
  Search History:** Track trends, compare results over time
  External Tools:** Integrate with CRM, Slack, databases, BI tools

  📈 Performance & Limits
  Single search:** 2–5 minutes
  Data accuracy:** 95%+
  Success rate:** 90%+
  Concurrent searches:** 1–3 (depends on plan)
  Daily capacity:** 50–200 searches
  Memory:** ~50MB per execution
  API calls:** 3 Bright Data + 1 Google Sheets per search

  🤝 Support & Community
  n8n Community Forum:** community.n8n.io
  Documentation:** docs.n8n.io
  Bright Data Support:** Via your dashboard
  GitHub Issues:** Report bugs and features

  Contributing: Share improvements, report issues, create variations, document best practices.

  Need Help? Check the full documentation or visit the n8n Community for support and workflow examples.

workflow_json:
  {"id":"CKmCHe6ST5Fn0bDm","meta":{"instanceId":"bc8ca75c203589705ae2e446cad7181d6f2a7cc1766f958ef9f34810e53b8cb2","templateCredsSetupCompleted":true},"name":"Glassdoor Job Finder: Bright Data Scraping + Keyword-Based Automation","tags":[],"nodes":[{"id":"ce3a7e97-41b6-49fc-ae23-cbf65044a974","name":"On form submission","type":"n8n-nodes-base.formTrigger","position":[-800,0],"webhookId":"9b16a680-d396-41ee-8304-44a430954ad7","parameters":{"options":{},"formTitle":"Search Job Listings Using Keywords","formFields":{"values":[{"fieldLabel":"Location"},{"fieldLabel":"Search Job type"},{"fieldLabel":"country"}]}},"typeVersion":2.2},{"id":"10cbb574-3967-490a-9c57-c1140a04af00","name":"Check Delivery Status of Snap ID","type":"n8n-nodes-base.httpRequest","position":[-280,0],"parameters":{"url":"=https://api.brightdata.com/datasets/v3/progress/{{ $json.snapshot_id }}","options":{},"sendHeaders":true,"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2,"alwaysOutputData":true},{"id":"c1090f01-84ab-4586-8c0e-4a2f3a5fc389","name":"Check Final Status","type":"n8n-nodes-base.if","position":[220,0],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"or","conditions":[{"id":"35ed620d-b5d5-4e97-bcc5-52b283d85616","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"ready"}]}},"typeVersion":2.2},{"id":"1cc8376f-393f-48cc-8bb3-93cfafa28d58","name":"Wait 1 minute","type":"n8n-nodes-base.wait","position":[-20,0],"webhookId":"10b45556-5e91-4387-abd0-f9078b220286","parameters":{"unit":"minutes","amount":1},"typeVersion":1.1},{"id":"c9157c5c-bcab-462c-9ace-6f5e456e186c","name":"Scrap data","type":"n8n-nodes-base.httpRequest","position":[-580,0],"parameters":{"url":"https://api.brightdata.com/datasets/v3/trigger","method":"POST","options":{},"jsonBody":"={\n  \"input\": [\n    {\n      \"keyword\": \"{{ $json['Search Job type'] }}\",\n      \"location\": \"{{ $json['Location'] }}\",\n      \"country\": \"{{ $json['country'] }}\"\n    }\n  ],\n  \"custom_output_fields\": [\n    \"url\",\n    \"company_name\",\n    \"company_rating\",\n    \"job_title\",\n    \"job_location\",\n    \"company_website\"\n  ]\n}","sendBody":true,"sendQuery":true,"sendHeaders":true,"specifyBody":"json","queryParameters":{"parameters":[{"name":"dataset_id","value":"gd_lpfbbndm1xnopbrcr0"},{"name":"include_errors","value":"true"},{"name":"type","value":"discover_new"},{"name":"discover_by","value":"keyword"},{"name":"limit_per_input","value":"5"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2},{"id":"f1a0e9ed-ced0-4eb6-8eeb-6c7537c7822f","name":"Getting Job Lists","type":"n8n-nodes-base.httpRequest","position":[480,-20],"parameters":{"url":"=https://api.brightdata.com/datasets/v3/snapshot/{{ $json.snapshot_id }}","options":{},"sendQuery":true,"sendHeaders":true,"queryParameters":{"parameters":[{"name":"format","value":"json"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2},{"id":"558543dc-af03-4033-990a-d850614150fe","name":"Update List","type":"n8n-nodes-base.googleSheets","position":[820,-20],"parameters":{"columns":{"value":{"Rating":"={{ $json.company_rating }}","Job Link":"={{ $json.company_website }}","Location":"={{ $json.job_location }}","Job Title":"={{ $json.job_title }}","Company Name":"={{ $json.company_name }}"},"schema":[{"id":"Job Title","type":"string","display":true,"removed":false,"required":false,"displayName":"Job Title","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Company Name","type":"string","display":true,"removed":false,"required":false,"displayName":"Company Name","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Location","type":"string","display":true,"removed":false,"required":false,"displayName":"Location","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Rating","type":"string","display":true,"removed":false,"required":false,"displayName":"Rating","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Salary Estimate","type":"string","display":true,"removed":true,"required":false,"displayName":"Salary Estimate","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Job Posted Date","type":"string","display":true,"removed":true,"required":false,"displayName":"Job Posted Date","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Job Link","type":"string","display":true,"removed":false,"required":false,"displayName":"Job Link","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["Job Link"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"appendOrUpdate","sheetName":{"__rl":true,"mode":"list","value":193286695,"cachedResultUrl":"https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID/edit#gid=193286695","cachedResultName":"Glassdoor Scraper by keyword"},"documentId":{"__rl":true,"mode":"list","value":"YOUR_GOOGLE_SHEET_ID","cachedResultUrl":"https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID/edit?usp=drivesdk","cachedResultName":"Data Scraper Yelp, Glassdoor,Tictok"}},"credentials":{"googleSheetsOAuth2Api":{"id":"YOUR_GOOGLE_SHEETS_CREDENTIAL_ID","name":"Google Sheets Credential"}},"typeVersion":4.6},{"id":"2ad5e448-ae48-4ae8-a8e7-243101810613","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-880,-100],"parameters":{"height":260,"content":"Triggers the workflow when the user submits the job type, location, and country via form."},"typeVersion":1},{"id":"02a1a60f-b11f-4981-81c3-c4e86f2e95d2","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-620,-100],"parameters":{"color":2,"width":260,"height":260,"content":"Calls Bright Data API to initiate scraping Glassdoor job listings based on the form input (keyword, location, country)."},"typeVersion":1},{"id":"32d05b44-e78e-4f09-9626-c25bbc1b8c6b","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-60,-100],"parameters":{"color":3,"width":220,"height":260,"content":"Pauses the workflow for 1 minute before rechecking status (to allow data generation)."},"typeVersion":1},{"id":"b7085f2b-c2ae-4f68-926d-ca6658ea9215","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-340,-100],"parameters":{"color":5,"width":260,"height":260,"content":"Checks the scraping task's status using Bright Data snapshot ID to monitor progress."},"typeVersion":1},{"id":"eee21db7-8bad-4c59-9dcd-ab95eb5501c9","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[420,-100],"parameters":{"color":7,"width":280,"height":280,"content":"Conditional node that checks if Bright Data has marked the scraping job as \"ready\". Loops back to check if not ready."},"typeVersion":1},{"id":"9b59c3c5-8e07-4082-a8b9-6657055d4e5f","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[720,-120],"parameters":{"color":4,"width":280,"height":340,"content":"Appends or updates job data (title, company, rating, location, link) in Google Sheets under the \"Glassdoor Scraper by keyword\" tab."},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"24dfda04-3ea1-45c2-bbf3-ef335974f595","connections":{"Scrap data":{"main":[[{"node":"Check Delivery Status of Snap ID","type":"main","index":0}]]},"Wait 1 minute":{"main":[[{"node":"Check Final Status","type":"main","index":0}]]},"Getting Job Lists":{"main":[[{"node":"Update List","type":"main","index":0}]]},"Check Final Status":{"main":[[{"node":"Getting Job Lists","type":"main","index":0}],[{"node":"Check Delivery Status of Snap ID","type":"main","index":0}]]},"On form submission":{"main":[[{"node":"Scrap data","type":"main","index":0}]]},"Check Delivery Status of Snap ID":{"main":[[{"node":"Wait 1 minute","type":"main","index":0}]]}}}


name: Scrape Yelp Business Data with Gemini AI, Bright Data & Google Sheets
author_name: Bright Data
author_username: bright-data
categories: []
created_at: 2025-06-10T07:53:49.388Z
updated_at: 2025-06-10T07:53:49.388Z
url: https://n8n.io/workflows/4844
scraped_at: 2025-07-06 21:16:30
description:
  🔍 Yelp Business Finder: Scraping Local Businesses by Keyword, Category & Location Using Bright Data and Google Sheets

  Description: Automate local business data collection from Yelp using AI-powered input validation, Bright Data scraping, and automatic Google Sheets integration. Perfect for market research, lead generation, and competitive analysis.

  🛠️ How It Works

  Form Submission: Users submit a simple form with country, location, and business category parameters.

  AI Validation: Google Gemini AI validates and cleans input data, ensuring proper formatting and Yelp category alignment.

  Data Scraping: Bright Data's Yelp dataset API scrapes business information based on the cleaned parameters.

  Status Monitoring: The workflow monitors scraping progress and waits for data completion.

  Data Export: Final business data is automatically appended to your Google Sheets for easy analysis.

  📋 Setup Steps

  ⏱️ Estimated Setup Time: 10-15 minutes

  Prerequisites

  ✅ Active n8n instance (cloud or self-hosted)
  ✅ Google account with Sheets access
  ✅ Bright Data account with Yelp scraping dataset
  ✅ Google Gemini API access

  Configuration Steps

  Import Workflow:
     Copy the provided JSON workflow
     In n8n: Go to Workflows → + Add workflow → Import from JSON
     Paste the JSON and click Import

  Configure Google Sheets:
     Create a new Google Sheet or use an existing one
     Set up OAuth2 credentials in n8n
     Update the Google Sheets node with your document ID
     Configure column mappings for business data

  Setup Bright Data:
     Add your Bright Data API credentials to n8n
     Replace BRIGHT_DATA_API_KEY with your actual API key
     Verify your Yelp dataset ID in the HTTP request nodes
     Test the connection

  Configure Google Gemini:
     Add your Google Gemini API credentials
     Test the AI Agent connection
     Verify the model configuration

  Test & Activate:
     Activate the workflow using the toggle switch
     Test with sample data: country="US", location="New York", category="restaurants"
     Verify data appears correctly in your Google Sheet

  📊 Data Output

  📍 Business Name  
  Official business name from Yelp

  ⭐ Overall Rating  
  Average customer rating (1-5 stars)

  📝 Reviews Count  
  Total number of customer reviews

  🏷️ Categories  
  Business categories and tags

  🌐 Website URL  
  Official business website

  📞 Phone Number  
  Contact phone number

  📍 Address  
  Full business address

  🔗 Yelp URL  
  Direct link to Yelp listing

  🎯 Use Cases

  🔍 Market Research  
  Analyze local business landscapes and competition

  📈 Lead Generation  
  Build prospect lists for B2B outreach

  🏪 Location Analysis  
  Research business density by area and category

  📊 Competitive Intelligence  
  Monitor competitor ratings and customer feedback

  ⚠️ Important Notes:
  Ensure you comply with Yelp's terms of service and rate limits
  Bright Data usage may incur costs based on your plan
  AI validation helps improve data quality and reduce errors
  Monitor your Google Sheets for data accuracy

  🔧 Troubleshooting

  Common Issues:
  API Rate Limits:** Implement delays between requests if needed
  Invalid Categories:** AI agent helps standardize category names
  Empty Results:** Verify location spelling and category alignment
  Authentication Errors:** Check all API credentials and permissions

  🚀 Ready to start scraping Yelp business data efficiently!

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

workflow_json:
  {"id":"a7VCjCT0yD0Ej6Wm","meta":{"instanceId":"bc8ca75c203589705ae2e446cad7181d6f2a7cc1766f958ef9f34810e53b8cb2","templateCredsSetupCompleted":true},"name":"Yelp Business Finder: Scraping Local Businesses by Keyword, Category & Location Using Bright Data and Google Sheets","tags":[],"nodes":[{"id":"56103501-5678-4e90-924a-c41dc5652c53","name":"Fetch Snapshot Results","type":"n8n-nodes-base.httpRequest","position":[-640,-460],"parameters":{"url":"=https://api.brightdata.com/datasets/v3/snapshot/{{ $json.snapshot_id }}","options":{},"sendQuery":true,"sendHeaders":true,"queryParameters":{"parameters":[{"name":"format","value":"json"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2},{"id":"b331c7cd-dfe8-47f2-896e-a062a3801b8a","name":"On Form Submission","type":"n8n-nodes-base.formTrigger","position":[-3040,-440],"webhookId":"37d0e84c-0cda-47f8-826d-9ae5b22ba1d5","parameters":{"options":{},"formTitle":"YelpDataScraper","formFields":{"values":[{"fieldLabel":"country"},{"fieldLabel":"category"},{"fieldLabel":"location"}]}},"typeVersion":2.2},{"id":"304245ae-cda6-430d-9f6c-9a0b66781db1","name":"Check Delivery Status of Snapshot ID","type":"n8n-nodes-base.httpRequest","position":[-1640,-440],"parameters":{"url":"=https://api.brightdata.com/datasets/v3/progress/{{ $json.snapshot_id }}","options":{},"sendHeaders":true,"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2,"alwaysOutputData":true},{"id":"a26943e0-ca71-460a-8eee-df027866997f","name":"Check Final Status","type":"n8n-nodes-base.if","position":[-1000,-440],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"or","conditions":[{"id":"35ed620d-b5d5-4e97-bcc5-52b283d85616","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"ready"}]}},"typeVersion":2.2},{"id":"d60385e6-5093-439e-9b70-3dbeb8f9f537","name":"Wait 1 Minute","type":"n8n-nodes-base.wait","position":[-1320,-440],"webhookId":"10b45556-5e91-4387-abd0-f9078b220286","parameters":{"unit":"minutes","amount":1},"typeVersion":1.1},{"id":"14d497b0-819b-4106-b095-439b63a77fd5","name":"Google Sheets - Save Business Data","type":"n8n-nodes-base.googleSheets","position":[-280,-460],"parameters":{"columns":{"value":{"url":"={{ $json.url }}","name":"={{ $json.name }}","address":"={{ $json.address }}","website":"={{ $json.website }}","categories":"={{ $json.categories }}","phone_number":"={{ $json.phone_number }}","reviews_count":"={{ $json.reviews_count }}","overall_rating":"={{ $json.overall_rating }}"},"schema":[{"id":"overall_rating","type":"string","display":true,"removed":false,"required":false,"displayName":"overall_rating","defaultMatch":false,"canBeUsedToMatch":true},{"id":"reviews_count","type":"string","display":true,"removed":false,"required":false,"displayName":"reviews_count","defaultMatch":false,"canBeUsedToMatch":true},{"id":"url","type":"string","display":true,"removed":false,"required":false,"displayName":"url","defaultMatch":false,"canBeUsedToMatch":true},{"id":"name","type":"string","display":true,"removed":false,"required":false,"displayName":"name","defaultMatch":false,"canBeUsedToMatch":true},{"id":"categories","type":"string","display":true,"removed":false,"required":false,"displayName":"categories","defaultMatch":false,"canBeUsedToMatch":true},{"id":"website","type":"string","display":true,"removed":false,"required":false,"displayName":"website","defaultMatch":false,"canBeUsedToMatch":true},{"id":"phone_number","type":"string","display":true,"removed":false,"required":false,"displayName":"phone_number","defaultMatch":false,"canBeUsedToMatch":true},{"id":"address","type":"string","display":true,"removed":false,"required":false,"displayName":"address","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/YOUR_GOOGLE_SHEET_ID/edit#gid=0","cachedResultName":"Yelp scraper data by keyword"},"documentId":{"__rl":true,"mode":"list","value":"YOUR_GOOGLE_SHEET_ID","cachedResultUrl":"https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID/edit?usp=drivesdk","cachedResultName":"Yelp Business Data Scraper"}},"credentials":{"googleSheetsOAuth2Api":{"id":"YOUR_GOOGLE_SHEETS_CREDENTIAL_ID","name":"Google Sheets OAuth2"}},"typeVersion":4.6},{"id":"821ee30e-faaf-4d97-b0bc-cd81b9162e27","name":"AI Agent - Validate Input","type":"@n8n/n8n-nodes-langchain.agent","position":[-2740,-440],"parameters":{"text":"=You are an intelligent assistant helping to extract structured business data using Bright Data. Based on the user's form inputs, generate a concise and clear structured JSON block that maximizes accuracy and relevance for the data scraper.\n\nInput:\n- Country: {{ $json.country }}\n- Location: {{ $json.location }}\n- Category: {{ $json.category }}\n\nYour task:\n1. Validate and clean the location and category (remove typos, use popular names).\n2. Convert the inputs into a well-formatted JSON object optimized for Bright Data's \"search_filters\" scraping.\n3. Ensure the `category` aligns with Yelp's known categories.\n4. Include synonyms or nearby areas in location if needed.\n\nRespond ONLY with a cleaned JSON block like:\n```json\n{\n  \"country\": \"{{ $json.country }}\",\n  \"location\": \"{{ $json.location }}\",\n  \"category\": \"{{ $json.category }}\"\n}\nRespond only with a valid compact JSON object like:\n{\"country\": \"...\", \"location\": \"...\", \"category\": \"...\"}\nNo explanation or markdown.\n","options":{},"promptType":"define"},"typeVersion":2},{"id":"067bdca2-7be4-4af5-add5-4a0b911ae870","name":"Google Gemini Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[-2820,-60],"parameters":{"options":{},"modelName":"models/gemini-1.5-flash"},"credentials":{"googlePalmApi":{"id":"YOUR_GOOGLE_GEMINI_CREDENTIAL_ID","name":"Google Gemini API"}},"typeVersion":1},{"id":"c09661f3-c8b8-4b75-9515-999a088abb46","name":"Format AI Response for Scraper","type":"n8n-nodes-base.code","position":[-2360,-440],"parameters":{"jsCode":"const rawOutput = $json.output || \"\";\n\n// Clean triple backticks if AI added them\nconst cleaned = rawOutput\n  .replace(/```json/g, '')\n  .replace(/```/g, '')\n  .trim();\n\n// Try to parse\nlet parsed;\ntry {\n  parsed = JSON.parse(cleaned);\n} catch (error) {\n  throw new Error(\"❌ JSON parse failed: \" + error.message + \"\\n\\nRaw cleaned output:\\n\" + cleaned);\n}\n\n// Log parsed output for debugging\nif (!parsed || !parsed.country || !parsed.location || !parsed.category) {\n  throw new Error(\"❌ Missing required fields.\\n\\nParsed Object:\\n\" + JSON.stringify(parsed, null, 2));\n}\n\n// Return structured JSON\nreturn [\n  {\n    json: {\n      country: parsed.country.trim(),\n      location: parsed.location.trim(),\n      category: parsed.category.trim()\n    }\n  }\n];\n"},"typeVersion":2},{"id":"66e5c0f7-5964-4ea0-b753-7671a315a31e","name":"Yelp Data Scraper - Bright Data","type":"n8n-nodes-base.httpRequest","position":[-2020,-440],"parameters":{"url":"https://api.brightdata.com/datasets/v3/trigger","method":"POST","options":{},"jsonBody":"={\n  \"input\": [\n    {\n      \"country\": \"{{ $json.country }}\",\n      \"location\": \"{{ $json.location }}\",\n      \"category\": \"{{ $json.category }}\"\n    }\n  ],\n  \"custom_output_fields\": [\n    \"name\",\n    \"overall_rating\",\n    \"reviews_count\",\n    \"categories\",\n    \"website\",\n    \"phone_number\",\n    \"address\",\n    \"url\"\n  ]\n}\n","sendBody":true,"sendQuery":true,"sendHeaders":true,"specifyBody":"json","queryParameters":{"parameters":[{"name":"dataset_id","value":"YOUR_YELP_DATASET_ID"},{"name":"include_errors","value":"true"},{"name":"type","value":"discover_new"},{"name":"discover_by","value":"search_filters"},{"name":"limit_per_input","value":"10"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2},{"id":"8c51dc47-d5a0-4ca5-8567-4800a953b8cb","name":"Sticky Note - Form Trigger","type":"n8n-nodes-base.stickyNote","position":[-3100,-580],"parameters":{"width":280,"height":340,"content":"🟢 1. On Form Submission\nTriggers the workflow when the user submits a form with country, location, and category values for Yelp business scraping."},"typeVersion":1},{"id":"ba8030a4-77c1-44d1-8002-dd18e526e96a","name":"Sticky Note - AI Validation","type":"n8n-nodes-base.stickyNote","position":[-2800,-580],"parameters":{"color":3,"width":360,"height":320,"content":"🤖 2. AI Agent - Validate Input\nUses Google Gemini AI to validate and clean the user's inputs (country, location, category) for proper formatting and relevance to Yelp categories."},"typeVersion":1},{"id":"42012c98-457e-4ddf-8e5d-fd383a05a78d","name":"Sticky Note - AI Model","type":"n8n-nodes-base.stickyNote","position":[-3040,-160],"parameters":{"color":4,"width":620,"height":240,"content":"🔵 3. Google Gemini Chat Model\nProvides AI capabilities to transform raw form inputs into clean, structured JSON optimized for Bright Data's search filters."},"typeVersion":1},{"id":"63626dab-0eac-45ca-8b94-0824673d32ff","name":"Sticky Note - Format Response","type":"n8n-nodes-base.stickyNote","position":[-2420,-560],"parameters":{"color":5,"width":280,"height":300,"content":"🔧 4. Format AI Response for Scraper\nParses the cleaned JSON returned by the AI and ensures it's properly formatted for Bright Data API consumption."},"typeVersion":1},{"id":"8beb6d5f-eb92-4c10-8b95-6241973e4b75","name":"Sticky Note - Data Scraper","type":"n8n-nodes-base.stickyNote","position":[-2120,-560],"parameters":{"color":6,"width":300,"height":300,"content":"🌐 5. Yelp Data Scraper - Bright Data\nSends the cleaned JSON input to Bright Data's Yelp dataset using the search_filters trigger to extract business information."},"typeVersion":1},{"id":"75affc5d-d11b-4ad7-a3ef-e7adcca1a3d1","name":"Sticky Note - Status Check","type":"n8n-nodes-base.stickyNote","position":[-1760,-560],"parameters":{"color":3,"width":340,"height":300,"content":"⏱ 6. Check Delivery Status of Snapshot ID\nMonitors the progress of the Bright Data scraping task using the snapshot_id returned from the previous step."},"typeVersion":1},{"id":"f61ef2ba-c05a-4f24-8fb0-1fce34ab8413","name":"Sticky Note - Wait Timer","type":"n8n-nodes-base.stickyNote","position":[-1380,-560],"parameters":{"color":4,"width":280,"height":320,"content":"⏰ 7. Wait 1 Minute\nWaits for 1 minute before rechecking Bright Data status to allow sufficient time for the data scraping to complete."},"typeVersion":1},{"id":"bac612fb-371d-499f-89c8-08b4a3c859ca","name":"Sticky Note - Final Status","type":"n8n-nodes-base.stickyNote","position":[-1100,-560],"parameters":{"color":5,"width":320,"height":300,"content":"🔄 8. Check Final Status\nConditionally checks if the status from Bright Data is \"ready\". If not ready, loops back to wait again until data is available."},"typeVersion":1},{"id":"92ee614c-78b6-4593-88d9-69b23abd5255","name":"Sticky Note - Fetch Results","type":"n8n-nodes-base.stickyNote","position":[-700,-560],"parameters":{"color":6,"width":280,"height":300,"content":"📥 9. Fetch Snapshot Results\nWhen Bright Data status is \"ready\", this step fetches the complete dataset snapshot containing all scraped Yelp business data."},"typeVersion":1},{"id":"c55c18e9-9bd1-401e-bce6-b980f3559c79","name":"Sticky Note - Save Data","type":"n8n-nodes-base.stickyNote","position":[-360,-560],"parameters":{"color":3,"width":280,"height":300,"content":"📊 10. Google Sheets - Save Business Data\nAppends the final Yelp business data (name, rating, reviews, phone, website, address, etc.) into your designated Google Sheet."},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"c092b9ac-181d-4332-8137-43080e4fe924","connections":{"Wait 1 Minute":{"main":[[{"node":"Check Final Status","type":"main","index":0}]]},"Check Final Status":{"main":[[{"node":"Fetch Snapshot Results","type":"main","index":0}],[{"node":"Check Delivery Status of Snapshot ID","type":"main","index":0}]]},"On Form Submission":{"main":[[{"node":"AI Agent - Validate Input","type":"main","index":0}]]},"Fetch Snapshot Results":{"main":[[{"node":"Google Sheets - Save Business Data","type":"main","index":0}]]},"Google Gemini Chat Model":{"ai_languageModel":[[{"node":"AI Agent - Validate Input","type":"ai_languageModel","index":0}]]},"AI Agent - Validate Input":{"main":[[{"node":"Format AI Response for Scraper","type":"main","index":0}]]},"Format AI Response for Scraper":{"main":[[{"node":"Yelp Data Scraper - Bright Data","type":"main","index":0}]]},"Yelp Data Scraper - Bright Data":{"main":[[{"node":"Check Delivery Status of Snapshot ID","type":"main","index":0}]]},"Check Delivery Status of Snapshot ID":{"main":[[{"node":"Wait 1 Minute","type":"main","index":0}]]}}}


name: Generate AI Videos with Google Veo3, Save to Google Drive and Upload to YouTube
author_name: Davide
author_username: n3witalia
categories: []
created_at: 2025-06-10T08:27:01.375Z
updated_at: 2025-06-10T08:27:01.375Z
url: https://n8n.io/workflows/4846
scraped_at: 2025-07-06 21:16:30
description:
  This workflow allows users to generate AI videos using Google Veo3, save them to Google Drive, generate optimized YouTube titles with GPT-4o, and automatically upload them to YouTube . The entire process is triggered from a Google Sheet that acts as the central interface for input and output.

  IT automates video creation, uploading, and tracking, ensuring seamless integration between Google Sheets, Google Drive, Google Veo3, and YouTube.

  Benefits of this Workflow

  💡 No Code Interface**: Trigger and control the video production pipeline from a simple Google Sheet.
  ⚙️ Full Automation**: Once set up, the entire video generation and publishing process runs hands-free.
  🧠 AI-Powered Creativity**:

    Generates engaging YouTube titles using GPT-4o.
    Leverages advanced generative video AI from Google Veo3.
  📁 Cloud Storage & Backup**: Stores all generated videos on Google Drive for safekeeping.
  📈 YouTube Ready**: Automatically uploads to YouTube with correct metadata, saving time and boosting visibility.
  🧪 Scalable**: Designed to process multiple video prompts by looping through new entries in Google Sheets.
  🔒 API-First**: Utilizes secure API-based communication for all services.

  How It Works  
  Trigger: The workflow can be started manually ("When clicking ‘Test workflow’") or scheduled ("Schedule Trigger") to run at regular intervals (e.g., every 5 minutes).  
  Fetch Data: The "Get new video" node retrieves unfilled video requests from a Google Sheet (rows where the "VIDEO" column is empty).  
  Video Creation:  
     The "Set data" node formats the prompt and duration from the Google Sheet.  
     The "Create Video" node sends a request to the Fal.run API (Google Veo3) to generate a video based on the prompt.  
  Status Check:  
     The "Wait 60 sec." node pauses execution for 60 seconds.  
     The "Get status" node checks the video generation status. If the status is "COMPLETED," the workflow proceeds; otherwise, it waits again.  
  Video Processing:  
     The "Get Url Video" node fetches the video URL.  
     The "Generate title" node uses OpenAI (GPT-4.1) to create an SEO-optimized YouTube title.  
     The "Get File Video" node downloads the video file.  
  Upload & Update:  
     The "Upload Video" node saves the video to Google Drive.  
     The "HTTP Request" node uploads the video to YouTube via the Upload-Post API.  
     The "Update Youtube URL" and "Update result" nodes update the Google Sheet with the video URL and YouTube link.  

  Set Up Steps  
  Google Sheet Setup:  
     Create a Google Sheet with columns: PROMPT, DURATION, VIDEO, and YOUTUBE_URL.  
     Share the Sheet link in the "Get new video" node.  

  API Keys:  
     Obtain a Fal.run API key (for Veo3) and set it in the "Create Video" node (Header: Authorization: Key YOURAPIKEY).  
     Get an Upload-Post API key (for YouTube uploads) and configure the "HTTP Request" node (Header: Authorization: Apikey YOUR_API_KEY).  

  YouTube Upload Configuration:  
     Replace YOUR_USERNAME in the "HTTP Request" node with your Upload-Post profile name.  

  Schedule Trigger:  
     Configure the "Schedule Trigger" node to run periodically (e.g., every 5 minutes).  

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

nodes_used:
  ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest","n8n-nodes-base.googleDrive","@n8n/n8n-nodes-langchain.openAi"]

workflow_json:
  {"id":"g1hmK8jw38TOYX7D","meta":{"instanceId":"a4bfc93e975ca233ac45ed7c9227d84cf5a2329310525917adaf3312e10d5462","templateCredsSetupCompleted":true},"name":"Create Video with Google Veo3 and Upload to Youtube","tags":[],"nodes":[{"id":"f1fcb9ab-37aa-44a3-91fc-8480351aa5cd","name":"When clicking ‘Test workflow’","type":"n8n-nodes-base.manualTrigger","position":[-220,840],"parameters":{},"typeVersion":1},{"id":"58194812-a64d-401e-be5e-2f1ba9210557","name":"Get status","type":"n8n-nodes-base.httpRequest","position":[840,840],"parameters":{"url":"=https://queue.fal.run/fal-ai/veo3/requests/{{ $('Create Video').item.json.request_id }}/status ","options":{},"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"daOZafXpRXLtoLUV","name":"Fal.run API"}},"typeVersion":4.2},{"id":"1e23339c-f829-4426-b4f6-b02add8f8c5e","name":"Wait 60 sec.","type":"n8n-nodes-base.wait","position":[660,840],"webhookId":"490facb8-d0ae-402e-ab59-a87720cf0bdd","parameters":{"amount":60},"typeVersion":1.1},{"id":"98ad8a6d-9ded-4f4e-a4ef-b624f7fe7e39","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[-220,700],"parameters":{"rule":{"interval":[{"field":"minutes"}]}},"typeVersion":1.2},{"id":"262608c6-e905-4d16-bc52-22b67c1bc298","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-220,-460],"parameters":{"color":3,"width":740,"height":280,"content":"# Generate AI Videos with Google Veo3, Save to Google Drive and Upload to YouTube\n\nThis workflow allows users to **generate AI videos** using **Google Veo3**, save them to **Google Drive**, generate optimized YouTube titles with GPT-4o, and **automatically upload them to YouTube** . The entire process is triggered from a Google Sheet that acts as the central interface for input and output.\n\nIT automates video creation, uploading, and tracking, ensuring seamless integration between Google Sheets, Google Drive, Google Veo3, and YouTube.\n\n\n\n\n"},"typeVersion":1},{"id":"1ea1879e-1e8e-42f9-8b11-7f771cfca2f8","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-220,-140],"parameters":{"width":740,"height":200,"content":"## STEP 1 - GOOGLE SHEET\nCreate a [Google Sheet like this](https://docs.google.com/spreadsheets/d/1pcoY9N_vQp44NtSRR5eskkL5Qd0N0BGq7Jh_4m-7VEQ/edit?usp=sharing).\n\nPlease insert:\n- in the \"PROMPT\" column the accurate description of the video you want to create\n- in the \"DURATION\" column the lenght of the video you want to create\n\nLeave the \"VIDEO\" column unfilled. It will be inserted by the system once the video has been created"},"typeVersion":1},{"id":"8c54b723-d0b9-4d89-8150-975306640a96","name":"Completed?","type":"n8n-nodes-base.if","position":[1020,840],"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":"1135e1f0-b605-4724-a8b3-7f16b9887ef7","name":"Update result","type":"n8n-nodes-base.googleSheets","position":[860,1100],"parameters":{"columns":{"value":{"VIDEO":"={{ $('Get Url Video').item.json.video.url }}","row_number":"={{ $('Get new video').item.json.row_number }}"},"schema":[{"id":"PROMPT","type":"string","display":true,"removed":false,"required":false,"displayName":"PROMPT","defaultMatch":false,"canBeUsedToMatch":true},{"id":"DURATION","type":"string","display":true,"removed":false,"required":false,"displayName":"DURATION","defaultMatch":false,"canBeUsedToMatch":true},{"id":"VIDEO","type":"string","display":true,"removed":false,"required":false,"displayName":"VIDEO","defaultMatch":false,"canBeUsedToMatch":true},{"id":"YOUTUBE_URL","type":"string","display":true,"removed":false,"required":false,"displayName":"YOUTUBE_URL","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/11ebWJvwwXHgvQld9kxywKQUvIoBw6xMa0g0BuIqHDxE/edit#gid=0","cachedResultName":"Foglio1"},"documentId":{"__rl":true,"mode":"list","value":"1pcoY9N_vQp44NtSRR5eskkL5Qd0N0BGq7Jh_4m-7VEQ","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1pcoY9N_vQp44NtSRR5eskkL5Qd0N0BGq7Jh_4m-7VEQ/edit?usp=drivesdk","cachedResultName":"Video Google Veo3"}},"credentials":{"googleSheetsOAuth2Api":{"id":"JYR6a64Qecd6t8Hb","name":"Google Sheets account"}},"typeVersion":4.5},{"id":"8d0ac30d-5a92-487b-aaff-f761bd720293","name":"Set data","type":"n8n-nodes-base.set","position":[220,840],"parameters":{"options":{},"assignments":{"assignments":[{"id":"c713d31f-9abd-496a-ac79-e8e2efe60aa0","name":"prompt","type":"string","value":"={{ $json.PROMPT }}\n\nDuration of the video: {{ $json.DURATION }}"}]}},"typeVersion":3.4},{"id":"ae68690d-c154-4ec9-a5b8-ba95137d2cf4","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-220,520],"parameters":{"width":740,"height":100,"content":"## STEP 4 - MAIN FLOW\nStart the workflow manually or periodically by hooking the \"Schedule Trigger\" node. It is recommended to set it at 5 minute intervals."},"typeVersion":1},{"id":"429ab164-e165-409c-adc7-8a80c25b9f7d","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-220,100],"parameters":{"width":740,"height":140,"content":"## STEP 2 - 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":"868339d3-e3f0-473b-9f1f-c7c4fe9c9898","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[400,780],"parameters":{"width":180,"height":200,"content":"Set API Key created in Step 2"},"typeVersion":1},{"id":"44793285-6bb8-471a-a632-e0fe33d2d047","name":"Get new video","type":"n8n-nodes-base.googleSheets","position":[0,840],"parameters":{"options":{},"filtersUI":{"values":[{"lookupColumn":"VIDEO"}]},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1pcoY9N_vQp44NtSRR5eskkL5Qd0N0BGq7Jh_4m-7VEQ/edit#gid=0","cachedResultName":"Foglio1"},"documentId":{"__rl":true,"mode":"list","value":"1pcoY9N_vQp44NtSRR5eskkL5Qd0N0BGq7Jh_4m-7VEQ","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1pcoY9N_vQp44NtSRR5eskkL5Qd0N0BGq7Jh_4m-7VEQ/edit?usp=drivesdk","cachedResultName":"Video Google Veo3"}},"credentials":{"googleSheetsOAuth2Api":{"id":"JYR6a64Qecd6t8Hb","name":"Google Sheets account"}},"typeVersion":4.5},{"id":"7271ea9a-c4f5-4091-8f0f-ef40bb1d94af","name":"Create Video","type":"n8n-nodes-base.httpRequest","position":[440,840],"parameters":{"url":"https://queue.fal.run/fal-ai/veo3","method":"POST","options":{},"jsonBody":"={\n     \"prompt\": \"{{$json.prompt}}\"\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":"f0cbd048-011e-47ee-8840-af630adf6f85","name":"Get Url Video","type":"n8n-nodes-base.httpRequest","position":[-220,1220],"parameters":{"url":"=https://queue.fal.run/fal-ai/veo3/requests/{{ $json.request_id }}","options":{},"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"daOZafXpRXLtoLUV","name":"Fal.run API"}},"typeVersion":4.2},{"id":"f48cef5b-0609-417b-b4ec-21614397cb07","name":"Get File Video","type":"n8n-nodes-base.httpRequest","position":[400,1220],"parameters":{"url":"={{ $('Get Url Video').item.json.video.url }}","options":{}},"typeVersion":4.2},{"id":"2cde22e1-1b71-4672-80dc-4992c4bdfe5d","name":"Upload Video","type":"n8n-nodes-base.googleDrive","position":[680,1100],"parameters":{"name":"={{ $now.format('yyyyLLddHHmmss') }}-{{ $('Get Url Video').item.json.video.file_name }}","driveId":{"__rl":true,"mode":"list","value":"My Drive"},"options":{},"folderId":{"__rl":true,"mode":"list","value":"1aHRwLWyrqfzoVC8HoB-YMrBvQ4tLC-NZ","cachedResultUrl":"https://drive.google.com/drive/folders/1aHRwLWyrqfzoVC8HoB-YMrBvQ4tLC-NZ","cachedResultName":"Fal.run"}},"credentials":{"googleDriveOAuth2Api":{"id":"HEy5EuZkgPZVEa9w","name":"Google Drive account (n3w.it)"}},"typeVersion":3},{"id":"bf77f692-8a47-4f49-883b-ba045cb39f3b","name":"HTTP Request","type":"n8n-nodes-base.httpRequest","position":[680,1320],"parameters":{"url":"https://api.upload-post.com/api/upload","method":"POST","options":{},"sendBody":true,"contentType":"multipart-form-data","authentication":"genericCredentialType","bodyParameters":{"parameters":[{"name":"title","value":"={{ $('Generate title').item.json.message.content }}"},{"name":"user","value":"YOUR_USERNAME"},{"name":"platform[]","value":"youtube"},{"name":"video","parameterType":"formBinaryData","inputDataFieldName":"data"}]},"genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"DEE2XGvhGodgbAJh","name":"Upload-post.com API"}},"typeVersion":4.2},{"id":"0fab9370-c079-40c8-9e87-e9b319e0bee7","name":"Generate title","type":"@n8n/n8n-nodes-langchain.openAi","position":[20,1220],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"gpt-4o-mini","cachedResultName":"GPT-4O-MINI"},"options":{},"messages":{"values":[{"content":"=Input: {{ $('Get new video').item.json.PROMPT }}"},{"role":"system","content":"You are a YouTube SEO expert specialized in creating engaging and optimized titles.\n\nYour task is to generate an effective title for a YouTube video based on the user's video description.\n\nGUIDELINES:\n- Maximum 60 characters to avoid truncation\n- Use relevant keywords for SEO\n- Make the title catchy and clickable\n- Avoid excessive or misleading clickbait\n- Consider the target audience of the content\n- Use numbers, questions, or power words when appropriate\n- IMPORTANT: Generate the title in the same language as the input description\n\nOUTPUT FORMAT:\nProvide only the title, without additional explanations.\n\nEXAMPLE:\nInput: \"Tutorial video on how to cook perfect pasta carbonara\"\nOutput: \"PERFECT Carbonara in 10 Minutes - Chef's Secrets\""}]}},"credentials":{"openAiApi":{"id":"TefveNaDaMERl1hY","name":"OpenAi account (Eure)"}},"typeVersion":1.8},{"id":"cf9a58f0-0523-4229-ac2e-42f0f71d5306","name":"Update Youtube URL","type":"n8n-nodes-base.googleSheets","position":[860,1320],"parameters":{"columns":{"value":{"VIDEO":"=","row_number":"={{ $('Get new video').item.json.row_number }}","YOUTUBE_URL":"https://youtu.be/{{ $json.results.youtube.video_id }}"},"schema":[{"id":"PROMPT","type":"string","display":true,"removed":false,"required":false,"displayName":"PROMPT","defaultMatch":false,"canBeUsedToMatch":true},{"id":"DURATION","type":"string","display":true,"removed":false,"required":false,"displayName":"DURATION","defaultMatch":false,"canBeUsedToMatch":true},{"id":"VIDEO","type":"string","display":true,"removed":false,"required":false,"displayName":"VIDEO","defaultMatch":false,"canBeUsedToMatch":true},{"id":"YOUTUBE_URL","type":"string","display":true,"removed":false,"required":false,"displayName":"YOUTUBE_URL","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/11ebWJvwwXHgvQld9kxywKQUvIoBw6xMa0g0BuIqHDxE/edit#gid=0","cachedResultName":"Foglio1"},"documentId":{"__rl":true,"mode":"list","value":"1pcoY9N_vQp44NtSRR5eskkL5Qd0N0BGq7Jh_4m-7VEQ","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1pcoY9N_vQp44NtSRR5eskkL5Qd0N0BGq7Jh_4m-7VEQ/edit?usp=drivesdk","cachedResultName":"Video Google Veo3"}},"credentials":{"googleSheetsOAuth2Api":{"id":"JYR6a64Qecd6t8Hb","name":"Google Sheets account"}},"typeVersion":4.5},{"id":"2f97346c-78df-41fe-b15d-c2af7e9ee680","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[660,1260],"parameters":{"width":180,"height":200,"content":"Set YOUR_USERNAME in Step 3"},"typeVersion":1},{"id":"0d6517cb-d2a3-4afe-b163-25311faed711","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[-220,280],"parameters":{"width":740,"height":200,"content":"## STEP 3 - Upload video on Youtube\n- Find your API key in your [Upload-Post Manage Api Keys](https://app.upload-post.com/) 10 FREE uploads per month\n- Set the the \"Auth Header\":\n-- Name: Authorization\n-- Value: Apikey YOUR_API_KEY_HERE\n- Create profiles to manage your social media accounts. The \"Profile\" you choose will be used in the field YOUR_USRNAME (eg. test1 or test2).  "},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"a358d31a-ae0a-44e0-83e4-0a0df359e143","connections":{"Set data":{"main":[[{"node":"Create Video","type":"main","index":0}]]},"Completed?":{"main":[[{"node":"Get Url Video","type":"main","index":0}],[{"node":"Wait 60 sec.","type":"main","index":0}]]},"Get status":{"main":[[{"node":"Completed?","type":"main","index":0}]]},"Create Video":{"main":[[{"node":"Wait 60 sec.","type":"main","index":0}]]},"HTTP Request":{"main":[[{"node":"Update Youtube URL","type":"main","index":0}]]},"Upload Video":{"main":[[{"node":"Update result","type":"main","index":0}]]},"Wait 60 sec.":{"main":[[{"node":"Get status","type":"main","index":0}]]},"Get Url Video":{"main":[[{"node":"Generate title","type":"main","index":0}]]},"Get new video":{"main":[[{"node":"Set data","type":"main","index":0}]]},"Update result":{"main":[[]]},"Generate title":{"main":[[{"node":"Get File Video","type":"main","index":0}]]},"Get File Video":{"main":[[{"node":"Upload Video","type":"main","index":0},{"node":"HTTP Request","type":"main","index":0}]]},"When clicking ‘Test workflow’":{"main":[[{"node":"Get new video","type":"main","index":0}]]}}}


name: Generate and Send AI News Newsletters Automatically with GPT & Gmail
author_name: Rahul Joshi
author_username: rahul08
categories: []
created_at: 2025-06-10T08:27:24.513Z
updated_at: 2025-06-10T08:27:24.513Z
url: https://n8n.io/workflows/4847
scraped_at: 2025-07-06 21:16:30
description:
  Description:

  Automate your AI newsletter creation and delivery using this ready-to-deploy n8n workflow template. Powered by GPT (OpenAI/Azure) and integrated with Gmail, this workflow generates rich, structured, and engaging AI-focused newsletters and sends them out daily or weekly—completely hands-free.

  What It Does:

  📰 Fetches the latest AI trends and updates using GPT
  ✍️ Automatically formats news into structured newsletter sections: headlines, tools, stats, tips, and more
  📧 Sends HTML email newsletters via Gmail
  🕘 Runs automatically at your chosen schedule (default: 9 AM daily)

  Setup Includes:

  Connect your OpenAI or Azure GPT API
  Add Gmail SMTP or OAuth credentials
  Customize categories, schedule, and email styling

  Perfect for:

  Tech bloggers, content marketers, AI influencers, and automation enthusiasts who want to send curated AI content to their audience without manual effort.

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

workflow_json:
  {"id":"DSxmKG8H861zKUw8","meta":{"instanceId":"18c9b77a7db94bab09d77f4a9c44dd94853695bba1618cb7bc3c4bc412c07c1e","templateCredsSetupCompleted":true},"name":"AI Generated Email Newsletter","tags":[],"nodes":[{"id":"a915b64b-1052-4cd1-aca9-0325c1b2c29d","name":"Workflow Documentation","type":"n8n-nodes-base.stickyNote","position":[-120,-140],"parameters":{"color":6,"width":450,"height":420,"content":"## Daily AI News Summary Workflow\n\nThis workflow runs every day at 9 AM to:\n\n1. **Fetch Latest AI News**: Uses Perplexity to find recent AI developments\n2. **Categorize Content**: Organizes news into three key areas:\n   - 🚀 New Technology (breakthroughs, models, research)\n   - 💡 Tips & Tricks (practical applications, tutorials)\n   - 🛡️ AI Ethics & Security (privacy, safety, regulations)\n3. **Format & Send**: Creates a beautiful HTML email with summaries and links\n\n### Setup Required:\n- Perplexity API credentials\n- SMTP email credentials\n- Update recipient email address\n\n### Customization:\n- Change schedule time in Daily Trigger\n- Modify categories in Perplexity prompt\n- Adjust email styling in Format Email Content node"},"typeVersion":1},{"id":"3c6ef52a-3c4b-4d0e-be08-d496c407fa66","name":"Setup Instructions","type":"n8n-nodes-base.stickyNote","position":[480,0],"parameters":{"color":3,"width":580,"height":280,"content":"⚙️ **Configuration Needed:**\n\n1. **AI Agent**: Add your Chat Model API key to the \"AI Agent\"\n\n2. **Email Settings**: \n   - Add your Gmail Credentials\n   - Add subject and message seperately\n   - Email should be in HTML format\n\n3. **Timing**: Modify schedule in \"Daily Trigger\" if you want different timing\n\n4. **Content**: Customize the news categories or add more in the AI Agent prompt"},"typeVersion":1},{"id":"2f165ff5-7666-4f7b-93e0-73556ad9ed7a","name":"Set Dates1","type":"n8n-nodes-base.set","position":[60,360],"parameters":{"options":{},"assignments":{"assignments":[{"id":"current-date","name":"currentDate","type":"string","value":"={{ $now.format('yyyy-MM-dd') }}"},{"id":"yesterday-date","name":"lastweekDate","type":"string","value":"={{ $now.minus({days: 7}).format('yyyy-MM-dd') }}"}]}},"typeVersion":3.4},{"id":"419a0eac-33f1-4349-ba54-a0a428ef8c1b","name":"Gmail1","type":"n8n-nodes-base.gmail","position":[880,360],"webhookId":"6e5776e8-b6b9-4c56-8b3a-812f68959433","parameters":{"sendTo":"jyothi.swarup@techdome.net.in","message":"={{ $json.html }}","options":{},"subject":"={{ $json.subject }}"},"credentials":{"gmailOAuth2":{"id":"kqndcZ7sNbQqDrJF","name":"Gmail account"}},"typeVersion":2.1},{"id":"57cb8666-b3ff-489b-a6a5-be329ad82ab5","name":"Format Email Content","type":"n8n-nodes-base.code","position":[660,360],"parameters":{"jsCode":"// n8n Code Node - Email Formatter for AI Newsletter\n// This code formats the AI agent output for email sending\n\n// Get the AI agent output from the previous node\nconst aiOutput = $input.all()[0].json.output || $input.all()[0].json.text || $input.all()[0].json;\n\n// Extract the newsletter content (remove the prefix text)\nlet newsletterContent = '';\nif (typeof aiOutput === 'object' && aiOutput.content) {\n  newsletterContent = aiOutput.content;\n} else if (typeof aiOutput === 'string') {\n  // Remove the \"this is the output from the ai agent:\" prefix if it exists\n  newsletterContent = aiOutput.replace(/^this is the output from the ai agent:\\s*/i, '');\n} else {\n  newsletterContent = JSON.stringify(aiOutput);\n}\n\n// Clean up the newsletter content - remove \\n literals and format properly\nnewsletterContent = newsletterContent\n  .replace(/\\\\n/g, '\\n')  // Convert literal \\n to actual newlines\n  .replace(/^\\s+|\\s+$/g, '')  // Trim whitespace\n  .replace(/\\n{3,}/g, '\\n\\n');  // Replace multiple newlines with double newlines\n\n// Generate email subject with current date\nfunction generateEmailSubject() {\n  const currentDate = new Date().toLocaleDateString('en-US', { \n    year: 'numeric', \n    month: 'long', \n    day: 'numeric' \n  });\n  return `🤖 AI Weekly Pulse - ${currentDate}: ChatGPT Voice Update & Latest AI News`;\n}\n\n// Generate email body with proper formatting\nfunction generateEmailBody() {\n  const emailBody = `Hi there!\n\nI hope this email finds you well. Here's this week's AI newsletter with the latest updates from the AI world:\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n${newsletterContent}\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nHope you found this week's AI updates valuable! Feel free to reply with your thoughts or questions.\n\nBest regards,\nAI Weekly Pulse Team\n\n---\n📧 This newsletter was automatically generated and sent via n8n automation.\n🔗 Want to unsubscribe or have questions? Just reply to this email.`;\n\n  return emailBody;\n}\n\n// Generate HTML version of the email for better formatting\nfunction generateHTMLEmailBody() {\n  // Convert markdown-like content to basic HTML\n  let htmlContent = newsletterContent\n    .replace(/^# (.*$)/gm, '<h1 style=\"color: #333; border-bottom: 2px solid #667eea; padding-bottom: 10px;\">$1</h1>')\n    .replace(/^## (.*$)/gm, '<h2 style=\"color: #444; margin-top: 30px; margin-bottom: 15px;\">$1</h2>')\n    .replace(/^### (.*$)/gm, '<h3 style=\"color: #555; margin-top: 20px; margin-bottom: 10px;\">$1</h3>')\n    .replace(/\\*\\*(.*?)\\*\\*/g, '<strong>$1</strong>')\n    .replace(/\\*(.*?)\\*/g, '<em>$1</em>')\n    .replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '<a href=\"$2\" style=\"color: #667eea; text-decoration: none;\">$1</a>')\n    .replace(/^- (.*$)/gm, '<li style=\"margin-bottom: 8px;\">$1</li>')\n    .replace(/^> (.*$)/gm, '<blockquote style=\"border-left: 4px solid #667eea; padding-left: 20px; margin: 20px 0; font-style: italic; color: #666;\">$1</blockquote>')\n    .replace(/---/g, '<hr style=\"border: none; border-top: 2px solid #eee; margin: 30px 0;\">')\n    .replace(/\\n\\n/g, '</p><p style=\"line-height: 1.6; margin-bottom: 15px;\">')\n    .replace(/\\n/g, '<br>');\n\n  // Wrap list items in ul tags\n  htmlContent = htmlContent.replace(/(<li[^>]*>.*?<\\/li>)/gs, '<ul style=\"padding-left: 20px; margin-bottom: 20px;\">$1</ul>');\n\n  const htmlBody = `\n<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>AI Weekly Pulse</title>\n</head>\n<body style=\"font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 800px; margin: 0 auto; padding: 20px; background-color: #f9f9f9;\">\n    <div style=\"background: white; padding: 40px; border-radius: 10px; box-shadow: 0 4px 15px rgba(0,0,0,0.1);\">\n        <div style=\"text-align: center; margin-bottom: 30px; padding: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 8px; color: white;\">\n            <h1 style=\"margin: 0; font-size: 24px;\">🤖 AI Weekly Pulse</h1>\n            <p style=\"margin: 10px 0 0 0; opacity: 0.9;\">Your Weekly Dose of AI Innovation</p>\n        </div>\n        \n        <div style=\"margin-bottom: 30px;\">\n            <p style=\"font-size: 16px; color: #555;\">Hi there!</p>\n            <p style=\"font-size: 16px; color: #555;\">Hope this email finds you well. Here's this week's AI newsletter with the latest updates from the AI world:</p>\n        </div>\n        \n        <div style=\"background: #fafafa; padding: 30px; border-radius: 8px; margin: 20px 0;\">\n            <p style=\"line-height: 1.6; margin-bottom: 15px;\">${htmlContent}</p>\n        </div>\n        \n        <div style=\"margin-top: 40px; padding: 30px; background: #f0f4ff; border-radius: 8px; text-align: center;\">\n            <p style=\"font-size: 16px; color: #555; margin-bottom: 15px;\">Hope you found this week's AI updates valuable!</p>\n            <p style=\"font-size: 16px; color: #555; margin-bottom: 20px;\">Feel free to reply with your thoughts or questions.</p>\n            <p style=\"font-size: 18px; color: #333; margin: 0;\"><strong>Best regards,<br>AI Weekly Pulse Team</strong></p>\n        </div>\n        \n        <div style=\"margin-top: 30px; padding: 20px; background: #e8f2ff; border-radius: 8px; font-size: 14px; color: #666; text-align: center;\">\n            <p style=\"margin: 5px 0;\">📧 This newsletter was automatically generated and sent via n8n automation.</p>\n            <p style=\"margin: 5px 0;\">🔗 Want to unsubscribe or have questions? Just reply to this email.</p>\n        </div>\n    </div>\n</body>\n</html>`;\n\n  return htmlBody;\n}\n\n// Generate the formatted output for the email node\nconst emailSubject = generateEmailSubject();\nconst emailBodyText = generateEmailBody();\nconst emailBodyHTML = generateHTMLEmailBody();\n\n// Return the formatted data for the next node (email sender)\nreturn [\n  {\n    json: {\n      subject: emailSubject,\n      text: emailBodyText,\n      html: emailBodyHTML,\n      // Additional metadata\n      newsletter_content: newsletterContent,\n      generated_at: new Date().toISOString(),\n      email_type: \"ai_weekly_pulse\"\n    }\n  }\n];"},"typeVersion":2},{"id":"9a9676bb-d645-49fc-84ab-5a5c0cd92645","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[280,360],"parameters":{"text":"=Newsletter Structure\n1. Title\nEngaging and punchy (under 10 words).\n\nIncludes a relevant keyword (e.g., “AI”, “ChatGPT”, “Machine Learning”).\n\n2. Editor’s Note (Optional but preferred)\nA short 2–3 sentence personal note to the readers.\n\nTone: Conversational and warm.\n\nSummarize the theme of this issue or highlight an AI trend to watch.\n\n3. 🧠 AI in Focus (Main Story)\nOne key development or trend in AI this week.\n\nCould be about a breakthrough, a major product launch, a regulatory move, or a case study.\n\n3–5 paragraphs long.\n\nInclude context (why it matters), impact, and your analysis.\n\n4. 📰 Headlines in AI (News Roundup)\nList 3–5 bite-sized headlines with 1–2 sentence summaries for each. Include:\n\nDate (optional).\n\nSource (e.g., OpenAI, Google, MIT, etc.).\n\nLink (if available).\n\nExample:\n\nOpenAI Releases GPT-5 Preview – OpenAI teased major upgrades in language understanding and reasoning. Read more\n\n5. 🔍 Tool of the Week\nIntroduce one new or underrated AI tool.\n\nInclude what it does, who it’s for, and how it works (2–3 sentences).\n\nInclude a link if available.\n\n6. 📚 Learning Corner\nRecommend one AI resource: a blog post, YouTube video, podcast, free course, or paper.\n\nMention why it’s worth reading/listening/watching.\n\n7. 🤖 Prompt of the Week\nShare a powerful or creative prompt users can try with ChatGPT or any LLM.\n\nExplain what it does and when to use it.\n\n8. 📈 AI Stat of the Week\nShare one interesting stat about AI.\n\nCite the source and explain the takeaway in 1–2 sentences.\n\n9. 👥 Community Shoutout (Optional)\nHighlight a person, open-source project, or discussion in the AI community.\n\n10. 👀 What to Watch Next Week\nPreview an upcoming event, release, or expected trend in AI.\n\nKeep it short (1–2 sentences).\n\n🧾 Style Guidelines\nUse markdown for formatting: **bold**, # headers, - lists, etc.\n\nKeep tone informative, clear, and slightly casual.\n\nAvoid jargon unless explained.\n\nUse bullet points and subheaders for readability.\n\nProvide citations for all the topics immediately ","options":{"systemMessage":"You are an AI writing assistant tasked with creating a weekly newsletter about artificial intelligence (AI). The goal is to inform, engage, and educate readers ranging from tech-savvy professionals to curious enthusiasts. Follow the structure below and ensure the tone is professional yet accessible."},"promptType":"define"},"typeVersion":1.9},{"id":"4e5e19a9-b05f-4ef0-a432-a0e72c479095","name":"Azure OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatAzureOpenAi","position":[260,520],"parameters":{"model":"gpt-4.1","options":{}},"credentials":{"azureOpenAiApi":{"id":"gDiLXmZSX0q3CyLu","name":"Azure Open AI account"}},"typeVersion":1},{"id":"e7dbd62a-6580-4a28-ab85-5fdf885dacf0","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[-140,360],"parameters":{"rule":{"interval":[{}]}},"typeVersion":1.2}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"e0cf8d41-3776-4aab-a5ec-fd16b8bc7457","connections":{"AI Agent":{"main":[[{"node":"Format Email Content","type":"main","index":0}]]},"Set Dates1":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"Schedule Trigger":{"main":[[{"node":"Set Dates1","type":"main","index":0}]]},"Format Email Content":{"main":[[{"node":"Gmail1","type":"main","index":0}]]},"Azure OpenAI Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]}}}


name: Automated Invoice Processing with Telegram, GPT-4o, OCR and SAP Integration
author_name: Raquel Giugliano
author_username: raquelgiugliano
categories: []
created_at: 2025-06-10T10:01:39.029Z
updated_at: 2025-06-10T10:01:39.029Z
url: https://n8n.io/workflows/4849
scraped_at: 2025-07-06 21:16:30
description:
  ++HOW IT WORKS:++
  This workflow automates the processing of invoices sent via Telegram. It extracts the data using LlamaIndex OCR, logs it in Google Sheets, and optionally pushes the structured data to SAP Business One

  🔹 1. Receive Invoice via Telegram:**
  A user sends a PDF of an invoice through Telegram
  A Telegram Trigger node listens for incoming messages and captures the file and metadata
  The document is downloaded and prepared for OCR

  🔹 2. OCR with LlamaIndex:
  The file is uploaded to the LlamaIndex OCR API.
  The workflow polls the API until the processing status returns SUCCESS
  Once ready, the parsed content is fetched in Markdown format

  🔹 3. Data Extraction via LLM (editable):
  The Markdown content is sent to a language model (LLM) using LangChain
  A Structured Output Parser transforms the result into a clean, structured editable JSON

  🔹 4. Save to Google Sheets:
  The structured JSON is split into:
  Header (main invoice metadata)
  Detail (individual line items)

  Each part is stored in a dedicated tab within a connected Google Sheets file

  🔹 5. Ask for SAP Confirmation:
  The bot replies to the user via Telegram:

  "Do you want to send the data to SAP?"

  If the user clicks "Yes", the next automation path is triggered.

  🔹 6. Push Data to SAP B1:
  A connection is made to SAP Business One's Service Layer API

  Header and detail data are fetched from Google Sheets

  The invoice structure is rebuilt as required by SAP (DocumentLines, CardCode, etc.)

  A POST request creates the Purchase Invoice in SAP

  A confirmation message with the created DocEntry is sent back to the user on Telegram

  ++SET UP STEPS:++
  Follow these steps to properly configure the workflow before execution:

  1️⃣ Create Required Credentials:
  Go to Credentials &gt; + New Credential and create the following:
  Telegram API (set your bot token get it from BotFather)
  Google Sheets
  OpenAI

  2️⃣ Set Up Environment Variables (Optional but Recommended):
  LLAMAINDEX_API_KEY
  SAP_USER
  SAP_PASSWORD
  SAP_COMPANY_DB
  SAP_URL

  3️⃣ Prepare Google Sheets:
  Ensure your Google Spreadsheet has the following:
  ➤ Sheet 1: Header
  ➤ Sheet 2: Details
  Contains columns for invoice lines

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

workflow_json:
  {"id":"5mGRqFpu73QguZPC","meta":{"instanceId":"06b3271522ae4bedcb94de9dac3219d19e1a4e5fcd0a448a4abc68198b391077","templateCredsSetupCompleted":true},"name":"ocr Telegram - SAP","tags":[],"nodes":[{"id":"026397ff-3b84-49f4-adf1-d4e8bef01e38","name":"Wait","type":"n8n-nodes-base.wait","position":[1620,100],"webhookId":"76b9bf12-3264-40e5-94dc-676f3954f41c","parameters":{"amount":3},"typeVersion":1.1},{"id":"7c032e9c-edc3-4b23-89d5-66e092b37857","name":"Basic LLM Chain","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[1840,-100],"parameters":{"text":"={{ $json.markdown }}","batching":{},"messages":{"messageValues":[{"message":"Eres un asistente experto en extracción y procesamiento de datos de documentos especializado en identificar con precisión los detalles claves de una factura"},{"type":"HumanMessagePromptTemplate","message":"=Tu tarea: Extraer de cualquier texto de factura los siguientes campos, devolviendo los datos en un JSON estructurado y con máxima precisión:\n\nCampos a extraer:\nnombre_proveedor: Nombre del proveedor.\n\nruc_proveedor: RUC del proveedor.\n\ndireccion_proveedor: Dirección del proveedor.\n\nnumero_factura: Número de factura.\n\nfecha_emision: Fecha de emisión de la factura (formato YYYY-MM-DD).\n\ndetalle_productos: Lista de líneas de detalle de los productos o servicios facturados. Cada línea incluirá:\n\ncodigo\n\ndescripcion\n\ncantidad\n\nprecio\n\nsubtotal\n\nsubtotal_factura: Subtotal general de la factura.\n\ndescuento_factura: Descuento total de la factura.\n\ntotal_neto: Total neto de la factura.\n\nFormato de salida esperado:\nSi algún campo no existe, deberá devolverse como null.\nDevuelve siempre el JSON con los nombres exactos de las claves.\n\nEjemplo de salida esperado:\n\n{\n  \"nombre_proveedor\": \"Blockies Corporation\",\n  \"ruc_proveedor\": \"78787878-7\",\n  \"direccion_proveedor\": \"AV. DE LAS ARTES NORTE NRO. 310 (ESPALDA RAMBLA DE JAVIER PRADO) LIMA - LIMA - SAN BORJA\",\n  \"numero_factura\": \"00003\",\n  \"fecha_emision\": \"2025-04-15\",\n  \"detalle_productos\": [\n    {\n      \"codigo\": \"srv001\",\n      \"descripcion\": \"Servicio de Alquiler de Montacargas\",\n      \"cantidad\": 1,\n      \"precio\": 35.00,\n      \"subtotal\": 35.00\n    }\n  ],\n  \"subtotal_factura\": 35.00,\n  \"descuento_factura\": 0.00,\n  \"total_neto\": 35.00\n}\nInstrucciones adicionales:\nNo resumas, no expliques, no añadas comentarios, solo responde con el JSON.\n\nSi existen varias líneas de productos, incluir todas dentro del array \"detalle_productos\".\n\nNo redondees importes, extrae exactamente el valor mostrado.\n\nLas fechas deben estar siempre en formato YYYY-MM-DD."}]},"promptType":"define","hasOutputParser":true},"typeVersion":1.7},{"id":"036c0443-0224-4a2f-9a9a-c7d9feebbdc3","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[1840,80],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"typeVersion":1.2},{"id":"0af0d3fb-6b87-44b4-8fe8-3c992c74a10d","name":"No Operation, do nothing","type":"n8n-nodes-base.noOp","position":[760,820],"parameters":{},"typeVersion":1},{"id":"a9201f0b-e504-45c2-ade0-86004ba5e323","name":"Split Out","type":"n8n-nodes-base.splitOut","position":[2280,-100],"parameters":{"options":{},"fieldToSplitOut":"output.detalle_productos"},"typeVersion":1},{"id":"8a189ae2-64d4-459b-a8fd-81b4423cf135","name":"Merge","type":"n8n-nodes-base.merge","position":[2240,540],"parameters":{"mode":"combine","options":{},"combineBy":"combineByPosition"},"typeVersion":3.2},{"id":"b13a0de4-a00e-4b38-8b12-fa9c2b1825d9","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-140,460],"parameters":{"width":3720,"height":560,"content":"## Waiting for an answer on telegram"},"typeVersion":1},{"id":"4aa3c30a-4a2c-4168-866d-4e1b8a3651f5","name":"Callback Waiting Answer","type":"n8n-nodes-base.telegramTrigger","position":[-40,640],"webhookId":"56b0ca20-2362-4658-b2b8-692b0303ae0c","parameters":{"updates":["callback_query"],"additionalFields":{}},"credentials":{"telegramApi":{"id":"d7ed9EHZ1GiHews4","name":"Telegram account"}},"typeVersion":1.2},{"id":"8b49790e-fc03-4a1b-944c-139e383a0a46","name":"Answer?","type":"n8n-nodes-base.switch","position":[300,640],"parameters":{"rules":{"values":[{"outputKey":"SI","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"c3ae2bff-a96d-4f42-b0b3-e04f8ef372d1","operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.callback_query.data }}","rightValue":"respuesta_si"}]},"renameOutput":true},{"outputKey":"NO","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"59ccf0b4-bb12-4c10-b289-354be138f96c","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.callback_query.data }}","rightValue":"respuesta_no"}]},"renameOutput":true}]},"options":{}},"typeVersion":3.2},{"id":"a958d830-0608-4d9b-a14d-922869c9fbd3","name":"Connect to SAP","type":"n8n-nodes-base.httpRequest","position":[760,520],"parameters":{"url":"={{ $vars.url_sap }}Login","method":"POST","options":{"allowUnauthorizedCerts":true},"jsonBody":"={\n       \"UserName\": \"{{ $vars.user_sap }}\",\n       \"Password\": \"{{ $vars.password_sap }}\",\n       \"CompanyDB\": \"{{ $vars.company_db }}\"\n}","sendBody":true,"specifyBody":"json"},"typeVersion":4.2,"alwaysOutputData":false},{"id":"ec4c8074-6aa8-4f89-812c-3d6305a10d60","name":"Get Header","type":"n8n-nodes-base.googleSheets","position":[1160,520],"parameters":{"sheetName":{"__rl":true,"mode":"list","value":"","cachedResultUrl":"","cachedResultName":""},"documentId":{"__rl":true,"mode":"list","value":""}},"credentials":{"googleSheetsOAuth2Api":{"id":"dWCmToHbrXSRjlDB","name":"Google Sheets account"}},"typeVersion":4.6},{"id":"5e290a19-236a-4baa-9093-1b32f486b058","name":"Get Row Details","type":"n8n-nodes-base.googleSheets","position":[1560,680],"parameters":{"sheetName":{"__rl":true,"mode":"list","value":"","cachedResultUrl":"","cachedResultName":""},"documentId":{"__rl":true,"mode":"list","value":""}},"credentials":{"googleSheetsOAuth2Api":{"id":"dWCmToHbrXSRjlDB","name":"Google Sheets account"}},"typeVersion":4.6,"alwaysOutputData":false},{"id":"42edf631-ee30-4b6f-b10b-fa53ee148c26","name":"Generate DocumentLines","type":"n8n-nodes-base.code","position":[1880,680],"parameters":{"jsCode":"const items = $input.all();  // capturamos todos los items que entran\nconst DocumentLines = [];\n\nfor (let i = 0; i < items.length; i++) {\n  const item = items[i].json;\n\n  DocumentLines.push({\n    ItemCode: item.código,\n    Quantity: item.cantidad,\n    UnitPrice: item.precio\n  });\n}\n\nreturn [{ DocumentLines }];\n"},"typeVersion":2},{"id":"d9d54a86-50e7-469a-88a2-c5860459bf99","name":"Create JSON","type":"n8n-nodes-base.code","position":[2580,540],"parameters":{"jsCode":"const item = $json;\n\n// Construimos el objeto final para SAP\nreturn [{\n  DocDate: item.fecha_emision,\n  DocDueDate: item.fecha_emision,\n  CardCode: item.ruc_proveedor,\n  DocumentLines: item.DocumentLines\n}];"},"typeVersion":2},{"id":"dfbd5b4b-a545-4062-bfdb-1d383c8277f6","name":"POST PurchaseInvoices","type":"n8n-nodes-base.httpRequest","position":[2980,540],"parameters":{"url":"={{ $vars.url_sap }}PurchaseInvoices","body":"={{ JSON.stringify($json) }}","method":"POST","options":{"allowUnauthorizedCerts":true},"sendBody":true,"contentType":"raw","sendHeaders":true,"rawContentType":"application/json","headerParameters":{"parameters":[{"name":"Cookie","value":"=B1SESSION={{ $('Connect to SAP').item.json.SessionId }}"}]}},"typeVersion":4.2},{"id":"ec33a3bf-2632-4f49-b0c8-4fe1284c90df","name":"PurchaseInvoices created","type":"n8n-nodes-base.telegram","position":[3360,540],"webhookId":"a3f4bedb-06da-446e-8a1a-a2666b511152","parameters":{"text":"=PurchaseInvoice {{ $json.DocEntry }} creada en SAP correctamente","chatId":"={{ $('Callback Waiting Answer').item.json.callback_query.message.chat.id }}","additionalFields":{"appendAttribution":false}},"credentials":{"telegramApi":{"id":"d7ed9EHZ1GiHews4","name":"Telegram account"}},"typeVersion":1.2},{"id":"311d3616-3ebf-439f-8d6f-f5aa18e89bc6","name":"Trigger Receive Message","type":"n8n-nodes-base.telegramTrigger","position":[0,0],"webhookId":"5af23994-f45e-4b53-8bc0-edfee56e962c","parameters":{"updates":["message"],"additionalFields":{}},"typeVersion":1.2},{"id":"c01eb2e3-7aa8-4a4c-897f-4414816fa459","name":"Capture Telegram Data","type":"n8n-nodes-base.set","position":[260,0],"parameters":{"options":{},"assignments":{"assignments":[{"id":"b6e43e6c-452f-4747-b17c-2de6191fb0f0","name":"message.chat.id","type":"number","value":"={{ $json.message.chat.id }}"},{"id":"a82f3829-5ce1-4a94-b7e0-a1449f7a3da6","name":"message.chat","type":"object","value":"={{ $json.message.chat }}"},{"id":"619ffe10-2bea-4bda-a356-501562628bc5","name":"telegram.file_id","type":"string","value":"={{ $json.message.document.file_id }}"},{"id":"afbbdb8a-47e8-4b33-8f81-91989d1121af","name":"message.caption","type":"string","value":"={{ $('Trigger Receive Message').item.json.message.caption }}"}]}},"typeVersion":3.4},{"id":"bacef005-e65c-4894-aa0b-8ef34033daac","name":"File Received","type":"n8n-nodes-base.telegram","position":[500,0],"webhookId":"39a7a3e0-95ba-400f-9c3b-58bfc70b5fb3","parameters":{"text":"Hemos recibido tu documento y lo estamos procesando...","chatId":"={{ $json.message.chat.id }}","additionalFields":{"appendAttribution":false}},"credentials":{"telegramApi":{"id":"d7ed9EHZ1GiHews4","name":"Telegram account"}},"typeVersion":1.2},{"id":"01bae880-e0d1-449f-b459-94b7a56b3adb","name":"Download File","type":"n8n-nodes-base.telegram","position":[720,0],"webhookId":"1393ba90-f818-4d06-88b9-806d1542abea","parameters":{"fileId":"={{ $('Capture Telegram Data').item.json.telegram.file_id }}","resource":"file"},"credentials":{"telegramApi":{"id":"d7ed9EHZ1GiHews4","name":"Telegram account"}},"typeVersion":1.2},{"id":"86e1b80a-302d-4010-a740-ce916f8f74df","name":"Upload File LlamaIndex","type":"n8n-nodes-base.httpRequest","position":[940,0],"parameters":{"url":"https://api.cloud.llamaindex.ai/api/v1/parsing/upload","method":"POST","options":{},"sendBody":true,"contentType":"multipart-form-data","sendHeaders":true,"bodyParameters":{"parameters":[{"name":"file","parameterType":"formBinaryData","inputDataFieldName":"data"}]},"headerParameters":{"parameters":[{"name":"accept","value":"application/json"},{"name":"Authorization","value":"=Bearer {{ $vars.llamaindex_apikey }}"}]}},"typeVersion":4.2},{"id":"92f93bbd-3192-40aa-b81f-bf5165e3dc35","name":"Validate Status LlamaIndex","type":"n8n-nodes-base.httpRequest","position":[1180,0],"parameters":{"url":"=https://api.cloud.llamaindex.ai/api/v1/parsing/job/{{ $json.id }}","options":{},"sendHeaders":true,"headerParameters":{"parameters":[{"name":"accept","value":"application/json"},{"name":"Authorization","value":"=Bearer {{ $vars.llamaindex_apikey }}"}]}},"typeVersion":4.2},{"id":"4914e5d3-ec4e-4c96-b6c1-6f2ede2b5b38","name":"Status?","type":"n8n-nodes-base.switch","position":[1400,0],"parameters":{"rules":{"values":[{"outputKey":"SUCCESS","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"7005abbb-4094-4dde-9cc5-b973fe54a09e","operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"SUCCESS"}]},"renameOutput":true},{"outputKey":"PENDING","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"b4bdda84-6e9d-44c9-a85c-fd87d7427765","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"PENDING"}]},"renameOutput":true}]},"options":{}},"typeVersion":3.2},{"id":"d2c19099-01c7-4547-aa3e-944c16009aaf","name":"Get Results LlamaIndex","type":"n8n-nodes-base.httpRequest","position":[1620,-100],"parameters":{"url":"=https://api.cloud.llamaindex.ai/api/v1/parsing/job/{{ $json.id }}/result/markdown","options":{},"sendHeaders":true,"headerParameters":{"parameters":[{"name":"accept","value":"application/json"},{"name":"Authorization","value":"=Bearer {{ $vars.llamaindex_apikey }}"}]}},"typeVersion":4.2},{"id":"c0ba5071-56b6-45c0-b0ad-bb87b8c543ca","name":"Structured Output Parser (Example)","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[2060,60],"parameters":{"jsonSchemaExample":"{\n  \"nombre_proveedor\": \"Blockies Corporation\",\n  \"ruc_proveedor\": \"78787878-7\",\n  \"direccion_proveedor\": \"AV. DE LAS ARTES NORTE NRO. 310 (ESPALDA RAMBLA DE JAVIER PRADO) LIMA - LIMA - SAN BORJA\",\n  \"numero_factura\": \"00003\",\n  \"fecha_emision\": \"2025-04-15\",\n  \"detalle_productos\": [\n    {\n      \"codigo\": \"srv001\",\n      \"descripcion\": \"Servicio de Alquiler de Montacargas\",\n      \"cantidad\": 1,\n      \"precio\": 35.00,\n      \"subtotal\": 35.00\n    }\n  ],\n  \"subtotal_factura\": 35.00,\n  \"descuento_factura\": 0.00,\n  \"total_neto\": 35.00\n}"},"typeVersion":1.2},{"id":"f62a9650-a966-4efa-a9ec-ee166e4e3881","name":"Detail","type":"n8n-nodes-base.googleSheets","position":[2480,80],"parameters":{"columns":{"value":{"precio":"={{ $('Split Out').item.json.precio }}","código":"={{ $('Split Out').item.json.codigo }}","cantidad":"={{ $('Split Out').item.json.cantidad }}","subtotal":"={{ $('Split Out').item.json.subtotal }}","descripcion":"={{ $('Split Out').item.json.descripcion }}","numero_factura":"={{ $('Basic LLM Chain').item.json.output.numero_factura }}"},"schema":[{"id":"numero_factura","type":"string","display":true,"required":false,"displayName":"numero_factura","defaultMatch":false,"canBeUsedToMatch":true},{"id":"código","type":"string","display":true,"required":false,"displayName":"código","defaultMatch":false,"canBeUsedToMatch":true},{"id":"descripcion","type":"string","display":true,"required":false,"displayName":"descripcion","defaultMatch":false,"canBeUsedToMatch":true},{"id":"cantidad","type":"string","display":true,"required":false,"displayName":"cantidad","defaultMatch":false,"canBeUsedToMatch":true},{"id":"precio","type":"string","display":true,"required":false,"displayName":"precio","defaultMatch":false,"canBeUsedToMatch":true},{"id":"subtotal","type":"string","display":true,"required":false,"displayName":"subtotal","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"append","documentId":{"__rl":true,"mode":"list","value":""}},"typeVersion":4.6},{"id":"ec718e9d-d729-4493-8439-78cf63394e28","name":"Header","type":"n8n-nodes-base.googleSheets","position":[2620,-100],"parameters":{"operation":"append","sheetName":{"__rl":true,"mode":"list","value":""},"documentId":{"__rl":true,"mode":"list","value":""}},"credentials":{"googleSheetsOAuth2Api":{"id":"dWCmToHbrXSRjlDB","name":"Google Sheets account"}},"executeOnce":true,"typeVersion":4.6},{"id":"d30ac579-8f31-471f-89d6-e27b6b99a4f3","name":"¿Upload to SAP?","type":"n8n-nodes-base.telegram","position":[2900,-100],"webhookId":"f327fe60-a943-4b8b-8413-8caf56d4657d","parameters":{"text":"=¿Quieres enviar los datos a SAP?","chatId":"={{ $('Capture Telegram Data').item.json.message.chat.id }}","replyMarkup":"inlineKeyboard","inlineKeyboard":{"rows":[{"row":{"buttons":[{"text":"Si","additionalFields":{"callback_data":"respuesta_si"}},{"text":"No","additionalFields":{"callback_data":"respuesta_no"}}]}}]},"additionalFields":{"appendAttribution":false}},"credentials":{"telegramApi":{"id":"d7ed9EHZ1GiHews4","name":"Telegram account"}},"executeOnce":true,"typeVersion":1.2},{"id":"e80fa814-502a-4af1-8c3f-8b35c65ed0eb","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-120,-180],"parameters":{"color":7,"width":3280,"height":540,"content":"## Send data and OCR with LlamaIndex\n"},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"c7b1fdbb-20e4-48aa-b67a-7da7ceee2fa7","connections":{"Wait":{"main":[[{"node":"Validate Status LlamaIndex","type":"main","index":0}]]},"Merge":{"main":[[{"node":"Create JSON","type":"main","index":0}]]},"Detail":{"main":[[{"node":"Header","type":"main","index":0}]]},"Header":{"main":[[{"node":"¿Upload to SAP?","type":"main","index":0}]]},"Answer?":{"main":[[{"node":"Connect to SAP","type":"main","index":0}],[{"node":"No Operation, do nothing","type":"main","index":0}]]},"Status?":{"main":[[{"node":"Get Results LlamaIndex","type":"main","index":0}],[{"node":"Wait","type":"main","index":0}]]},"Split Out":{"main":[[{"node":"Detail","type":"main","index":0}]]},"Get Header":{"main":[[{"node":"Get Row Details","type":"main","index":0},{"node":"Merge","type":"main","index":0}]]},"Create JSON":{"main":[[{"node":"POST PurchaseInvoices","type":"main","index":0}]]},"Download File":{"main":[[{"node":"Upload File LlamaIndex","type":"main","index":0}]]},"File Received":{"main":[[{"node":"Download File","type":"main","index":0}]]},"Connect to SAP":{"main":[[{"node":"Get Header","type":"main","index":0}]]},"Basic LLM Chain":{"main":[[{"node":"Split Out","type":"main","index":0}]]},"Get Row Details":{"main":[[{"node":"Generate DocumentLines","type":"main","index":0}]]},"¿Upload to SAP?":{"main":[[]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"Basic LLM Chain","type":"ai_languageModel","index":0}]]},"Capture Telegram Data":{"main":[[{"node":"File Received","type":"main","index":0}]]},"POST PurchaseInvoices":{"main":[[{"node":"PurchaseInvoices created","type":"main","index":0}]]},"Generate DocumentLines":{"main":[[{"node":"Merge","type":"main","index":1}]]},"Get Results LlamaIndex":{"main":[[{"node":"Basic LLM Chain","type":"main","index":0}]]},"Upload File LlamaIndex":{"main":[[{"node":"Validate Status LlamaIndex","type":"main","index":0}]]},"Callback Waiting Answer":{"main":[[{"node":"Answer?","type":"main","index":0}]]},"Trigger Receive Message":{"main":[[{"node":"Capture Telegram Data","type":"main","index":0}]]},"Validate Status LlamaIndex":{"main":[[{"node":"Status?","type":"main","index":0}]]},"Structured Output Parser (Example)":{"ai_outputParser":[[{"node":"Basic LLM Chain","type":"ai_outputParser","index":0}]]}}}


name: Automated Multi-Platform Sales Agent with RAG, CRM & Payment Processing
author_name: Electrabot
author_username: vansh404
categories: []
created_at: 2025-06-10T18:54:19.132Z
updated_at: 2025-06-10T18:54:19.132Z
url: https://n8n.io/workflows/4859
scraped_at: 2025-07-06 21:16:30
description:
  Turn More Website and Social Media Leads into Sales, Automatically.

  This AI workflow instantly connects with new leads from your website, WhatsApp, Instagram, and Facebook, acting as your 24/7 automated sales agent to boost sales.

  Who is it for?

  This solution is designed for:

  Businesses wanting to maximize sales from their online leads.
  Sales Teams looking to automate lead engagement and close deals faster.
  Companies that need to provide instant, personalized responses on all channels.
  Use Case: Turn Conversations into Conversions, 24/7

  When a customer messages you on any channel, our AI instantly starts a natural conversation. It understands their needs, suggests the right products, and can even offer a special discount to close the deal. The AI sends payment links directly in the chat and books meetings in your calendar, all while automatically updating your CRM. Every lead is handled perfectly, from start to finish.

  How This Workflow Works:

  This intelligent system streamlines your entire sales process:

  Lead Capture: Engages leads from website forms, web chat, WhatsApp, Instagram, and Facebook.
  AI-Powered Sales: Qualifies leads, answers questions, and recommends products using your business information.
  Automated Actions: Sends payment links, offers discounts, books meetings, and updates your CRM automatically.
  Multi-Channel Communication: Manages the entire conversation on the customer's preferred platform.
  How to Set It Up:

  Connect your tools: Link your social media, CRM, calendar, and payment gateways.
  Create a knowledge base: Give the AI your product details, sales info, and company FAQs.
  Personalize the AI: Customize the agent’s personality and responses to match your brand's voice.
  Go Live: Embed the chat on your website and activate it across your social channels to start selling automatically.

  DEMO DATABASE -
  https://airtable.com/appFUS6RjSdbJhtR0/shrIEUJf9egBqDl8q

nodes_used:
  ["n8n-nodes-base.httpRequest","n8n-nodes-base.postgres","n8n-nodes-base.facebookGraphApi","n8n-nodes-base.whatsApp","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.memoryBufferWindow","@n8n/n8n-nodes-langchain.toolWorkflow","@n8n/n8n-nodes-langchain.openAi","@n8n/n8n-nodes-langchain.embeddingsGoogleGemini","@n8n/n8n-nodes-langchain.lmChatGoogleGemini","@n8n/n8n-nodes-langchain.memoryPostgresChat","@n8n/n8n-nodes-langchain.toolVectorStore","@n8n/n8n-nodes-langchain.vectorStorePGVector"]

workflow_json:
  {"meta":{"instanceId":"28099d2544433ae0f39c65315a4d4c531947fcb0f060a94d6047d7be5df31063"},"nodes":[{"id":"fc1c7eb2-f966-4780-8bc6-b6ba22e2a924","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[3220,700],"parameters":{},"typeVersion":1.7},{"id":"fc3c4d99-5891-4f11-b5d6-d1f1ee5cd303","name":"No Operation, do nothing","type":"n8n-nodes-base.noOp","position":[2800,680],"parameters":{},"typeVersion":1},{"id":"1594475a-b111-4d64-86ad-7cdde127dae1","name":"Calendar Agent","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[3260,920],"parameters":{},"typeVersion":2},{"id":"099a27aa-b6d1-4e7d-846a-b7b997e50c2a","name":"CRM Agent","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[3380,920],"parameters":{},"typeVersion":2},{"id":"df8f0ce9-a9e4-4457-9836-f884a97fa819","name":"Postgres Chat Memory","type":"@n8n/n8n-nodes-langchain.memoryPostgresChat","position":[3140,920],"parameters":{},"typeVersion":1.3},{"id":"fd5ed307-4d18-4e4e-ab2f-8ec7f2726eb6","name":"Handle Message Types","type":"n8n-nodes-base.switch","position":[1700,680],"parameters":{},"typeVersion":3.2},{"id":"8016b3f6-b288-4d55-b3a1-03edd2171a56","name":"Reply To User1","type":"n8n-nodes-base.whatsApp","position":[1920,880],"webhookId":"0e86d9ab-6130-44f5-a7f1-4930bfcad48b","parameters":{},"typeVersion":1},{"id":"8fd8ef0f-7e1e-44f7-9d9d-b574ecd03d9b","name":"Edit Fields - chat1","type":"n8n-nodes-base.set","position":[2580,480],"parameters":{},"typeVersion":3.4},{"id":"d2008bd2-b8d1-41eb-88a4-3e234df59790","name":"Reply To  User","type":"n8n-nodes-base.whatsApp","position":[4220,580],"webhookId":"3b2ca5bf-7b1d-4012-b68e-ef06653a3c18","parameters":{},"typeVersion":1},{"id":"1fc97a0e-fc10-414a-9b07-0361fa7fbe82","name":"WhatsApp","type":"n8n-nodes-base.whatsAppTrigger","position":[1260,680],"webhookId":"aaf6d81e-dbdd-47e2-a2d4-c496ff92933b","parameters":{},"typeVersion":1},{"id":"c00e2d94-5884-45ab-ab42-14b059ba67d4","name":"WhatsApp Business Cloud","type":"n8n-nodes-base.whatsApp","position":[1920,680],"webhookId":"5cbf4730-3963-45f9-8457-6f41e648d4fe","parameters":{},"typeVersion":1},{"id":"64c1465e-60a5-42d7-9693-5f5ebce1a2a2","name":"HTTP Request","type":"n8n-nodes-base.httpRequest","position":[2140,680],"parameters":{},"typeVersion":4.2},{"id":"c3960605-94fb-42e4-b600-da1d00b72db0","name":"OpenAI","type":"@n8n/n8n-nodes-langchain.openAi","position":[2360,680],"parameters":{},"typeVersion":1.8},{"id":"181f6ff9-04c6-4614-9d92-f2f95c843ac1","name":"Edit Fields - chat2","type":"n8n-nodes-base.set","position":[2580,680],"parameters":{},"typeVersion":3.4},{"id":"da170c50-289d-49de-bd66-3014a0864eaa","name":"Output - chat","type":"n8n-nodes-base.set","position":[4220,1160],"parameters":{},"typeVersion":3.4},{"id":"7a047681-55a4-46bb-b24d-6f75df3e8499","name":"Postgres PGVector Store","type":"@n8n/n8n-nodes-langchain.vectorStorePGVector","position":[3320,1300],"parameters":{},"typeVersion":1.1},{"id":"403e783d-a3ae-4dd3-8ed6-6de60490f9f2","name":"Get Lead","type":"n8n-nodes-base.postgres","position":[1480,680],"parameters":{},"typeVersion":2.6},{"id":"9a3d1aa6-77a4-4903-aeca-c91c7a1c2c93","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[2340,1700],"webhookId":"0e63503d-ab21-4a3d-8d29-19c5d94c24d4","parameters":{},"typeVersion":1.1},{"id":"62c3803a-a4fe-44dc-95c6-e2ef44a52f66","name":"Google Gemini Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[3020,920],"parameters":{},"typeVersion":1},{"id":"052eb8f1-74ed-46b0-9777-d8b901d295ab","name":"Google Gemini Chat Model1","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[3120,1240],"parameters":{},"typeVersion":1},{"id":"c4735285-ee35-4a38-9638-1422599cbe71","name":"Embeddings Google Gemini1","type":"@n8n/n8n-nodes-langchain.embeddingsGoogleGemini","position":[3340,1440],"parameters":{},"typeVersion":1},{"id":"0fd7d9e7-97f8-454f-93ec-0f2fd16f9616","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[1140,440],"parameters":{"content":""},"typeVersion":1},{"id":"0500f16c-6b06-42a7-b6bb-ff7fb01bcde0","name":"Simple Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[180,1680],"parameters":{},"typeVersion":1.3},{"id":"86b1e536-f5e8-4296-8238-9d23b760305a","name":"Create Charge","type":"n8n-nodes-base.stripeTool","position":[300,1680],"parameters":{},"typeVersion":1},{"id":"a2bb895a-61fc-404b-9efa-9ef1cfdc6909","name":"Create Discount Coupon","type":"n8n-nodes-base.stripeTool","position":[420,1680],"parameters":{},"typeVersion":1},{"id":"5924b845-9f4f-4a08-909c-b7871b505457","name":"Get Customer Card","type":"n8n-nodes-base.stripeTool","position":[540,1680],"parameters":{},"typeVersion":1},{"id":"4348c965-a204-4f96-9e37-cc9d8505d795","name":"Get Customer","type":"n8n-nodes-base.stripeTool","position":[660,1680],"parameters":{},"typeVersion":1},{"id":"9b2727f5-372a-4e72-bdc9-d704b0cf525d","name":"Create Customer","type":"n8n-nodes-base.stripeTool","position":[780,1680],"parameters":{},"typeVersion":1},{"id":"0d6c31e2-e77e-4426-8bfb-98efbc5dfc27","name":"Update Customer","type":"n8n-nodes-base.stripeTool","position":[900,1680],"parameters":{},"typeVersion":1},{"id":"59d12b07-a90b-44d0-8df6-3795e68dc43b","name":"Delete Customer","type":"n8n-nodes-base.stripeTool","position":[1020,1680],"parameters":{},"typeVersion":1},{"id":"6082562f-04e1-4203-a237-6e892d51f77c","name":"Google Gemini Chat Model4","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[60,1680],"parameters":{},"typeVersion":1},{"id":"b9c5fdca-adcc-42aa-9a77-922cc7131ab1","name":"Response1","type":"n8n-nodes-base.set","position":[900,1280],"parameters":{},"typeVersion":3.4},{"id":"732f64b4-8fb5-4490-8670-f6d9a1f35ed6","name":"Try Again2","type":"n8n-nodes-base.set","position":[920,1480],"parameters":{},"typeVersion":3.4},{"id":"d9eef59c-6d02-490c-ac01-6aca37b35a7f","name":"Billing Agent","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[3500,920],"parameters":{},"typeVersion":2.1},{"id":"bfbf29cd-2fc4-436e-baeb-1aa74c8475e1","name":"Billing Agent1","type":"@n8n/n8n-nodes-langchain.agent","position":[460,1460],"parameters":{},"typeVersion":1.9},{"id":"ba688bbd-4b96-4d4f-83c4-ec032e52e09e","name":"technical_and_sales_knowledge","type":"@n8n/n8n-nodes-langchain.toolVectorStore","position":[3020,1080],"parameters":{},"typeVersion":1,"alwaysOutputData":true},{"id":"752270b8-c6f2-48b8-a7e0-e0fefb849aff","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[0,1260],"parameters":{"content":""},"typeVersion":1},{"id":"56557012-e746-4a12-b109-e2e278a6a76e","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[0,0],"parameters":{"content":""},"typeVersion":1},{"id":"ddf2121e-3d3d-49b1-84a0-18a3e32f5fd6","name":"Facebook Trigger","type":"n8n-nodes-base.webhook","position":[1460,1220],"webhookId":"b7e461f0-9a0d-4e27-9e86-f74a3e684e3a","parameters":{},"typeVersion":2},{"id":"e163aed9-7345-4759-9793-befac35ec3d4","name":"Edit Fields - facebook","type":"n8n-nodes-base.set","position":[2120,1220],"parameters":{},"typeVersion":3.4},{"id":"a8fc15d6-98d7-4ce6-9a5f-e20f8daa8746","name":"Respond to Webhook - facebook post","type":"n8n-nodes-base.respondToWebhook","position":[1680,1120],"parameters":{},"typeVersion":1.1},{"id":"b1c56265-23cd-46f6-846e-18563017c5c7","name":"Respond to Webhook - facebook get","type":"n8n-nodes-base.respondToWebhook","position":[1680,1320],"parameters":{},"typeVersion":1.1},{"id":"7396d841-8a00-4be8-b734-dbe8f3619eb9","name":"Instagram Trigger","type":"n8n-nodes-base.webhook","position":[1780,1580],"webhookId":"cc6546da-6f16-4546-ada3-e2c83b208997","parameters":{},"typeVersion":2},{"id":"1d5adb5a-17d1-49ca-b83d-c808d5c8d14a","name":"Respond to Webhook - instagram get","type":"n8n-nodes-base.respondToWebhook","position":[2000,1680],"parameters":{},"typeVersion":1.1},{"id":"f5103d0f-0c4c-4d74-bc3c-fd3abbb6a7c1","name":"Respond to Webhook - instagram post","type":"n8n-nodes-base.respondToWebhook","position":[2000,1480],"parameters":{},"typeVersion":1.1},{"id":"acb6125b-e342-4d72-b09b-5479756c6030","name":"Edit Fields - instagram","type":"n8n-nodes-base.set","position":[2440,1480],"parameters":{},"typeVersion":3.4},{"id":"d2de4df9-416f-4c9f-8104-3f8287fc236c","name":"If is not echo - facebook","type":"n8n-nodes-base.if","position":[1900,1120],"parameters":{},"typeVersion":2.2},{"id":"6d10c7be-6c36-4c0c-a802-9756ac1d3e70","name":"If is not echo - instagram","type":"n8n-nodes-base.if","position":[2220,1480],"parameters":{},"typeVersion":2.2},{"id":"346ce220-4d11-4e9c-93e7-548a1d0c155f","name":"Sales Agent Demo - typing_on","type":"n8n-nodes-base.facebookGraphApi","position":[2120,1020],"parameters":{},"typeVersion":1},{"id":"3f42b084-25ec-473c-8106-932cf2e7d9a6","name":"Edit Fields - chat","type":"n8n-nodes-base.set","position":[2540,1700],"parameters":{},"typeVersion":3.4},{"id":"6a6107ac-f35d-4c81-b28a-1a81672a55fb","name":"Facebook Graph API - Sales Agent Demo","type":"n8n-nodes-base.facebookGraphApi","position":[4220,760],"parameters":{},"typeVersion":1},{"id":"331b9eac-c0ab-4935-83b6-5a703d0dddd0","name":"Instagram Graph API - smb.sales.agent.demo","type":"n8n-nodes-base.httpRequest","position":[4220,940],"parameters":{},"typeVersion":4.2},{"id":"4acbb570-65a3-4973-a106-c06151cd039b","name":"Switch1","type":"n8n-nodes-base.switch","position":[3780,840],"parameters":{},"typeVersion":3.2},{"id":"dffc3f73-3c04-4c7a-b976-57d71533fcbd","name":"Send First Message","type":"n8n-nodes-base.whatsApp","position":[3220,160],"webhookId":"89b0633a-88c4-4fe8-82f4-4e3ae20a075a","parameters":{},"typeVersion":1},{"id":"bdb62be6-5385-4d78-a4ce-be539bb22d29","name":"Personalised First Message","type":"@n8n/n8n-nodes-langchain.agent","position":[2880,60],"parameters":{},"typeVersion":1.8},{"id":"45b92ce3-0e74-4b29-86de-4264e3378118","name":"Gemini","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[2920,280],"parameters":{},"typeVersion":1},{"id":"50bb8e6c-caf6-4d1f-aac1-95969b5cfff9","name":"Contact Form","type":"n8n-nodes-base.formTrigger","position":[2460,160],"webhookId":"a34f7372-b42d-4176-ac9b-2518d85c125d","parameters":{},"typeVersion":2.2},{"id":"e35aa634-5fc8-476c-938c-16dcee3bf78f","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[2400,0],"parameters":{"content":""},"typeVersion":1},{"id":"03ff50c6-dc0c-438f-be24-0caa3479ecc3","name":"Response","type":"n8n-nodes-base.set","position":[2160,20],"parameters":{},"typeVersion":3.4},{"id":"565eca10-2203-4124-adcd-de9e88106ab7","name":"Try Again","type":"n8n-nodes-base.set","position":[2000,120],"parameters":{},"typeVersion":3.4},{"id":"e4d6dfc1-064f-413d-96f7-a69e61629e7a","name":"When Executed by Another Workflow","type":"n8n-nodes-base.executeWorkflowTrigger","position":[1240,60],"parameters":{},"typeVersion":1.1},{"id":"c453f5bc-c271-4848-bacc-642e861880fb","name":"Window Buffer Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[1360,280],"parameters":{},"typeVersion":1.3},{"id":"00256e82-9f75-4bf5-b398-ff6fa777e355","name":"Success","type":"n8n-nodes-base.set","position":[4140,60],"parameters":{},"typeVersion":3.4},{"id":"ea7c1010-8de9-46da-a9f9-75d0dbd25d0a","name":"Create Event with Attendee","type":"n8n-nodes-base.googleCalendarTool","position":[3660,280],"parameters":{},"typeVersion":1.3},{"id":"9ea7a1d6-a78d-4299-930c-2e8428861f55","name":"Create Event","type":"n8n-nodes-base.googleCalendarTool","position":[3780,280],"parameters":{},"typeVersion":1.3},{"id":"019a38f2-4447-4b31-8fc5-41cf0ca90a29","name":"Get Events","type":"n8n-nodes-base.googleCalendarTool","position":[3900,280],"parameters":{},"typeVersion":1.3},{"id":"c3352115-f872-46a8-a880-bd45d9e082b9","name":"Delete Event","type":"n8n-nodes-base.googleCalendarTool","position":[4020,280],"parameters":{},"typeVersion":1.3},{"id":"d6c48e3b-7e3f-4924-a41d-e772e3e1b208","name":"Update Event","type":"n8n-nodes-base.googleCalendarTool","position":[4140,280],"parameters":{},"typeVersion":1.3},{"id":"c78ead66-8c1c-4003-82dd-4e3ba42dd04a","name":"Try Again1","type":"n8n-nodes-base.set","position":[4260,220],"parameters":{},"typeVersion":3.4},{"id":"e0473a31-8f1e-462c-9b15-6f84a5db76a3","name":"Calendar Agent1","type":"@n8n/n8n-nodes-langchain.agent","onError":"continueErrorOutput","position":[3680,60],"parameters":{},"typeVersion":1.6},{"id":"705c27dc-47d9-4401-bd11-b2a68a8af8e5","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[3460,0],"parameters":{"content":""},"typeVersion":1},{"id":"fc98cf69-c168-4ae0-8d1d-66f250414f6b","name":"Google Gemini Chat Model2","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[1240,280],"parameters":{},"typeVersion":1},{"id":"9117f2b8-000a-4cf5-8c4b-18a8d46094b3","name":"Create Opportunity","type":"n8n-nodes-base.postgresTool","position":[1480,280],"parameters":{},"typeVersion":2.6},{"id":"4ba86ac5-dec6-40ae-9eb3-02f7d1644849","name":"List Records","type":"n8n-nodes-base.postgresTool","position":[1600,280],"parameters":{},"typeVersion":2.6},{"id":"bc13a69b-9825-44eb-80f3-972b5b29a2b3","name":"Update Contact","type":"n8n-nodes-base.postgresTool","position":[1720,280],"parameters":{},"typeVersion":2.6},{"id":"e0b84bcb-b5b5-4c1e-9600-d22b1aa77046","name":"Delete Contact","type":"n8n-nodes-base.postgresTool","position":[1960,280],"parameters":{},"typeVersion":2.6},{"id":"f398eeee-61bd-40bb-96a9-0fb580797199","name":"Delete Opportunity","type":"n8n-nodes-base.postgresTool","position":[2080,280],"parameters":{},"typeVersion":2.6},{"id":"10a4a520-2e13-4579-b1dd-66c2b5434315","name":"Update Opportunity","type":"n8n-nodes-base.postgresTool","position":[2200,280],"parameters":{},"typeVersion":2.6},{"id":"b8342a8f-1d0d-4d77-a537-6f29e033139c","name":"Google Gemini Chat Model3","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[3540,280],"parameters":{},"typeVersion":1},{"id":"c7a34e7e-09a2-45ef-ba7b-6929625d5604","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1140,0],"parameters":{"content":""},"typeVersion":1},{"id":"91fdb189-8e68-458d-9f1f-eb8537964211","name":"Create Contact","type":"n8n-nodes-base.postgresTool","position":[1840,280],"parameters":{},"typeVersion":2.6},{"id":"b5971e41-2122-4a06-a51d-1d5e392f1a51","name":"CRM Agent2","type":"@n8n/n8n-nodes-langchain.agent","onError":"continueErrorOutput","position":[1500,60],"parameters":{},"typeVersion":1.7},{"id":"6c53a122-d748-418e-bc25-886fbfdc3ce8","name":"Create Contact1","type":"n8n-nodes-base.postgres","position":[2660,160],"parameters":{},"typeVersion":2.6}],"connections":{"Gemini":{"ai_languageModel":[[{"node":"Personalised First Message","type":"ai_languageModel","index":0}]]},"OpenAI":{"main":[[{"node":"Edit Fields - chat2","type":"main","index":0}]]},"Switch1":{"main":[[{"node":"Reply To  User","type":"main","index":0}],[{"node":"Facebook Graph API - Sales Agent Demo","type":"main","index":0}],[{"node":"Instagram Graph API - smb.sales.agent.demo","type":"main","index":0}],[{"node":"Output - chat","type":"main","index":0}]]},"AI Agent":{"main":[[{"node":"Switch1","type":"main","index":0}]]},"Get Lead":{"main":[[{"node":"Handle Message Types","type":"main","index":0}]]},"WhatsApp":{"main":[[{"node":"Get Lead","type":"main","index":0}]]},"CRM Agent":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"CRM Agent2":{"main":[[{"node":"Response","type":"main","index":0}],[{"node":"Try Again","type":"main","index":0}]]},"Get Events":{"ai_tool":[[{"node":"Calendar Agent1","type":"ai_tool","index":0}]]},"Contact Form":{"main":[[{"node":"Create Contact1","type":"main","index":0}]]},"Create Event":{"ai_tool":[[{"node":"Calendar Agent1","type":"ai_tool","index":0}]]},"Delete Event":{"ai_tool":[[{"node":"Calendar Agent1","type":"ai_tool","index":0}]]},"Get Customer":{"ai_tool":[[{"node":"Billing Agent1","type":"ai_tool","index":0}]]},"HTTP Request":{"main":[[{"node":"OpenAI","type":"main","index":0}]]},"List Records":{"ai_tool":[[{"node":"CRM Agent2","type":"ai_tool","index":0}]]},"Update Event":{"ai_tool":[[{"node":"Calendar Agent1","type":"ai_tool","index":0}]]},"Billing Agent":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"Create Charge":{"ai_tool":[[{"node":"Billing Agent1","type":"ai_tool","index":0}]]},"Simple Memory":{"ai_memory":[[{"node":"Billing Agent1","type":"ai_memory","index":0}]]},"Billing Agent1":{"main":[[{"node":"Response1","type":"main","index":0},{"node":"Try Again2","type":"main","index":0}]]},"Calendar Agent":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"Create Contact":{"ai_tool":[[{"node":"CRM Agent2","type":"ai_tool","index":0}]]},"Delete Contact":{"ai_tool":[[{"node":"CRM Agent2","type":"ai_tool","index":0}]]},"Update Contact":{"ai_tool":[[{"node":"CRM Agent2","type":"ai_tool","index":0}]]},"Calendar Agent1":{"main":[[{"node":"Success","type":"main","index":0}],[{"node":"Try Again1","type":"main","index":0}]]},"Create Contact1":{"main":[[{"node":"Personalised First Message","type":"main","index":0}]]},"Create Customer":{"ai_tool":[[{"node":"Billing Agent1","type":"ai_tool","index":0}]]},"Delete Customer":{"ai_tool":[[{"node":"Billing Agent1","type":"ai_tool","index":0}]]},"Update Customer":{"ai_tool":[[{"node":"Billing Agent1","type":"ai_tool","index":0}]]},"Facebook Trigger":{"main":[[{"node":"Respond to Webhook - facebook post","type":"main","index":0}],[{"node":"Respond to Webhook - facebook get","type":"main","index":0}]]},"Get Customer Card":{"ai_tool":[[{"node":"Billing Agent1","type":"ai_tool","index":0}]]},"Instagram Trigger":{"main":[[{"node":"Respond to Webhook - instagram post","type":"main","index":0}],[{"node":"Respond to Webhook - instagram get","type":"main","index":0}]]},"Create Opportunity":{"ai_tool":[[{"node":"CRM Agent2","type":"ai_tool","index":0}]]},"Delete Opportunity":{"ai_tool":[[{"node":"CRM Agent2","type":"ai_tool","index":0}]]},"Edit Fields - chat":{"main":[[{"node":"No Operation, do nothing","type":"main","index":0}]]},"Update Opportunity":{"ai_tool":[[{"node":"CRM Agent2","type":"ai_tool","index":0}]]},"Edit Fields - chat1":{"main":[[{"node":"No Operation, do nothing","type":"main","index":0}]]},"Edit Fields - chat2":{"main":[[{"node":"No Operation, do nothing","type":"main","index":0}]]},"Handle Message Types":{"main":[[{"node":"Edit Fields - chat1","type":"main","index":0}],[{"node":"WhatsApp Business Cloud","type":"main","index":0}],[{"node":"Reply To User1","type":"main","index":0}]]},"Postgres Chat Memory":{"ai_memory":[[{"node":"AI Agent","type":"ai_memory","index":0}]]},"Window Buffer Memory":{"ai_memory":[[{"node":"CRM Agent2","type":"ai_memory","index":0}]]},"Create Discount Coupon":{"ai_tool":[[{"node":"Billing Agent1","type":"ai_tool","index":0}]]},"Edit Fields - facebook":{"main":[[{"node":"No Operation, do nothing","type":"main","index":0}]]},"Edit Fields - instagram":{"main":[[{"node":"No Operation, do nothing","type":"main","index":0}]]},"Postgres PGVector Store":{"ai_vectorStore":[[{"node":"technical_and_sales_knowledge","type":"ai_vectorStore","index":0}]]},"WhatsApp Business Cloud":{"main":[[{"node":"HTTP Request","type":"main","index":0}]]},"Google Gemini Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"No Operation, do nothing":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"Embeddings Google Gemini1":{"ai_embedding":[[{"node":"Postgres PGVector Store","type":"ai_embedding","index":0}]]},"Google Gemini Chat Model1":{"ai_languageModel":[[{"node":"technical_and_sales_knowledge","type":"ai_languageModel","index":0}]]},"Google Gemini Chat Model2":{"ai_languageModel":[[{"node":"CRM Agent2","type":"ai_languageModel","index":0}]]},"Google Gemini Chat Model3":{"ai_languageModel":[[{"node":"Calendar Agent1","type":"ai_languageModel","index":0}]]},"Google Gemini Chat Model4":{"ai_languageModel":[[{"node":"Billing Agent1","type":"ai_languageModel","index":0}]]},"If is not echo - facebook":{"main":[[{"node":"Edit Fields - facebook","type":"main","index":0},{"node":"Sales Agent Demo - typing_on","type":"main","index":0}]]},"Create Event with Attendee":{"ai_tool":[[{"node":"Calendar Agent1","type":"ai_tool","index":0}]]},"If is not echo - instagram":{"main":[[{"node":"Edit Fields - instagram","type":"main","index":0}]]},"Personalised First Message":{"main":[[{"node":"Send First Message","type":"main","index":0}]]},"When chat message received":{"main":[[{"node":"Edit Fields - chat","type":"main","index":0}]]},"Sales Agent Demo - typing_on":{"main":[[{"node":"No Operation, do nothing","type":"main","index":0}]]},"technical_and_sales_knowledge":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"When Executed by Another Workflow":{"main":[[{"node":"CRM Agent2","type":"main","index":0}]]},"Respond to Webhook - facebook post":{"main":[[{"node":"If is not echo - facebook","type":"main","index":0}]]},"Respond to Webhook - instagram post":{"main":[[{"node":"If is not echo - instagram","type":"main","index":0}]]}}}


name: YouTube Comment Scraper & Analyzer with GPT-4o + Email Summary Report
author_name: Amit Mehta
author_username: amitswba
categories: []
created_at: 2025-06-11T00:37:10.771Z
updated_at: 2025-06-11T00:37:10.771Z
url: https://n8n.io/workflows/4863
scraped_at: 2025-07-06 21:16:30
description:
  How it Works

  This workflow automates the collection and analysis of YouTube comments from a video and sends a summary report via email, using Google Sheets, the YouTube API, OpenAI (GPT-4o), and Gmail.

  Whether you're a content creator, brand manager, or social media analyst, this workflow helps you automate sentiment analysis and receive insights directly in your inbox — all triggered from a simple spreadsheet.

  🎯 Use Case

  Ideal for:
  YouTubers** monitoring audience sentiment
  Marketing teams** analyzing campaign feedback
  Community managers** summarizing engagement

  Setup Instructions

  1. Upload the Spreadsheet

  File name: Youtube_Video
  Sheet structure:
  | ID | Video Title | YouTube Video ID | Status |
  Add video IDs and set their Status as Pending

  2. Configure Google Sheets Nodes

  Connect your Google account to:
  Pick Video IDs from Google Sheet
  Update Status on Google Sheet

  3. Add API Credentials

  YouTube API Key** → for comment + video scraping nodes
  OpenAI API Key** → for analyzing comments
  Gmail Account** → for sending the summary email

  4. Activate the Workflow

  Once live, the workflow will:
  Watch for new or updated rows in the spreadsheet
  Scrape comments using the YouTube API
  Analyze sentiment and key themes via GPT-4o
  Send a formatted HTML email with the summary
  Update the spreadsheet status to Mail sent

  🔁 Workflow Logic

  Trigger: New/updated row in Google Sheet
  Retrieve: YouTube video metadata + comments
  Analyze: Comments using GPT-4o
  Email: Summary report via Gmail
  Update: Spreadsheet status to Mail sent

  🧩 Node Descriptions

  | Node Name | Description |
  |-----------|-------------|
  | Pick Video IDs from Google Sheet | Watches the spreadsheet and retrieves pending video IDs |
  | If | Checks whether status is 'Pending' |
  | Limit | Restricts the number of processed rows |
  | Set Video Details | Prepares video info (e.g., title, channel) |
  | Get YouTube Video Details | Fetches metadata (title, channel, etc.) |
  | Get YouTube Video Comments | Pulls top-level comments using YouTube API |
  | Prepare Comments Data | Formats comment text for OpenAI |
  | AI Agent | Summarizes comments using OpenAI's GPT-4o |
  | Prepare HTML for Email | Converts summary into HTML for email body |
  | Gmail Account Configuration | Sends the email report via Gmail |
  | Update Status on Google Sheet | Marks the row as 'Mail sent' |

  🛠️ Customization Tips

  Change the AI prompt for tone, length, or custom metrics
  Send results to Slack or Telegram instead of Gmail
  Export summaries to Notion, Airtable, or PDF
  Schedule it daily/weekly for recurring analysis

  📒 Suggested Sticky Notes for Workflow

  | Node/Section | Sticky Note Content |
  |--------------|---------------------|
  | Pick Video IDs from Google Sheet | "Triggers on new YouTube videos in your spreadsheet" |
  | AI Agent | "Uses OpenAI to generate an analysis summary – customize prompt as needed" |
  | Gmail | "Sends summary report – you can update subject, recipients, or style" |
  | Update Status | "Marks video as processed to avoid duplicate runs" |

  📎 Required Files

  | File Name | Purpose |
  |-----------|---------|
  | Youtube_Video | Google Sheet to hold YouTube video IDs and status |
  | Youtube_Comment_Scraper.json | Main n8n workflow export for this automation |

  🧪 Testing Tips

  Add one test video with a valid YouTube video ID and status = Pending
  Monitor the workflow logs to confirm API responses
  Confirm summary delivery in your inbox
  Verify that status updates in the sheet

  🏷 Suggested Tags & Categories

  #YouTube
  #OpenAI
  #Automation
  #Marketing
  #Email
  #Analytics

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

workflow_json:
  {"id":"ItynUguvK0Dx6mw4","meta":{"instanceId":"260491e02302632e6a217f5c83135ad573c31ec4f93b05d79785a77df9c4a7e5","templateCredsSetupCompleted":true},"name":"Youtube Comment Scraper","tags":[],"nodes":[{"id":"workflow-overview-note","name":"Workflow Overview","type":"n8n-nodes-base.stickyNote","position":[-300,-250],"parameters":{"color":2,"width":350,"height":400,"content":"# 📊 YouTube Comment Analyzer Workflow\n\n**Purpose:** Automate YouTube comment collection, sentiment analysis, and email reporting\n\n**Schedule:** Triggers every minute for new/updated rows\n\n**Required Setup:**\n1. Google Sheet with video IDs\n2. YouTube API credentials\n3. OpenAI API key\n4. Gmail account\n\n## Workflow Steps:\n1. **Trigger** - Monitor Google Sheet\n2. **Filter** - Process only 'Pending' videos\n3. **Fetch** - Get video details & comments\n4. **Analyze** - AI sentiment analysis\n5. **Report** - Send email summary\n6. **Update** - Mark as processed"},"typeVersion":1},{"id":"trigger-section-note","name":"Trigger Documentation","type":"n8n-nodes-base.stickyNote","position":[-50,-250],"parameters":{"color":3,"width":300,"height":220,"content":"## 🚀 Trigger Section\n\n**Google Sheets Trigger**\nMonitors the spreadsheet every minute for:\n- New video IDs added\n- Status changes to 'Pending'\n\n**Required Sheet Structure:**\n| ID | Video Title | YouTube Video ID | Status |\n\n⚠️ Set Status to 'Pending' to trigger analysis"},"typeVersion":1},{"id":"youtube-data-note","name":"YouTube API Section","type":"n8n-nodes-base.stickyNote","position":[770,-250],"parameters":{"color":1,"width":280,"height":200,"content":"## 📹 YouTube Data Collection\n\n**This section fetches:**\n- Video metadata (title, channel)\n- Top 100 comments\n- Comment statistics\n\n**API Limits:**\n- Max 100 comments per request\n- Ordered by relevance\n- Top-level comments only"},"typeVersion":1},{"id":"ai-analysis-note","name":"AI Analysis Documentation","type":"n8n-nodes-base.stickyNote","position":[1420,-280],"parameters":{"color":5,"width":320,"height":250,"content":"## 🤖 AI Analysis Section\n\n**GPT-4o analyzes comments for:**\n1. Sentiment breakdown (positive/negative/neutral)\n2. Main themes & topics\n3. Common viewer questions\n4. Key feedback points\n5. Actionable insights\n\n**Output Format:** Structured JSON with underscore keys\n\n💡 Customize the prompt in AI Agent node for different analysis needs"},"typeVersion":1},{"id":"email-update-note","name":"Email & Status Update","type":"n8n-nodes-base.stickyNote","position":[2036,-250],"parameters":{"color":4,"width":300,"height":220,"content":"## 📧 Email & Update Section\n\n**Email Report includes:**\n- Video statistics\n- Sentiment analysis\n- Key insights\n- Formatted HTML\n\n**Final Step:**\nUpdates Google Sheet status to 'Mail Sent' to prevent duplicate processing\n\n⚠️ Update recipient email in Gmail node"},"typeVersion":1},{"id":"data-prep-note","name":"Data Processing Note","type":"n8n-nodes-base.stickyNote","position":[1270,200],"parameters":{"color":6,"width":250,"height":180,"content":"⚠️ **Data Preparation**\n\nThis node:\n- Extracts comment texts\n- Calculates statistics\n- Performs basic sentiment analysis\n- Prepares data for AI\n\nLimited to 50 comments for AI analysis to manage token usage"},"typeVersion":1},{"id":"b5d9ad95-9fcc-4c3d-bf90-42e897ab5eda","name":"Limit","type":"n8n-nodes-base.limit","notes":"Limits processing to 1 item at a time to prevent API overload","position":[440,0],"parameters":{},"typeVersion":1},{"id":"d0f82101-07e6-4559-9b73-91b85dc77b40","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","notes":"Uses OpenAI GPT-4o to analyze comments and generate insights. Customize the prompt for different analysis needs.","position":[1540,0],"parameters":{"text":"=Analyze these comments from the video \"{{ $json.videoTitle }}\":\n\nTotal Comments: {{ $json.totalComments }}\nAverage Likes: {{ $json.avgLikes }}\n\nComments to analyze:\n{{ $json.commentTexts }}","options":{"maxIterations":100,"systemMessage":"You are a YouTube comment analyst. Analyze the provided comments and return a structured analysis with:\n1. Overall sentiment breakdown (positive/negative/neutral percentages)\n2. Top 3-5 main themes or topics discussed\n3. Common questions from viewers\n4. Key feedback points and suggestions\n5. Actionable insights for content improvement\n\nFormat your response in clear sections with headers in json key value format and use underscore in the key name. Always use following keys for output json: \n1. overall_sentiment_breakdown\n2. main_themes\n3. common_questions\n4. key_feedback_points\n5. actionable_insights"},"promptType":"define"},"typeVersion":1.9},{"id":"e7a9b6ea-af4a-4970-ba0e-3e18608015f5","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[1628,220],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{"responseFormat":"json_object"}},"credentials":{"openAiApi":{"id":"O2czYITX17GGksaO","name":"OpenAi account 4"}},"typeVersion":1.2},{"id":"7c22599f-6fa8-4461-9b81-89a283a9dc84","name":"If","type":"n8n-nodes-base.if","notes":"Filters rows to process only videos with 'Pending' status","position":[220,0],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"5f1eae10-5270-4e99-8627-597e3451c82c","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.Status }}","rightValue":"Pending"}]}},"typeVersion":2.2},{"id":"152902fb-d715-4473-972f-4f75e5788b7a","name":"Set Video Details","type":"n8n-nodes-base.set","notes":"Prepares video ID and sets max comments limit (100)","position":[660,0],"parameters":{"options":{},"assignments":{"assignments":[{"id":"219795ef-daa4-4444-9865-c5d3856be63b","name":"videoId","type":"string","value":"={{ $json['Youtube video id'] }}"},{"id":"cd4f519d-4c84-496c-8974-29ef69c890fc","name":"maxComments ","type":"number","value":100}]}},"typeVersion":3.4},{"id":"67bb511b-478c-4fec-ba6a-816d81a8bad1","name":"Get Youtube Video Details","type":"n8n-nodes-base.youTube","notes":"Fetches video metadata including title, channel name, and other details","position":[880,0],"parameters":{"options":{},"videoId":"={{ $json.videoId }}","resource":"video","operation":"get"},"credentials":{"youTubeOAuth2Api":{"id":"2Mya1dm7vKjkxzqb","name":"YouTube account"}},"typeVersion":1},{"id":"880379c3-791a-424f-a170-db214ee0bad0","name":"Get Youtube Video Comments","type":"n8n-nodes-base.httpRequest","notes":"Retrieves top 100 comments ordered by relevance using YouTube API","position":[1100,0],"parameters":{"url":"https://www.googleapis.com/youtube/v3/commentThreads","options":{},"sendQuery":true,"authentication":"predefinedCredentialType","queryParameters":{"parameters":[{"name":"part","value":"snippet"},{"name":"videoId","value":"={{ $('Set Video Details').item.json.videoId }}"},{"name":"maxResults","value":"100"},{"name":"order","value":"relevance"}]},"nodeCredentialType":"youTubeOAuth2Api"},"credentials":{"youTubeOAuth2Api":{"id":"2Mya1dm7vKjkxzqb","name":"YouTube account"}},"typeVersion":4.2},{"id":"4a7f24c6-5dea-400f-8f0b-351597cae840","name":"Prepare Comments Data","type":"n8n-nodes-base.code","notes":"Processes raw comments: extracts text, calculates stats, performs basic sentiment analysis, limits to 50 comments for AI","position":[1320,0],"parameters":{"jsCode":"// Get comments from HTTP Request node\nconst comments = $input.first().json.items\n//const comments = response.items || [];\n\n// Get video title from the YouTube node (step 5)\n//const videoData = ;\nconst videoTitle = $('Get Youtube Video Details').first().json.snippet.title;\n\n// Extract comment data\nconst processedComments = comments.map(item => {\n  const comment = item.snippet.topLevelComment.snippet;\n  return {\n    text: comment.textDisplay,\n    author: comment.authorDisplayName,\n    likes: comment.likeCount || 0,\n    publishedAt: comment.publishedAt,\n    replyCount: item.snippet.totalReplyCount || 0\n  };\n});\n\n// Calculate statistics\nconst totalComments = processedComments.length;\nconst totalLikes = processedComments.reduce((sum, c) => sum + c.likes, 0);\nconst avgLikes = totalComments > 0 ? (totalLikes / totalComments).toFixed(2) : 0;\nconst totalReplies = processedComments.reduce((sum, c) => sum + c.replyCount, 0);\n\n// Get top comments by likes\nconst topComments = processedComments\n  .sort((a, b) => b.likes - a.likes)\n  .slice(0, 5);\n\n// Prepare comment texts for AI analysis\nconst commentTexts = processedComments\n  .slice(0, 50) // Limit to 50 comments for AI analysis\n  .map(c => c.text)\n  .join('\\n---\\n');\n\n// Basic sentiment analysis (count positive/negative keywords)\nconst positiveWords = ['love', 'great', 'awesome', 'amazing', 'excellent', 'good', 'fantastic', 'helpful', 'thanks'];\nconst negativeWords = ['hate', 'terrible', 'awful', 'bad', 'worst', 'horrible', 'useless', 'waste'];\n\nlet positiveCount = 0;\nlet negativeCount = 0;\n\nprocessedComments.forEach(comment => {\n  const lowerText = comment.text.toLowerCase();\n  positiveWords.forEach(word => {\n    if (lowerText.includes(word)) positiveCount++;\n  });\n  negativeWords.forEach(word => {\n    if (lowerText.includes(word)) negativeCount++;\n  });\n});\n\nreturn [{\n  json: {\n    videoTitle,\n    totalComments,\n    avgLikes,\n    totalReplies,\n    topComments,\n    commentTexts,\n    processedComments,\n    sentimentCounts: {\n      positive: positiveCount,\n      negative: negativeCount,\n      neutral: totalComments - positiveCount - negativeCount\n    }\n  }\n}];\n\n"},"typeVersion":2},{"id":"06ddd27a-242e-4975-82e4-2795af0252a7","name":"Prepare HTML for Email","type":"n8n-nodes-base.code","notes":"Converts AI analysis into formatted HTML email with statistics, insights, and professional styling","position":[1916,0],"parameters":{"mode":"runOnceForEachItem","jsCode":"const output = JSON.parse($json.output)\n //return output; \n//return output.overall_sentiment_breakdown.Positive;\n\nlet common_question = \"\";\n  \noutput.common_questions.map(rec => {\n  return common_question += \"<li>\"+rec.trim().replace(new RegExp(\".*,$\"), \"\")+\"</li>\"\n})\n\nlet key_feedback_points_and_suggestions = \"\";\n\noutput.key_feedback_points.map(rec => {\n  return key_feedback_points_and_suggestions += \"<li>\"+rec.trim().replace(new RegExp(\".*,$\"), \"\")+\"</li>\"\n})\n\n\nlet actionable_insights_for_content_improvement = \"\"\n\noutput.actionable_insights.map(rec => {\n  return actionable_insights_for_content_improvement += \"<li>\"+rec.trim().replace(new RegExp(\".*,$\"), \"\")+\"</li>\"\n})\n\n\n// return {common_question};\n\n\n     \n\n//return output; \n// Generate the email HTML\nconst emailHTML = `\n<!DOCTYPE html>\n<html>\n<head>\n  <style>\n    body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }\n    .header { background: #f4f4f4; padding: 20px; border-radius: 5px; }\n    .section { margin: 20px 0; }\n    .stats { background: #e9ecef; padding: 15px; border-radius: 5px; }\n    .analysis { background: #f8f9fa; padding: 20px; border-radius: 5px; }\n    h2 { color: #2c3e50; }\n    h3 { color: #34495e; }\n    h4 { color: #7f8c8d; }\n    .footer { margin-top: 30px; padding-top: 20px; border-top: 1px solid #ddd; color: #666; font-size: 0.9em; }\n  </style>\n</head>\n<body>\n  <div class=\"header\">\n    <h2>YouTube Comments Analysis Report</h2>\n    <h3>Video: ${$(\"Prepare Comments Data\").item.json.videoTitle}</h3>\n  </div>\n\n  <div class=\"section stats\">\n    <h3> Quick Statistics</h3>\n    <ul>\n      <li><strong>Total Comments Analyzed:</strong> ${$('Prepare Comments Data').item.json.totalComments}</li>\n      <li><strong>Average Likes per Comment:</strong> ${$('Prepare Comments Data').item.json.avgLikes}</li>\n      <li><strong>Total Replies:</strong> ${$('Prepare Comments Data').item.json.totalReplies}</li>\n      <li><strong>Sentiment Summary:</strong> \n        Positive: ${output.overall_sentiment_breakdown.positive}, \n        Negative: ${output.overall_sentiment_breakdown.negative}, \n        Neutral: ${output.overall_sentiment_breakdown.neutral}\n      </li>\n    </ul>\n  </div>\n\n  <div class=\"section stats\">\n    <h3>Common Questions</h3>\n    <ul>\n      ${common_question}\n    </ul>\n  </div>\n\n    <div class=\"section stats\">\n    <h3>Key feedback points and suggestions</h3>\n    <ul>\n      ${key_feedback_points_and_suggestions}\n    </ul>\n  </div>\n\n\n  <div class=\"section stats\">\n    <h3>Actionable insights for content improvement</h3>\n    <ul>\n      ${actionable_insights_for_content_improvement}\n    </ul>\n  </div>\n\n\n\n\n  <div class=\"footer\">\n    <p><em>Report generated on ${new Date().toLocaleString()}</em></p>\n    \n  </div>\n</body>\n</html>`;\n\n\n// Return the formatted data\nreturn  {\n  json: {\n    emailHTML,\n    subject: `YouTube Analysis: ${$('Prepare Comments Data').item.json.videoTitle} - ${$('Prepare Comments Data').item.json.totalComments} comments analyzed`,\n    videoTitle: $('Prepare Comments Data').item.json.videoTitle\n  }\n};"},"typeVersion":2},{"id":"2c28a815-1e36-47ab-a96c-a3c040f60551","name":"Gmail Account Configuration","type":"n8n-nodes-base.gmail","notes":"Sends formatted analysis report via Gmail. Update SENDER_EMAIL_ADDRESS with actual recipient","position":[2136,0],"webhookId":"90b8f9ad-4226-42a0-971b-7fa9f5f190bd","parameters":{"sendTo":"SENDER_EMAIL_ADDRESS","message":"={{ $json.emailHTML }}","options":{},"subject":"={{ $json.subject }}"},"credentials":{"gmailOAuth2":{"id":"JYZ1uo6n4Jnfozjt","name":"Gmail account 3"}},"typeVersion":2.1},{"id":"1303d6f5-d8a8-44ea-b062-ba25dbb43e6e","name":"Update Status on Google Sheet","type":"n8n-nodes-base.googleSheets","notes":"Updates video status to 'Mail Sent' to prevent duplicate processing","position":[2356,0],"parameters":{"columns":{"value":{"Id":"={{ $('Pick Video Ids from Google sheet').item.json.Id }}","Status":"Mail Sent"},"schema":[{"id":"Id","type":"string","display":true,"removed":false,"required":false,"displayName":"Id","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Youtube video id","type":"string","display":true,"required":false,"displayName":"Youtube video id","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Status","type":"string","display":true,"required":false,"displayName":"Status","defaultMatch":false,"canBeUsedToMatch":true},{"id":"row_number","type":"string","display":true,"removed":true,"readOnly":true,"required":false,"displayName":"row_number","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["Id"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"update","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"GOOGLE_DRIVE_URL","cachedResultName":"Youtube_Video "},"documentId":{"__rl":true,"mode":"list","value":"1qe6Ovp_pfmwZA2k5c7LmmZx-OKqv3hnu8Dg80Pw4KoY","cachedResultUrl":"GOOGLE_DRIVE_URL","cachedResultName":"Youtube_Video"}},"credentials":{"googleSheetsOAuth2Api":{"id":"ApqY25iiOci0QMVA","name":"Google Sheets account 4"}},"typeVersion":4.5},{"id":"f9028f08-170b-4d2f-8c6b-b1dbf470d3a3","name":"Pick Video Ids from Google sheet","type":"n8n-nodes-base.googleSheetsTrigger","notes":"Triggers on new YouTube videos added to spreadsheet. Polls every minute for changes","position":[0,0],"parameters":{"options":{},"pollTimes":{"item":[{"mode":"everyMinute"}]},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"GOOGLE_DRIVE_URL","cachedResultName":"Youtube_Video "},"documentId":{"__rl":true,"mode":"list","value":"1qe6Ovp_pfmwZA2k5c7LmmZx-OKqv3hnu8Dg80Pw4KoY","cachedResultUrl":"GOOGLE_DRIVE_URL","cachedResultName":"Youtube_Video"}},"credentials":{"googleSheetsTriggerOAuth2Api":{"id":"qr4PWvkowXONSaw4","name":"Google Sheets Trigger account 4"}},"typeVersion":1}],"active":true,"settings":{"executionOrder":"v1"},"versionId":"be4e97c1-bc7f-4a62-bd2a-f636c65fd256","connections":{"If":{"main":[[{"node":"Limit","type":"main","index":0}]]},"Limit":{"main":[[{"node":"Set Video Details","type":"main","index":0}]]},"AI Agent":{"main":[[{"node":"Prepare HTML for Email","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"Set Video Details":{"main":[[{"node":"Get Youtube Video Details","type":"main","index":0}]]},"Prepare Comments Data":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"Prepare HTML for Email":{"main":[[{"node":"Gmail Account Configuration","type":"main","index":0}]]},"Get Youtube Video Details":{"main":[[{"node":"Get Youtube Video Comments","type":"main","index":0}]]},"Get Youtube Video Comments":{"main":[[{"node":"Prepare Comments Data","type":"main","index":0}]]},"Gmail Account Configuration":{"main":[[{"node":"Update Status on Google Sheet","type":"main","index":0}]]},"Update Status on Google Sheet":{"main":[[]]},"Pick Video Ids from Google sheet":{"main":[[{"node":"If","type":"main","index":0}]]}}}


name: Automated News Summarizer with GPT-4o + Email Delivery
author_name: Amit Mehta
author_username: amitswba
categories: []
created_at: 2025-06-11T01:06:35.204Z
updated_at: 2025-06-11T01:06:35.204Z
url: https://n8n.io/workflows/4864
scraped_at: 2025-07-06 21:16:30
description:
  How it Works

  This workflow fetches top news headlines every 10 minutes from NewsAPI, summarizes them using OpenAI's GPT-4o model, and sends a concise email digest to a list of recipients defined in a Google Spreadsheet. It's ideal for anyone who wants to stay updated with the latest news in a short, digestible format.

  🎯 Use Case

  Professionals who want summarized daily news
  Newsletters or internal communication updates
  Teams that require contextual summaries of the latest events

  Setup Instructions

  1. Upload the Spreadsheet
  File name: Emails
  Column: Email with recipient addresses
  2. Configure Google Sheets Nodes
  Connect your Google account to:
    Email List
    Send Email
  3. Add API Credentials
  NewsAPI Key** → for fetching top headlines
  OpenAI API Key** → for summarizing headlines
  Gmail Account** → for sending the email digest
  4. Activate the Workflow
  Once active, the workflow runs every 10 minutes via a cron trigger
  Summarized news is sent to the list of emails in the spreadsheet

  🔁 Workflow Logic

  Trigger: Every 10 minutes via Cron
  Fetch News: HTTP request to NewsAPI for top headlines
  Summarize: Headlines are passed to OpenAI's GPT-4o for 5-bullet summary
  Read Recipients: Google Sheet is used to collect email recipients
  Send Email: Summary is formatted and sent via Gmail

  🧩 Node Descriptions

  | Node Name | Description |
  |-----------|-------------|
  | Cron | Triggers the workflow every 10 minutes. |
  | HTTP Request - NewsAPI | Fetches top news headlines using NewsAPI. |
  | Set | Formats or structures raw news data before processing. |
  | AI Agent | Summarizes the news content using OpenAI into 5 bullet points. |
  | Email List | Reads recipient email addresses from the 'Emails' Google Spreadsheet. |
  | Send Email | Sends the email digest to all recipients using Gmail. |

  🛠️ Customization Tips

  Modify the AI prompt for tone, length, or content type
  Send summaries to Slack, Telegram, or Notion instead of Gmail
  Adjust cron interval for more/less frequent updates
  Change email formatting (HTML vs plain text)

  📎 Required Files

  | File Name | Purpose |
  |-----------|---------|
  | Emails spreadsheet | Google Sheet containing the list of email recipients |
  | daily_news.json | Main n8n workflow file to automate daily news digest |

  🧪 Testing Tips

  Add 1–2 test email addresses in your spreadsheet
  Temporarily change the Cron node to run every minute for testing
  Check email inbox for delivery and formatting
  Inspect the execution logs for API errors or formatting issues

  🏷 Suggested Tags & Categories

  #News #OpenAI #Automation #Email #Digest #Marketing

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

workflow_json:
  {"id":"0amwQfcJAlNBQvX6","meta":{"instanceId":"ISNTANCE_ID","templateCredsSetupCompleted":true},"name":"Daily News","tags":[],"nodes":[{"id":"1145643c-2b2c-44e9-bcf4-30e412f9416e","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[-960,-340],"parameters":{"rule":{"interval":[{"field":"minutes","minutesInterval":10}]}},"typeVersion":1.2},{"id":"44038509-248a-47d4-9c49-5c0f29ffda22","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[-400,-340],"parameters":{"text":"=You are act as news expert and collect all news headlines  in below and summarise in 5 bullets.\n\n\n {{ $json.articles[1].title }}","options":{},"promptType":"define"},"typeVersion":1.9},{"id":"e97aeaae-a829-40d5-a344-6ae7141095ec","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-400,-160],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"w5WriC1L8qFxdflM","name":"OpenAi account"}},"typeVersion":1.2},{"id":"7b285d38-5089-4eed-bd81-8ef4667f3c28","name":"Pull News","type":"n8n-nodes-base.httpRequest","position":[-680,-340],"parameters":{"url":"https://newsapi.org/v2/top-headlines","options":{},"sendQuery":true,"queryParameters":{"parameters":[{"name":"country","value":"us"},{"name":"apiKey","value":"NEWS_API_KEY"}]}},"typeVersion":4.2},{"id":"4c6e30ad-4030-48e7-b735-1d8e228a1c03","name":"Send Mail","type":"n8n-nodes-base.gmail","position":[180,-340],"webhookId":"e5c02fba-64bc-47f0-b752-2de2b8e6b03c","parameters":{"sendTo":"={{ $json.Email }}","message":"=Hi {{ $json.Name }},\nPlease find the top news headlines as below:\n\n{{ $('AI Agent').item.json.output }}","options":{},"subject":"News Headlines","emailType":"text"},"credentials":{"gmailOAuth2":{"id":"OgS5yqJfZOSZiv1I","name":"Gmail account"}},"typeVersion":2.1},{"id":"c05f27cc-fd08-457a-b964-3bbd3e7193a2","name":"Email list","type":"n8n-nodes-base.googleSheets","position":[-40,-340],"parameters":{"options":{},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1L2dLObdw_aicD6fTd-ElHSBBJIj1aBmKT7FecMtbyyE","cachedResultUrl":"https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID/edit?usp=drivesdk","cachedResultName":"Emails"}},"credentials":{"googleSheetsOAuth2Api":{"id":"OdwrcEa5aEuPpUNR","name":"Google Sheets account"}},"typeVersion":4.5}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"b5ab7305-3729-4b0a-a432-1e187a93e1bb","connections":{"AI Agent":{"main":[[{"node":"Email list","type":"main","index":0}]]},"Pull News":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"Email list":{"main":[[{"node":"Send Mail","type":"main","index":0}]]},"Schedule Trigger":{"main":[[{"node":"Pull News","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]}}}


name: AI-Powered Stock Market Summary Bot
author_name: kenandrewmiranda
author_username: kenandrewmiranda
categories: []
created_at: 2025-06-11T04:29:53.154Z
updated_at: 2025-06-11T04:29:53.154Z
url: https://n8n.io/workflows/4867
scraped_at: 2025-07-06 21:16:30
description:
  An automated n8n workflow that analyzes stocks using RSI and MACD, summarizes insights with OpenAI, and sends a Slack-ready market update every hour.

  This workflow:
  Runs hourly from 6:30 AM to 2:30 PM PT, Mon–Fri
  Checks if the U.S. stock market is open using Alpaca’s /clock API
  Pulls daily stock bars for a list of tickers via Alpaca’s /v2/stocks/bars
  Calculates RSI and MACD using a Python code node
  Categorizes each stock as Buy / Hold / Sell
  Uses OpenAI Assistant to summarize the results in Slack markdown
  Sends the message to a specific Slack user or channel

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

workflow_json:
  {"id":"e5XxiuYXr5atCH64","meta":{"instanceId":"564ad264d05dc77e4e5afc0ced9da90c41c9a77ab9c35729bf6f29309796798d","templateCredsSetupCompleted":true},"name":"Stock Analysis Assistant","tags":[{"id":"TkUb5sI0Ae0hwCo3","name":"Agent","createdAt":"2025-04-07T21:00:21.151Z","updatedAt":"2025-04-07T21:00:21.151Z"},{"id":"xhCApXrnlelxaW2i","name":"Stock","createdAt":"2025-06-09T04:02:42.364Z","updatedAt":"2025-06-09T04:02:42.364Z"},{"id":"eZArPFfgyfBReNUS","name":"AlpacaAPI","createdAt":"2025-06-09T04:02:47.415Z","updatedAt":"2025-06-09T04:02:47.415Z"}],"nodes":[{"id":"f9e2b1a6-4bc4-429c-a516-78fc440cb259","name":"Ticker List","type":"n8n-nodes-base.set","position":[800,0],"parameters":{"mode":"raw","options":{},"jsonOutput":"{\n  \"symbols\": \"AAPL,MSFT,NVDA,TSLA,AMZN,GOOGL,META,JPM,XOM,UNH,GME\"\n}\n"},"typeVersion":3.4},{"id":"46c712d0-8e65-4da0-bdbc-9eadf4213f2f","name":"Fetch Stock Data","type":"n8n-nodes-base.httpRequest","position":[1020,0],"parameters":{"url":"=https://data.alpaca.markets/v2/stocks/bars","options":{},"sendQuery":true,"authentication":"genericCredentialType","genericAuthType":"httpCustomAuth","queryParameters":{"parameters":[{"name":"symbols","value":"={{ $json.symbols }}"},{"name":"timeframe","value":"1Day"},{"name":"limit","value":"1000"},{"name":"feed","value":"iex"},{"name":"=start","value":"={{ new Date(Date.now() - 100 * 24 * 60 * 60 * 1000).toISOString().split('T')[0] }}"},{"name":"end","value":"={{ new Date().toISOString().split('T')[0] }}"}]}},"credentials":{"httpCustomAuth":{"id":"REDACTED_ID","name":"REDACTED_NAME"}},"typeVersion":4.2},{"id":"e8d96c0c-e927-4676-a02f-7729c0126165","name":"Interpret Data","type":"n8n-nodes-base.code","position":[1240,0],"parameters":{"language":"python","pythonCode":"import pandas as pd\nimport numpy as np\nimport json\n\nbars_by_symbol = items[0]['json']['bars']\nstocks = []\n\nfor symbol, bars in bars_by_symbol.items():\n    closes = [bar['c'] for bar in bars if 'c' in bar]\n    if len(closes) < 30:\n        continue\n\n    df = pd.DataFrame({'close': closes})\n\n    # RSI(14)\n    delta = df['close'].diff()\n    gain = delta.clip(lower=0)\n    loss = -delta.clip(upper=0)\n    avg_gain = gain.rolling(14).mean()\n    avg_loss = loss.rolling(14).mean()\n    rs = avg_gain / avg_loss\n    df['rsi'] = 100 - (100 / (1 + rs))\n\n    # MACD (12,26,9)\n    ema12 = df['close'].ewm(span=12, adjust=False).mean()\n    ema26 = df['close'].ewm(span=26, adjust=False).mean()\n    df['macd'] = ema12 - ema26\n    df['signal'] = df['macd'].ewm(span=9, adjust=False).mean()\n\n    latest = df.iloc[-1]\n    rsi = latest['rsi']\n    macd = latest['macd']\n    signal = latest['signal']\n\n    status = \"Hold\"\n    if rsi < 30 and macd > signal:\n        status = \"Buy\"\n    elif rsi > 70 and macd < signal:\n        status = \"Sell\"\n\n    stocks.append({\n        \"ticker\": symbol,\n        \"rsi\": round(float(rsi), 2),\n        \"macd\": round(float(macd), 2),\n        \"signal\": round(float(signal), 2),\n        \"status\": status\n    })\n\nreturn [{\n    \"json\": {\n        \"summary\": json.dumps({\n            \"stocks\": stocks\n        }, separators=(',', ':')),\n      \"stocks\": stocks\n    }\n}]\n"},"typeVersion":2},{"id":"5ace21ee-80b0-4d79-be68-ded17b53b5a2","name":"Stock Analysis Assistant","type":"@n8n/n8n-nodes-langchain.openAi","position":[1440,0],"parameters":{"text":"=Here is the technical indicator data as JSON:\n\n{{ $json.summary }}\n\nPulled as of {{ $now }}","prompt":"define","options":{},"resource":"assistant","assistantId":{"mode":"list","value":"REDACTED_ASSISTANT_ID","cachedResultName":"REDACTED_ASSISTANT"}},"credentials":{"openAiApi":{"id":"REDACTED_ID","name":"REDACTED_NAME"}},"typeVersion":1.8},{"id":"97f8d2af-02a9-4f93-8bf7-ee083b13dccf","name":"Send Summary to User(s)","type":"n8n-nodes-base.slack","position":[1816,0],"webhookId":"57e1eff1-81c1-42f1-b8ee-fb3e40551362","parameters":{"text":"={{ $json.output }}","user":{"mode":"list","value":"REDACTED_USER_ID","cachedResultName":"REDACTED_USER"},"select":"user","otherOptions":{}},"credentials":{"slackApi":{"id":"REDACTED_ID","name":"REDACTED_NAME"}},"typeVersion":2.3},{"id":"21b091f5-ce81-4d98-8978-f7193734a72c","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[120,0],"parameters":{"rule":{"interval":[{"field":"cronExpression","expression":"0 30 6-14 * * 1-5"}]}},"typeVersion":1.2},{"id":"94804d45-b868-4501-a53c-0a1063768f14","name":"Check if Market is open","type":"n8n-nodes-base.if","position":[560,0],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"acca2d72-d9db-436d-aee8-81a3a359fe85","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ $json.is_open }}","rightValue":""}]}},"typeVersion":2.2},{"id":"8366acca-42ff-4106-8b37-316727ac8963","name":"Market is Closed","type":"n8n-nodes-base.noOp","position":[800,200],"parameters":{},"typeVersion":1},{"id":"ee50cf08-efe2-4886-8527-23c069495afd","name":"Check Market Status","type":"n8n-nodes-base.httpRequest","position":[360,0],"parameters":{"url":"https://paper-api.alpaca.markets/v2/clock","options":{},"authentication":"genericCredentialType","genericAuthType":"httpCustomAuth"},"credentials":{"httpCustomAuth":{"id":"REDACTED_ID","name":"REDACTED_NAME"}},"typeVersion":4.2},{"id":"97de7640-5be5-4821-9cea-a8d481590256","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-640,-360],"parameters":{"width":660,"content":"# 🧠 Stock Analysis Assistant\n\nThis workflow analyzes selected S&P 500 stocks using RSI and MACD indicators, summarizes the insights into plain English, and posts an update to Slack every hour during U.S. market hours (Mon–Fri)."},"typeVersion":1},{"id":"4c40864c-ad6d-420f-88b8-a497d7c71a5d","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[40,-360],"parameters":{"color":7,"height":700,"content":"## 📅 Schedule Trigger\n\n**Node:** `Schedule Trigger`  \nRuns every hour between 6:30 AM and 2:30 PM (PST), Monday to Friday.  \n**Cron Expression:** `0 30 6-14 * * 1-5`\n\n⏰ Triggers analysis only during U.S. stock market hours."},"typeVersion":1},{"id":"28ee034a-cb6a-4a54-8ce1-fef5e439e2de","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[280,-360],"parameters":{"color":7,"width":460,"height":700,"content":"## 🏛️ Market Status Check\n\n**Node:** `Check Market Status`  \nEndpoint: `https://paper-api.alpaca.markets/v2/clock`\n\nChecks if the market is open using Alpaca’s `/clock` endpoint.\n\n**Node:** `Check if Market is open`  \n- ✅ If true → continue  \n- ❌ If false → exit gracefully via the “Market is Closed” NoOp node"},"typeVersion":1},{"id":"ab88e6c4-bafb-47d6-9292-b54850f1d984","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[740,-360],"parameters":{"color":4,"width":220,"height":540,"content":"## 📈 Ticker Setup\n\n**Node:** `Ticker List`  \nSets the stock symbols to be analyzed.\n\n📌 You can update this list to monitor different stocks."},"typeVersion":1},{"id":"01892c69-4c22-4c78-a1db-1add2d06993c","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[960,-360],"parameters":{"color":4,"width":220,"height":540,"content":"## 🔗 Fetch Stock Data\n\n**Node:** `Fetch Stock Data`  \nCalls Alpaca’s `/v2/stocks/bars` endpoint with:\n- `symbols`: from `Ticker List`\n- `timeframe`: `1Day`\n- `limit`: `1000`\n- `feed`: `iex` (avoid SIP permission error)\n- `start`: 100 days ago\n- `end`: today"},"typeVersion":1},{"id":"a1b98ff6-b033-4f0c-90c6-b6bf2ea0e461","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[1180,-360],"parameters":{"color":4,"width":220,"height":540,"content":"## 🧮 Interpret Data\n\n**Node:** `Interpret Data`  \nPython code calculates:\n- RSI(14)\n- MACD(12,26,9)\n- Decision status: `\"Buy\"`, `\"Hold\"`, or `\"Sell\"`\n\nOutputs:\n- `stocks`: a list of indicator values and status\n- `summary`: JSON string version for GPT"},"typeVersion":1},{"id":"0ac7e6ad-405e-46b6-81b9-3367c7793136","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[1400,-360],"parameters":{"color":4,"width":360,"height":540,"content":"## 🤖 AI Assistant Summary\n\n**Node:** `Stock Analysis Assistant`  \nUses a custom OpenAI assistant to:\n- Group stocks into categories\n- Provide commentary in plain English\n- Teach users simple market behaviors\n\nPrompt includes:\n- Stock JSON (`summary`)\n- Timestamp (`$now`)\n\n📌 Uses Slack-friendly markdown output."},"typeVersion":1},{"id":"10b73555-9619-4327-beac-d36a5a88f844","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[740,180],"parameters":{"color":3,"width":220,"content":""},"typeVersion":1},{"id":"91c98665-4226-4579-a9df-2dd4ad137638","name":"End of Flow","type":"n8n-nodes-base.noOp","position":[2040,0],"parameters":{},"typeVersion":1},{"id":"f11bdac9-2fbe-4ea5-a470-d89d26aa01ba","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[1760,-360],"parameters":{"color":4,"width":220,"height":540,"content":"## 💬 Post to Slack\n\n**Node:** `Send Summary to User(s)`  \nSends the GPT-generated summary to Slack using:\n```js\n{{ $json.output }}\n```\n⚙️ Configured with the appropriate Slack user or channel."},"typeVersion":1},{"id":"8221dafd-302c-4bbe-9cea-25bdbe980acb","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[1980,-360],"parameters":{"color":4,"width":220,"height":540,"content":""},"typeVersion":1},{"id":"d492d1bc-99ba-43da-bf15-1cbe11badb13","name":"Sticky Note10","type":"n8n-nodes-base.stickyNote","position":[-640,-180],"parameters":{"color":5,"width":660,"height":940,"content":"## 🤖 AI Assistant Prompt\n\nYou are a financial assistant writing a quick, readable market update for a general audience. Your job is to help people understand how well-known stocks are behaving — even if they aren’t professional traders.\n\nYou’ll be given:\n\nA list of stocks with technical indicators (e.g., momentum data)\nA timestamp (in RFC 3339 or ISO format) for when the data was pulled.\n📌 Your task:\nGroup the stocks into three categories:\n🟢 Buy Watchlist – Stocks showing signs of recovery or upward momentum\n⚪ Neutral Hold – Stocks with steady or unclear direction\n🔴 Caution / Sell – Stocks that appear overbought or may pull back\nFor each stock:\nWrite a short, plain-language insight about what’s happening\nUse familiar terms like “gaining steam,” “cooling off,” or “showing hesitation”\nAvoid technical jargon like RSI or MACD unless context makes it helpful\nAdd a helpful tip or comment for each stock (e.g.,\n“This pattern often signals hesitation” or\n“This dip might attract bargain hunters”)\nFinish with a summary line using the timestamp like this:\nSummary as of October 2, 2025 – Most stocks were stable with one or two worth watching.\n📦 Respond in Slack Markdown Only:\nExample Format:\n\n*📊 Market Summary (as of October 2, 2025)*\n\n🟢 *Buy Watchlist*  \n• TSLA – Recovering after a dip; gaining steam. This type of rebound often attracts early buyers.\n\n⚪ *Neutral Hold*  \n• AAPL – Holding steady. This often means the market is waiting on new developments.  \n• GOOGL – Moving sideways. A sign of consolidation before potential breakout.  \n• MSFT – Little movement. Could be digesting prior gains.  \n• NVDA – Slight back-and-forth. May indicate indecision in the market.\n\n🔴 *Caution / Sell*  \n• None at this time.\n\n_Summary as of October 2, 2025: Most stocks appear steady. TSLA could be one to watch if momentum holds._\n🚫 Do NOT:\nReturn raw JSON\nUse code blocks unless formatting Slack markdown (no YAML or tags)\nUse technical finance language unless simplified"},"typeVersion":1}],"active":true,"settings":{"timezone":"America/Los_Angeles","callerPolicy":"workflowsFromSameOwner","executionOrder":"v1"},"versionId":"0523c0a7-8874-4eff-bcd7-cf3d9ab7c362","connections":{"Ticker List":{"main":[[{"node":"Fetch Stock Data","type":"main","index":0}]]},"Interpret Data":{"main":[[{"node":"Stock Analysis Assistant","type":"main","index":0}]]},"Fetch Stock Data":{"main":[[{"node":"Interpret Data","type":"main","index":0}]]},"Schedule Trigger":{"main":[[{"node":"Check Market Status","type":"main","index":0}]]},"Check Market Status":{"main":[[{"node":"Check if Market is open","type":"main","index":0}]]},"Check if Market is open":{"main":[[{"node":"Ticker List","type":"main","index":0}],[{"node":"Market is Closed","type":"main","index":0}]]},"Send Summary to User(s)":{"main":[[{"node":"End of Flow","type":"main","index":0}]]},"Stock Analysis Assistant":{"main":[[{"node":"Send Summary to User(s)","type":"main","index":0}]]}}}


name: Extract Invoice Data from Google Drive to Sheets with Mistral OCR and Gemini
author_name: Ysqander
author_username: ysqander
categories: []
created_at: 2025-06-11T06:15:58.579Z
updated_at: 2025-06-11T06:15:58.579Z
url: https://n8n.io/workflows/4868
scraped_at: 2025-07-06 21:16:30
description:
  Extract data from any PDF or image invoice dropped in Google Drive directly into Google Sheets – powered by AI OCR. Free, fully modifiable n8n workflow. Optional add-ons for pro features.

  🚀 What this template does

  Stop typing invoice data by hand. Drop a PDF or phone-snapshot into your Invoices Inbox folder in Google Drive and this n8n workflow will:





  Auto-OCR the document with the Mistral OCR API



  Match any fields you list in Row 1 of your Google Sheet (totally schema-agnostic)



  Append a clean, structured row – every time

  Works with both PDFs and images, in any language supported by Mistral.

  Template JSON included, ready to import into self-hosted or n8n Cloud

  👀 Who’s this for?





  Freelancers & agencies processing client invoices



  Small finance teams on Google Workspace



  Anyone self-hosting n8n who wants an AI OCR flow without glue-code

  No coding skills required – but flow tweaking is possible for power users.

  🛠 Upcoming PRO Add-Ons
  I am also working on PRO add-ons for this template: 

  Add-On #1 – Error Handling & Alerts (ships Jul 2025)• Flags missing fields, branches to Email/Slack notification; prevents silent failures



  Add-On #2 – Auto-Currency Converter (ships Jul 2025)• Detects invoice currency symbol/code → converts Total into your base currency via a free FX API



  Add-On #3 – VAT / GST Breakdown (ships Jul 2025)• Extracts VAT number, net, tax rate, tax amount, gross – ready for EU/UK/AU filings

  To pre-order these please see: https://ysqander.gumroad.com/l/N8N-AI-Workflow-Invoice-Data-Extraction-LITE

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

workflow_json:
  {"id":"x4DcB7sVAeVmIrMD","meta":{"instanceId":"910d3d65eae3484a05204e7f2f6d897587e3de5b30ca7b532a3b4f6f96a2c11c","templateCredsSetupCompleted":true},"name":"Invoice-Parser-Lite","tags":[],"nodes":[{"id":"a8716edb-e05a-43a5-a38f-384fa05e93cf","name":"When clicking ‘Test workflow’","type":"n8n-nodes-base.manualTrigger","position":[320,-80],"parameters":{},"typeVersion":1},{"id":"bce283e2-29fd-47a1-9cfe-c4cf50f4e35d","name":"On new file in Google Drive","type":"n8n-nodes-base.googleDriveTrigger","position":[320,260],"parameters":{"event":"fileCreated","options":{"fileType":"all"},"pollTimes":{"item":[{}]},"triggerOn":"specificFolder","folderToWatch":{"__rl":true,"mode":"list","value":"15Xpvr0Q4cBwYv1e_jNI8JO4LKAQmgYC2","cachedResultUrl":"https://drive.google.com/drive/folders/15Xpvr0Q4cBwYv1e_jNI8JO4LKAQmgYC2","cachedResultName":"Invoices_Inbox"}},"credentials":{"googleDriveOAuth2Api":{"id":"2wyYFvVBTOBlFJRv","name":"Google Drive account"}},"typeVersion":1},{"id":"160e8e02-8f70-4c8f-a3c4-a94cf2325b82","name":"Load files from Google Drive folder","type":"n8n-nodes-base.googleDrive","position":[880,260],"parameters":{"filter":{"folderId":{"__rl":true,"mode":"list","value":"15Xpvr0Q4cBwYv1e_jNI8JO4LKAQmgYC2","cachedResultUrl":"https://drive.google.com/drive/folders/15Xpvr0Q4cBwYv1e_jNI8JO4LKAQmgYC2","cachedResultName":"Invoices_Inbox"}},"options":{},"resource":"fileFolder","returnAll":true},"credentials":{"googleDriveOAuth2Api":{"id":"2wyYFvVBTOBlFJRv","name":"Google Drive account"}},"executeOnce":true,"typeVersion":3},{"id":"ad1c63fb-4aae-48a2-8329-20afd04e069d","name":"Filter processed files","type":"n8n-nodes-base.merge","position":[1360,140],"parameters":{"mode":"combine","options":{},"joinMode":"keepNonMatches","outputDataFrom":"input2","fieldsToMatchString":"id"},"typeVersion":3},{"id":"1e689ab2-32d1-453f-b30b-61eb8ac5e1db","name":"Download file for OCR","type":"n8n-nodes-base.googleDrive","position":[1560,140],"parameters":{"fileId":{"__rl":true,"mode":"id","value":"={{ $json.id }}"},"options":{},"operation":"download"},"credentials":{"googleDriveOAuth2Api":{"id":"2wyYFvVBTOBlFJRv","name":"Google Drive account"}},"typeVersion":3},{"id":"37e21a39-2383-4934-9b41-81b76c484974","name":"Get already processed rows from Sheets","type":"n8n-nodes-base.googleSheets","position":[1160,-80],"parameters":{"options":{},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1WNXkB6SpJyGtPVcHmj1oaaDFikyACCuq6RY5rEPH4OQ/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1WNXkB6SpJyGtPVcHmj1oaaDFikyACCuq6RY5rEPH4OQ","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1WNXkB6SpJyGtPVcHmj1oaaDFikyACCuq6RY5rEPH4OQ/edit?usp=drivesdk","cachedResultName":"n8n_ocr_invoices"}},"credentials":{"googleSheetsOAuth2Api":{"id":"OZHtTUbddU4IboX9","name":"Google Sheets account"}},"executeOnce":true,"typeVersion":4.3,"alwaysOutputData":true},{"id":"140113e8-31da-45f2-901a-cb83bd183478","name":"Save data to Google Sheets","type":"n8n-nodes-base.googleSheets","position":[3640,60],"parameters":{"columns":{"value":{},"schema":[{"id":"Id","type":"string","display":true,"required":false,"displayName":"Id","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Invoice No","type":"string","display":true,"required":false,"displayName":"Invoice No","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Invoice date","type":"string","display":true,"required":false,"displayName":"Invoice date","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Invoice Period","type":"string","display":true,"required":false,"displayName":"Invoice Period","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Gross Amount incl. VAT ","type":"string","display":true,"required":false,"displayName":"Gross Amount incl. VAT ","defaultMatch":false,"canBeUsedToMatch":true},{"id":"IBAN","type":"string","display":true,"required":false,"displayName":"IBAN","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"autoMapInputData","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"append","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1WNXkB6SpJyGtPVcHmj1oaaDFikyACCuq6RY5rEPH4OQ/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1WNXkB6SpJyGtPVcHmj1oaaDFikyACCuq6RY5rEPH4OQ","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1WNXkB6SpJyGtPVcHmj1oaaDFikyACCuq6RY5rEPH4OQ/edit?usp=drivesdk","cachedResultName":"n8n_ocr_invoices"}},"credentials":{"googleSheetsOAuth2Api":{"id":"OZHtTUbddU4IboX9","name":"Google Sheets account"}},"typeVersion":4.6},{"id":"fa83c3b3-b58d-40c8-b94e-93925347b2de","name":"Mistral Upload","type":"n8n-nodes-base.httpRequest","position":[2060,120],"parameters":{"url":"https://api.mistral.ai/v1/files","method":"POST","options":{},"sendBody":true,"contentType":"multipart-form-data","authentication":"predefinedCredentialType","bodyParameters":{"parameters":[{"name":"purpose","value":"ocr"},{"name":"file","parameterType":"formBinaryData","inputDataFieldName":"data"}]},"nodeCredentialType":"mistralCloudApi"},"credentials":{"mistralCloudApi":{"id":"1SLwPjP2Z9Gh0p3B","name":"Mistral Cloud account"}},"typeVersion":4.2},{"id":"f0aef4a8-ca9a-48a1-b94e-4879adf679c1","name":"Mistral Signed URL","type":"n8n-nodes-base.httpRequest","position":[2260,120],"parameters":{"url":"=https://api.mistral.ai/v1/files/{{ $json.id }}/url","options":{},"sendQuery":true,"sendHeaders":true,"authentication":"predefinedCredentialType","queryParameters":{"parameters":[{"name":"expiry","value":"24"}]},"headerParameters":{"parameters":[{"name":"Accept","value":"application/json"}]},"nodeCredentialType":"mistralCloudApi"},"credentials":{"mistralCloudApi":{"id":"1SLwPjP2Z9Gh0p3B","name":"Mistral Cloud account"}},"typeVersion":4.2},{"id":"165556d9-c325-4eb9-b1b2-4983f3fda5a4","name":"Mistral DOC OCR","type":"n8n-nodes-base.httpRequest","position":[2460,100],"parameters":{"url":"https://api.mistral.ai/v1/ocr","method":"POST","options":{},"jsonBody":"={\n  \"model\": \"mistral-ocr-latest\",\n  \"document\": {\n    \"type\": \"document_url\",\n    \"document_url\": \"{{ $json.url }}\"\n  },\n  \"include_image_base64\": true\n}","sendBody":true,"specifyBody":"json","authentication":"predefinedCredentialType","nodeCredentialType":"mistralCloudApi"},"credentials":{"mistralCloudApi":{"id":"1SLwPjP2Z9Gh0p3B","name":"Mistral Cloud account"}},"typeVersion":4.2},{"id":"849bbcd3-122d-4375-b6ae-920e6c5d2b9e","name":"extract schema","type":"n8n-nodes-base.code","position":[920,-80],"parameters":{"jsCode":"// Grab the keys from the first row\nconst schema = Object.keys($input.all()[0].json);\n\n// Return a single item whose JSON is just that schema array\nreturn [\n  { json: { schema } }\n];"},"typeVersion":2},{"id":"ff80d6f4-6758-482c-b5eb-3fa927525948","name":"Join OCR Pages and remove id field","type":"n8n-nodes-base.code","position":[2840,100],"parameters":{"jsCode":"// Node name: Join Pages\n// 1. Grab all incoming documents\nconst docs = $input.all();\n\n// 2. Pull in your schema once and filter it\nlet schema = $('extract schema').first().json.schema;\nconst toRemove = ['Id', 'row_number'];\nschema = schema.filter(f => !toRemove.includes(f));\n\n// 3. Build one output per document\nconst results = docs.map(doc => {\n  // join only that doc’s pages\n  const fullText = doc.json.pages\n    .map(p => p.markdown)\n    .join('\\n\\n');\n\n  return {\n    json: {\n      ocr_text: fullText,\n      schema,\n    },\n  };\n});\n\nreturn results;"},"typeVersion":2},{"id":"24f5b810-03cc-49d7-bc64-7748f6be9686","name":"Add google drive Id back","type":"n8n-nodes-base.code","position":[3380,60],"parameters":{"jsCode":"// 1. Get the array of processed files (with id & name)\nconst processed = $('Filter processed files').all();\n\n// 2. Take each LLM output in turn, parse it, inject the matching ID, and return\nreturn $input.all().map((item, index) => {\n  // parse the JSON string your chat node returned\n  const data = JSON.parse(item.json.output);\n\n  // look up the corresponding Drive file ID by array index\n  data.Id   = processed[index]?.json.id ?? null;\n\n\n  // emit for your Sheets node\n  return { json: data };\n});"},"typeVersion":2},{"id":"407bd6d8-8b90-47bd-84f8-c15f32ea1cf4","name":"Google Gemini Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[3060,280],"parameters":{"options":{},"modelName":"models/gemini-2.5-flash-preview-05-20"},"credentials":{"googlePalmApi":{"id":"F7phLhVf9DkmhJc7","name":"Google Gemini(PaLM) Api account"}},"typeVersion":1},{"id":"c7ceb651-3f48-49f9-a2f8-f933a63311a8","name":"Mistral Upload1","type":"n8n-nodes-base.httpRequest","position":[2080,340],"parameters":{"url":"https://api.mistral.ai/v1/files","method":"POST","options":{},"sendBody":true,"contentType":"multipart-form-data","authentication":"predefinedCredentialType","bodyParameters":{"parameters":[{"name":"purpose","value":"ocr"},{"name":"file","parameterType":"formBinaryData","inputDataFieldName":"data"}]},"nodeCredentialType":"mistralCloudApi"},"credentials":{"mistralCloudApi":{"id":"1SLwPjP2Z9Gh0p3B","name":"Mistral Cloud account"}},"typeVersion":4.2},{"id":"27c0f663-3833-4f67-8f2d-5efcd1a9b8a2","name":"Mistral Signed URL1","type":"n8n-nodes-base.httpRequest","position":[2260,340],"parameters":{"url":"=https://api.mistral.ai/v1/files/{{ $json.id }}/url","options":{},"sendQuery":true,"sendHeaders":true,"authentication":"predefinedCredentialType","queryParameters":{"parameters":[{"name":"expiry","value":"24"}]},"headerParameters":{"parameters":[{"name":"Accept","value":"application/json"}]},"nodeCredentialType":"mistralCloudApi"},"credentials":{"mistralCloudApi":{"id":"1SLwPjP2Z9Gh0p3B","name":"Mistral Cloud account"}},"typeVersion":4.2},{"id":"027a9c9c-4ebd-497a-8e61-a3ee63b99666","name":"Mistral IMAGE OCR","type":"n8n-nodes-base.httpRequest","position":[2460,320],"parameters":{"url":"https://api.mistral.ai/v1/ocr","method":"POST","options":{},"jsonBody":"={\n  \"model\": \"mistral-ocr-latest\",\n  \"document\": {\n    \"type\": \"image_url\",\n    \"image_url\": \"{{ $json.url }}\"\n  }\n}","sendBody":true,"specifyBody":"json","authentication":"predefinedCredentialType","nodeCredentialType":"mistralCloudApi"},"credentials":{"mistralCloudApi":{"id":"1SLwPjP2Z9Gh0p3B","name":"Mistral Cloud account"}},"typeVersion":4.2},{"id":"be5e7900-7ae8-4c56-83d5-d0984767abff","name":"If","type":"n8n-nodes-base.if","position":[1780,140],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"54e4c552-cdf0-4707-8723-65bcf41d8a96","operator":{"type":"string","operation":"startsWith"},"leftValue":"={{$binary.data.mimeType}}","rightValue":"image/"}]}},"typeVersion":2.2},{"id":"f33ce8fa-1412-4889-b586-130119d4bc4b","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[820,460],"parameters":{"color":4,"width":220,"height":80,"content":"### Modify Folder source"},"typeVersion":1},{"id":"fdc0a222-8962-4d4a-a50c-abd347794430","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[3560,260],"parameters":{"width":320,"height":100,"content":"### File Ids\nYou can view the files using Id from the first column. replace the <Id> below\nhttps://drive.google.com/file/d/<Id>/view"},"typeVersion":1},{"id":"f9e36727-f376-4bb3-b32f-bd55eab82e88","name":"Field Extractor","type":"@n8n/n8n-nodes-langchain.agent","position":[3020,60],"parameters":{"text":"=Extract the following fields from the invoice text:\n\n{{ JSON.stringify($json.schema) }}\n\nImportant: Double-check that all line items are extracted without omission.\n\n- You must respond ONLY with valid raw rendered JSON.\n- Do NOT include the word \"json\".\n- Do NOT include the word \"```json\".\n- Do NOT use triple backticks or markdown formatting.\n- Do NOT wrap the response in any key like \"output\".\n- Do NOT write anything starting at output directly start with valid root-level JSON.\n- Only respond with a valid, root-level JSON object.\n\nText to extract data from: {{ $json.ocr_text }}","options":{"systemMessage":"=You are a document parsing assistant designed to extract structured data from invoice PDFs for automated uploading and validation in a financial system."},"promptType":"define"},"typeVersion":1.8},{"id":"73cc08ed-caa1-405b-8b15-11f2a375fcd9","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[260,480],"parameters":{"color":4,"width":220,"height":80,"content":"### Set interval for checking drive folder and pull new files"},"typeVersion":1},{"id":"d7df816d-3aee-4bd8-9f12-76c23d2108dd","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[580,-380],"parameters":{"color":4,"width":300,"height":140,"content":"### Select Sheet\n  \nAdd column headers in the sheet to which you save data on row one to specify which fields you are interested in extracting. "},"typeVersion":1},{"id":"29782ff3-dbdf-4132-90d2-36a9fafa5815","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[1120,-180],"parameters":{"color":4,"width":200,"height":80,"content":"### Select sheet"},"typeVersion":1},{"id":"3d60e92c-2966-4ed3-900a-582cca0f0b8c","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[3600,-40],"parameters":{"color":4,"width":200,"height":80,"content":"### Select sheet to save data (same as at the start)"},"typeVersion":1},{"id":"3cabcbee-b685-4d9a-9f11-9a3328d70fcd","name":"Get Fields Schema","type":"n8n-nodes-base.googleSheets","position":[680,-80],"parameters":{"options":{"returnFirstMatch":false,"dataLocationOnSheet":{"values":{"firstDataRow":1,"rangeDefinition":"specifyRange"}}},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1WNXkB6SpJyGtPVcHmj1oaaDFikyACCuq6RY5rEPH4OQ/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1WNXkB6SpJyGtPVcHmj1oaaDFikyACCuq6RY5rEPH4OQ","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1WNXkB6SpJyGtPVcHmj1oaaDFikyACCuq6RY5rEPH4OQ/edit?usp=drivesdk","cachedResultName":"n8n_ocr_invoices"}},"credentials":{"googleSheetsOAuth2Api":{"id":"OZHtTUbddU4IboX9","name":"Google Sheets account"}},"typeVersion":4.6},{"id":"2beee512-688a-4c4a-a4eb-b4a20956ead2","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[580,-220],"parameters":{"color":3,"width":300,"height":120,"content":">> ### First column header in cell A1 MUST BE \"Id\". Id tracks the google drive Id and ensures the workflow is not processing previously processed files"},"typeVersion":1},{"id":"314e28c9-07c3-45f5-acb2-c2307d935638","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[1540,40],"parameters":{"color":2,"width":160,"height":80,"content":"Uses drive ID - no need to modify"},"typeVersion":1},{"id":"a3e0322c-3224-40fe-9e82-28274a69d77c","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[2040,-20],"parameters":{"color":2,"width":520,"height":80,"content":"Requires Mistral API Key for La Platforme\nhttps://mistral.ai/products/la-plateforme"},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"b1ae3903-befa-458f-b6db-ba33ce2d9cac","connections":{"If":{"main":[[{"node":"Mistral Upload1","type":"main","index":0}],[{"node":"Mistral Upload","type":"main","index":0}]]},"Mistral Upload":{"main":[[{"node":"Mistral Signed URL","type":"main","index":0}]]},"extract schema":{"main":[[{"node":"Get already processed rows from Sheets","type":"main","index":0}]]},"Field Extractor":{"main":[[{"node":"Add google drive Id back","type":"main","index":0}]]},"Mistral DOC OCR":{"main":[[{"node":"Join OCR Pages and remove id field","type":"main","index":0}]]},"Mistral Upload1":{"main":[[{"node":"Mistral Signed URL1","type":"main","index":0}]]},"Get Fields Schema":{"main":[[{"node":"extract schema","type":"main","index":0}]]},"Mistral IMAGE OCR":{"main":[[{"node":"Join OCR Pages and remove id field","type":"main","index":0}]]},"Mistral Signed URL":{"main":[[{"node":"Mistral DOC OCR","type":"main","index":0}]]},"Mistral Signed URL1":{"main":[[{"node":"Mistral IMAGE OCR","type":"main","index":0}]]},"Download file for OCR":{"main":[[{"node":"If","type":"main","index":0}]]},"Filter processed files":{"main":[[{"node":"Download file for OCR","type":"main","index":0}]]},"Add google drive Id back":{"main":[[{"node":"Save data to Google Sheets","type":"main","index":0}]]},"Google Gemini Chat Model":{"ai_languageModel":[[{"node":"Field Extractor","type":"ai_languageModel","index":0}]]},"On new file in Google Drive":{"main":[[{"node":"Load files from Google Drive folder","type":"main","index":0},{"node":"Get Fields Schema","type":"main","index":0}]]},"When clicking ‘Test workflow’":{"main":[[{"node":"Load files from Google Drive folder","type":"main","index":0},{"node":"Get Fields Schema","type":"main","index":0}]]},"Join OCR Pages and remove id field":{"main":[[{"node":"Field Extractor","type":"main","index":0}]]},"Load files from Google Drive folder":{"main":[[{"node":"Filter processed files","type":"main","index":1}]]},"Get already processed rows from Sheets":{"main":[[{"node":"Filter processed files","type":"main","index":0}]]}}}


