From 5129e420cbe3e28c70bf92a99b8ecff4b78506f0 Mon Sep 17 00:00:00 2001 From: enescingoz Date: Thu, 8 May 2025 19:42:30 +0100 Subject: [PATCH] n8n automations part 2 --- ... PDF Parsing with Multimodal Vision AI.txt | 348 +++ CV Screening with OpenAI.txt | 273 +++ Daily Podcast Summary.txt | 665 ++++++ ... meetings summarization with Gemini AI.txt | 245 ++ ...ing AI Grants for Eligibility using AI.txt | 891 ++++++++ ...ialised Ollama model bespoke-minicheck.txt | 478 ++++ ...ct toxic language in Telegram messages.txt | 148 ++ Discord AI-powered bot.txt | 265 +++ ...est using OpenAI Structured Output (1).txt | 224 ++ ...request using OpenAI Structured Output.txt | 224 ++ ETL pipeline for text processing.txt | 258 +++ Easy Image Captioning with Gemini 1.5 Pro.txt | 401 ++++ ...with AI-Powered Summarization & Review.txt | 892 ++++++++ ...ce with n8n Forms, Airtable and AI (1).txt | 1536 +++++++++++++ ...ervice with n8n Forms, Airtable and AI.txt | 1536 +++++++++++++ Email Summary Agent.txt | 311 +++ ...ffering Messages with Twilio and Redis.txt | 457 ++++ ...ith the Qualys Slack Shortcut Bot! (1).txt | 697 ++++++ ...ns with the Qualys Slack Shortcut Bot!.txt | 697 ++++++ ...on your website pages at scale with AI.txt | 1161 ++++++++++ ...ith OpenAI GPT-4o & Notify it in Slack.txt | 266 +++ ...ey with Image Recognition and AI Agent.txt | 960 ++++++++ ...g forms, AI, Google Sheet and Airtable.txt | 1992 +++++++++++++++++ ...ectly from PDF using Claude and Gemini.txt | 283 +++ ...m resume and create PDF with Gotenberg.txt | 1143 ++++++++++ ...yse YouTube comments via AI Agent chat.txt | 1194 ++++++++++ ...er from image uploaded via an n8n form.txt | 182 ++ ...data with self-hosted LLM Mistral NeMo.txt | 292 +++ ...ing history from gmail to google sheet.txt | 1134 ++++++++++ ...mage using Vertex AI (Gemini) into CSV.txt | 500 +++++ ...uto-Populate n8n Expressions in Prompt.txt | 503 +++++ Flux AI Image Generator.txt | 716 ++++++ ...ge Generation (Fal.ai) to Google Drive.txt | 380 ++++ Force AI to use a specific output format.txt | 250 +++ ...ages from Content and Brand Guidelines.txt | 1975 ++++++++++++++++ ...om Top Trends with AI Image Generation.txt | 1434 ++++++++++++ Generate SEO Seed Keywords Using AI.txt | 338 +++ ... queries from schema only - AI-powered.txt | 758 +++++++ ...ext-to-Speech Using Elevenlabs via API.txt | 186 ++ ... and Webhook _ Text to Speech Workflow.txt | 125 ++ ...e Embeddings via Textual Summarisation.txt | 526 +++++ ...irtable data via AI and Obsidian Notes.txt | 202 ++ ...pSeek V3 Chat & R1 Reasoning Quick Start.txt | 349 +++ ... AI Agent + Telegram + LONG TERM Memory 🧠.txt | 710 ++++++ 44 files changed, 28105 insertions(+) create mode 100644 CV Resume PDF Parsing with Multimodal Vision AI.txt create mode 100644 CV Screening with OpenAI.txt create mode 100644 Daily Podcast Summary.txt create mode 100644 Daily meetings summarization with Gemini AI.txt create mode 100644 Deduplicate Scraping AI Grants for Eligibility using AI.txt create mode 100644 Detect hallucinations using specialised Ollama model bespoke-minicheck.txt create mode 100644 Detect toxic language in Telegram messages.txt create mode 100644 Discord AI-powered bot.txt create mode 100644 Dynamically generate a webpage from user request using OpenAI Structured Output (1).txt create mode 100644 Dynamically generate a webpage from user request using OpenAI Structured Output.txt create mode 100644 ETL pipeline for text processing.txt create mode 100644 Easy Image Captioning with Gemini 1.5 Pro.txt create mode 100644 Effortless Email Management with AI-Powered Summarization & Review.txt create mode 100644 Email Subscription Service with n8n Forms, Airtable and AI (1).txt create mode 100644 Email Subscription Service with n8n Forms, Airtable and AI.txt create mode 100644 Email Summary Agent.txt create mode 100644 Enhance Customer Chat by Buffering Messages with Twilio and Redis.txt create mode 100644 Enhance Security Operations with the Qualys Slack Shortcut Bot! (1).txt create mode 100644 Enhance Security Operations with the Qualys Slack Shortcut Bot!.txt create mode 100644 Enrich FAQ sections on your website pages at scale with AI.txt create mode 100644 Enrich Pipedrive_s Organization Data with OpenAI GPT-4o & Notify it in Slack.txt create mode 100644 Enrich Property Inventory Survey with Image Recognition and AI Agent.txt create mode 100644 Extract Information from a Logo Sheet using forms, AI, Google Sheet and Airtable.txt create mode 100644 Extract and process information directly from PDF using Claude and Gemini.txt create mode 100644 Extract data from resume and create PDF with Gotenberg.txt create mode 100644 Extract insights & analyse YouTube comments via AI Agent chat.txt create mode 100644 Extract license plate number from image uploaded via an n8n form.txt create mode 100644 Extract personal data with self-hosted LLM Mistral NeMo.txt create mode 100644 Extract spending history from gmail to google sheet.txt create mode 100644 Extract text from PDF and image using Vertex AI (Gemini) into CSV.txt create mode 100644 Fetch Dynamic Prompts from GitHub and Auto-Populate n8n Expressions in Prompt.txt create mode 100644 Flux AI Image Generator.txt create mode 100644 Flux Dev Image Generation (Fal.ai) to Google Drive.txt create mode 100644 Force AI to use a specific output format.txt create mode 100644 Generate 9_16 Images from Content and Brand Guidelines.txt create mode 100644 Generate Instagram Content from Top Trends with AI Image Generation.txt create mode 100644 Generate SEO Seed Keywords Using AI.txt create mode 100644 Generate SQL queries from schema only - AI-powered.txt create mode 100644 Generate Text-to-Speech Using Elevenlabs via API.txt create mode 100644 Generate audio from text using OpenAI and Webhook _ Text to Speech Workflow.txt create mode 100644 Generating Image Embeddings via Textual Summarisation.txt create mode 100644 Get Airtable data via AI and Obsidian Notes.txt create mode 100644 🐋DeepSeek V3 Chat & R1 Reasoning Quick Start.txt create mode 100644 🐋🤖 DeepSeek AI Agent + Telegram + LONG TERM Memory 🧠.txt diff --git a/CV Resume PDF Parsing with Multimodal Vision AI.txt b/CV Resume PDF Parsing with Multimodal Vision AI.txt new file mode 100644 index 0000000..cac97ce --- /dev/null +++ b/CV Resume PDF Parsing with Multimodal Vision AI.txt @@ -0,0 +1,348 @@ +{ +"meta": { +"instanceId": "408f9fb9940c3cb18ffdef0e0150fe342d6e655c3a9fac21f0f644e8bedabcd9" +}, +"nodes": [ +{ +"id": "38da57b7-2161-415d-8473-783ccdc7b975", +"name": "When clicking ‘Test workflow’", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +-260, +840 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "2cd46d91-105d-4b5e-be43-3343a9da815d", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-780, +540 +], +"parameters": { +"width": 365.05232558139534, +"height": 401.24529475392126, +"content": "## Try me out!\n\n### This workflow converts a Candidate Resume PDF to an image which is then \"read\" by a Vision Language Model (VLM). The VLM assesses if the candidate's CV is a fit for the desired role.\n\nThis approach can be employed to combat \"hidden prompts\" planted in resumes to bypass and/or manipulate automated ATS systems using AI.\n\n\n### Need Help?\nJoin the [Discord](https://discord.com/invite/XPKeKXeB7d) or ask in the [Forum](https://community.n8n.io/)!\n" +}, +"typeVersion": 1 +}, +{ +"id": "40bab53a-fcbc-4acc-8d59-c20b3e1b2697", +"name": "Structured Output Parser", +"type": "@n8n/n8n-nodes-langchain.outputParserStructured", +"position": [ +1200, +980 +], +"parameters": { +"jsonSchemaExample": "{\n\t\"is_qualified\": true,\n\t\"reason\": \"\"\n}" +}, +"typeVersion": 1.2 +}, +{ +"id": "d75fb7ab-cfbc-419d-b803-deb9e99114ba", +"name": "Should Proceed To Stage 2?", +"type": "n8n-nodes-base.if", +"position": [ +1360, +820 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "4dd69ba3-bf07-43b3-86b7-d94b07e9eea6", +"operator": { +"type": "boolean", +"operation": "true", +"singleValue": true +}, +"leftValue": "={{ $json.output.is_qualified }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2 +}, +{ +"id": "a0f56270-67c2-4fab-b521-aa6f06b0b0fd", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-380, +540 +], +"parameters": { +"color": 7, +"width": 543.5706868577606, +"height": 563.6162790697684, +"content": "## 1. Download Candidate Resume\n[Read more about using Google Drive](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.googledrive)\n\nFor this demonstration, we'll pull the candidate's resume PDF from Google Drive but you can just as easily recieve this resume from email or your ATS.\n\nIt should be noted that our PDF is a special test case which has been deliberately injected with an AI bypass; the bypass is a hidden prompt which aims to override AI instructions and auto-qualify the candidate... sneaky!\n\nDownload a copy of this resume here: https://drive.google.com/file/d/1MORAdeev6cMcTJBV2EYALAwll8gCDRav/view?usp=sharing" +}, +"typeVersion": 1 +}, +{ +"id": "d21fe4dd-0879-4e5a-a70d-10f09b25eee2", +"name": "Download Resume", +"type": "n8n-nodes-base.googleDrive", +"position": [ +-80, +840 +], +"parameters": { +"fileId": { +"__rl": true, +"mode": "id", +"value": "1MORAdeev6cMcTJBV2EYALAwll8gCDRav" +}, +"options": {}, +"operation": "download" +}, +"credentials": { +"googleDriveOAuth2Api": { +"id": "yOwz41gMQclOadgu", +"name": "Google Drive account" +} +}, +"typeVersion": 3 +}, +{ +"id": "ea904365-d9d2-4f15-b7c3-7abfeb4c8c50", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +200, +540 +], +"parameters": { +"color": 7, +"width": 605.0267171444024, +"height": 595.3148729042731, +"content": "## 2. Convert PDF to Image(s)\n[Read more about using Stirling PDF](https://github.com/Stirling-Tools/Stirling-PDF)\n\nAI vision models can only accept images (and sometimes videos!) as non-text inputs but not PDFs at time of writing. We'll have to convert our PDF to an image in order to use it.\n\nHere, we'll use a tool called **Stirling PDF** which can provide this functionality and can be accessed via a HTTP API. Feel free to use an alternative solution if available, otherwise follow the instructions on the Stirling PDF website to set up your own instance.\n\nAdditionally, we'll reduce the resolution of our converted image to speed up the processing done by the LLM. I find that about 75% of an A4 (30x40cm) is a good balance." +}, +"typeVersion": 1 +}, +{ +"id": "cd00a47f-1ab9-46bf-8ea1-46ac899095e7", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +840, +540 +], +"parameters": { +"color": 7, +"width": 747.8139534883712, +"height": 603.1395348837208, +"content": "## 3. Parse Resume with Multimodal LLM\n[Read more about using Basic LLM Chain](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.chainllm/)\n\nMultimodal LLMs are LLMs which can accept binary inputs such as images, audio and/or video files. Most newer LLMs are by default multimodal and we'll use Google's Gemini here as an example. By processing each candidate's resume as an image, we avoid scenarios where text extraction fails due to layout issues or by picking up \"hidden\" or malicious prompts planted to subvert AI automated processing.\n\nThis vision model ensures the resume is read and understood as a human would. The hidden bypass is therefore rendered mute since the AI also cannot \"see\" the special prompt embedded in the document." +}, +"typeVersion": 1 +}, +{ +"id": "d60214c6-c67e-4433-9121-4d54f782b19d", +"name": "PDF-to-Image API", +"type": "n8n-nodes-base.httpRequest", +"position": [ +340, +880 +], +"parameters": { +"url": "https://stirlingpdf.io/api/v1/convert/pdf/img", +"method": "POST", +"options": {}, +"sendBody": true, +"contentType": "multipart-form-data", +"bodyParameters": { +"parameters": [ +{ +"name": "fileInput", +"parameterType": "formBinaryData", +"inputDataFieldName": "data" +}, +{ +"name": "imageFormat", +"value": "jpg" +}, +{ +"name": "singleOrMultiple", +"value": "single" +}, +{ +"name": "dpi", +"value": "300" +} +] +} +}, +"typeVersion": 4.2 +}, +{ +"id": "847de537-ad8f-47f5-a1c1-d207c3fc15ef", +"name": "Resize Converted Image", +"type": "n8n-nodes-base.editImage", +"position": [ +530, +880 +], +"parameters": { +"width": 75, +"height": 75, +"options": {}, +"operation": "resize", +"resizeOption": "percent" +}, +"typeVersion": 1 +}, +{ +"id": "5fb6ac7e-b910-4dce-bba7-19b638fd817a", +"name": "Google Gemini Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini", +"position": [ +1000, +980 +], +"parameters": { +"options": {}, +"modelName": "models/gemini-1.5-pro-latest" +}, +"credentials": { +"googlePalmApi": { +"id": "dSxo6ns5wn658r8N", +"name": "Google Gemini(PaLM) Api account" +} +}, +"typeVersion": 1 +}, +{ +"id": "2580b583-544a-47ee-b248-9cca528c9866", +"name": "Candidate Resume Analyser", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +1000, +820 +], +"parameters": { +"text": "=Evaluate the candidate's resume.", +"messages": { +"messageValues": [ +{ +"message": "=Assess the given Candiate Resume for the role of Plumber.\nDetermine if the candidate's skills match the role and if they qualify for an in-person interview." +}, +{ +"type": "HumanMessagePromptTemplate", +"messageType": "imageBinary" +} +] +}, +"promptType": "define", +"hasOutputParser": true +}, +"typeVersion": 1.4 +}, +{ +"id": "694669c2-9cf5-43ec-8846-c0ecbc5a77ee", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +280, +840 +], +"parameters": { +"width": 225.51725256895617, +"height": 418.95152406706313, +"content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n### Data Privacy Warning!\nFor demo purposes, we're using the public online version of Stirling PDF. It is recommended to setup your own private instance of Stirling PDF before using this workflow in production." +}, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"Download Resume": { +"main": [ +[ +{ +"node": "PDF-to-Image API", +"type": "main", +"index": 0 +} +] +] +}, +"PDF-to-Image API": { +"main": [ +[ +{ +"node": "Resize Converted Image", +"type": "main", +"index": 0 +} +] +] +}, +"Resize Converted Image": { +"main": [ +[ +{ +"node": "Candidate Resume Analyser", +"type": "main", +"index": 0 +} +] +] +}, +"Google Gemini Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Candidate Resume Analyser", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Structured Output Parser": { +"ai_outputParser": [ +[ +{ +"node": "Candidate Resume Analyser", +"type": "ai_outputParser", +"index": 0 +} +] +] +}, +"Candidate Resume Analyser": { +"main": [ +[ +{ +"node": "Should Proceed To Stage 2?", +"type": "main", +"index": 0 +} +] +] +}, +"When clicking ‘Test workflow’": { +"main": [ +[ +{ +"node": "Download Resume", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/CV Screening with OpenAI.txt b/CV Screening with OpenAI.txt new file mode 100644 index 0000000..8c3594b --- /dev/null +++ b/CV Screening with OpenAI.txt @@ -0,0 +1,273 @@ +{ +"meta": { +"instanceId": "6a2a7715680b8313f7cb4676321c5baa46680adfb913072f089f2766f42e43bd" +}, +"nodes": [ +{ +"id": "0f3b39af-2802-462c-ac54-a7bccf5b78c5", +"name": "Extract Document PDF", +"type": "n8n-nodes-base.extractFromFile", +"position": [ +520, +400 +], +"parameters": { +"options": {}, +"operation": "pdf" +}, +"typeVersion": 1, +"alwaysOutputData": false +}, +{ +"id": "6f76e3a6-a3be-4f9f-a0db-3f002eafc2ad", +"name": "Download File", +"type": "n8n-nodes-base.httpRequest", +"position": [ +340, +400 +], +"parameters": { +"url": "={{ $json.file_url }}", +"options": {} +}, +"typeVersion": 4.2 +}, +{ +"id": "2c4e0b0f-28c7-48f5-b051-6e909ac878d2", +"name": "When clicking ‘Test workflow’", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +-20, +400 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "a70d972b-ceb4-4f4d-8737-f0be624d6234", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +120, +280 +], +"parameters": { +"width": 187.37066290133808, +"height": 80, +"content": "**Add direct link to CV and Job description**" +}, +"typeVersion": 1 +}, +{ +"id": "9fdff1be-14cf-4167-af2d-7c5e60943831", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-800, +140 +], +"parameters": { +"color": 7, +"width": 280.2462120317618, +"height": 438.5821431288714, +"content": "### Setup\n\n1. **Download File**: Fetch the CV using its direct URL.\n2. **Extract Data**: Use N8N’s PDF or text extraction nodes to retrieve text from the CV.\n3. **Send to OpenAI**:\n - **URL**: POST to OpenAI’s API for analysis.\n - **Parameters**:\n - Include the extracted CV data and job description.\n - Use JSON Schema to structure the response.\n4. **Save Results**:\n - Store the extracted data and OpenAI's analysis in Supabase for further use." +}, +"typeVersion": 1 +}, +{ +"id": "b1ce4a61-270f-480b-a716-6618e6034581", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-800, +-500 +], +"parameters": { +"color": 7, +"width": 636.2128494576581, +"height": 598.6675280064023, +"content": "![5min Logo](https://cflobdhpqwnoisuctsoc.supabase.co/storage/v1/object/public/my_storage/Untitled%20(1500%20x%20300%20px).png)\n## CV Screening with OpenAI\n**Made by [Mark Shcherbakov](https://www.linkedin.com/in/marklowcoding/) from community [5minAI](https://www.skool.com/5minai-2861)**\n\nThis workflow is ideal for recruitment agencies, HR professionals, and hiring managers looking to automate the initial screening of CVs. It is especially useful for organizations handling large volumes of applications and seeking to streamline their recruitment process.\n\nThis workflow automates the resume screening process using OpenAI for analysis and Supabase for structured data storage. It provides a matching score, a summary of candidate suitability, and key insights into why the candidate fits (or doesn’t fit) the job. \n\n1. **Retrieve Resume**: The workflow downloads CVs from a direct link (e.g., Supabase storage or Dropbox).\n2. **Extract Data**: Extracts text data from PDF or DOC files for analysis.\n3. **Analyze with OpenAI**: Sends the extracted data and job description to OpenAI to:\n - Generate a matching score.\n - Summarize candidate strengths and weaknesses.\n - Provide actionable insights into their suitability for the job.\n4. **Store Results in Supabase**: Saves the analysis and raw data in a structured format for further processing or integration into other tools.\n" +}, +"typeVersion": 1 +}, +{ +"id": "747591cd-76b1-417e-ab9d-0a3935d3db03", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-500, +140 +], +"parameters": { +"color": 7, +"width": 330.5152611046425, +"height": 240.6839895136402, +"content": "### ... or watch set up video [8 min]\n[![Youtube Thumbnail](https://cflobdhpqwnoisuctsoc.supabase.co/storage/v1/object/public/my_storage/11.png)](https://youtu.be/TWuI3dOcn0E)\n" +}, +"typeVersion": 1 +}, +{ +"id": "051d8cb0-2557-4e35-9045-c769ec5a34f9", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +660, +280 +], +"parameters": { +"width": 187.37066290133808, +"height": 80, +"content": "**Replace OpenAI connection**" +}, +"typeVersion": 1 +}, +{ +"id": "865f4f69-e13d-49c1-8bb4-9f98facbf75c", +"name": "OpenAI - Analyze CV", +"type": "n8n-nodes-base.httpRequest", +"position": [ +700, +400 +], +"parameters": { +"url": "=https://api.openai.com/v1/chat/completions", +"method": "POST", +"options": {}, +"jsonBody": "={\n \"model\": \"gpt-4o-mini\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"{{ $('Set Variables').item.json.prompt }}\"\n },\n {\n \"role\": \"user\",\n \"content\": {{ JSON.stringify(encodeURIComponent($json.text))}}\n }\n ],\n \"response_format\":{ \"type\": \"json_schema\", \"json_schema\": {{ $('Set Variables').item.json.json_schema }}\n\n }\n }", +"sendBody": true, +"specifyBody": "json", +"authentication": "predefinedCredentialType", +"nodeCredentialType": "openAiApi" +}, +"credentials": { +"openAiApi": { +"id": "SphXAX7rlwRLkiox", +"name": "Test club key" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "68b7fc08-506d-4816-9a8f-db7ab89e4589", +"name": "Set Variables", +"type": "n8n-nodes-base.set", +"position": [ +160, +400 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "83274f6f-c73e-4d5e-946f-c6dfdf7ed1c4", +"name": "file_url", +"type": "string", +"value": "https://cflobdhpqwnoisuctsoc.supabase.co/storage/v1/object/public/my_storage/software_engineer_resume_example.pdf" +}, +{ +"id": "6e44f3e5-a0df-4337-9f7e-7cfa91b3cc37", +"name": "job_description", +"type": "string", +"value": "Melange is a venture-backed startup building a brand new search infrastructure for the patent system. Leveraging recent and ongoing advancements in machine learning and natural language processing, we are building systems to conduct patent search faster and more accurately than any human currently can. We are a small team with a friendly, mostly-remote culture\\n\\nAbout the team\\nMelange is currently made up of 9 people. We are remote but headquartered in Brooklyn, NY. We look for people who are curious and earnest.\\n\\nAbout the role\\nJoin the team at Melange, a startup with a focus on revolutionizing patent search through advanced technology. As a software engineer in this role, you will be responsible for developing conversation graphs, integrating grammar processes, and maintaining a robust codebase. The ideal candidate will have experience shipping products, working with cloud platforms, and have familiarity with containerization tools. Additionally, experience with prompting tools, NLP packages, and cybersecurity is a plus.\\n\\nCandidate location - the US. Strong preference if they're in NYC, Boston or SF but open to anywhere else but needs to be rockstar\\n\\nYou will \\n\\n* Ship high-quality products.\\n* Utilize prompting libraries such as Langchain and Langgraph to develop conversation graphs and evaluation flows.\\n* Collaborate with linguists to integrate our in-house grammar and entity mapping processes into an iterable patent search algorithm piloted by AI patent agents.\\n* Steward the codebase, ensuring that it remains robust as it scales.\\n\\n\\nCandidate requirements\\nMinimum requirements a candidate must meet\\nHad ownership over aspects of product development in both small and large organizations at differing points in your career.\\n\\nHave used Langchain, LangGraph, or other prompting tools in production or for personal projects.\\n\\nFamiliarity with NLP packages such as Spacy, Stanza, PyTorch, and/or Tensorflow.\\n\\nShipped a working product to users, either as part of a team or on your own. \\nThis means you have: \\nproficiency with one of AWS, Azure, or Google Cloud, \\nfamiliarity with containerization and orchestration tools like Docker and Kubernetes, and \\nbuilt and maintained CI/CD pipelines.\\n5+ years of experience as a software engineer\\n\\nNice-to-haves\\nWhat could make your candidate stand out\\nExperience with cybersecurity.\\n\\nIdeal companies\\nSuccessful b2b growth stage startups that have a strong emphasis on product and design. Orgs with competent management where talent is dense and protected.\\n\\nRamp, Rippling, Brex, Carta, Toast, Asana, Airtable, Benchling, Figma, Gusto, Stripe, Plaid, Monday.com, Smartsheet, Bill.com, Freshworks, Intercom, Sprout Social, Sisense, InsightSquared, DocuSign, Dropbox, Slack, Trello, Qualtrics, Datadog, HubSpot, Shopify, Zendesk, SurveyMonkey, Squarespace, Mixpanel, Github, Atlassian, Zapier, PagerDuty, Box, Snowflake, Greenhouse, Lever, Pendo, Lucidchart, Asana, New Relic, Kajabi, Veeva Systems, Adyen, Twilio, Workday, ServiceNow, Confluent.\\n" +}, +{ +"id": "c597c502-9a3c-48e6-a5f5-8a2a8be7282c", +"name": "prompt", +"type": "string", +"value": "You are the recruiter in recruiting agency, you are strict and you pay extra attention on details in a resume. You work with companies and find talents for their jobs. You asses any resume really attentively and critically. If the candidate is a jumper, you notice that and say us. You need to say if the candidate from out base is suitable for this job. Return 4 things: 1. Percentage (10% step) of matching candidate resume with job. 2. Short summary - should use simple language and be short. Provide final decision on candidate based on matching percentage and candidate skills vs job requirements. 3. Summary why this candidate suits this jobs. 4. Summary why this candidate doesn't suit this jobs." +}, +{ +"id": "1884eed1-9111-4ce1-8d07-ed176611f2d8", +"name": "json_schema", +"type": "string", +"value": "{ \"name\": \"candidate_evaluation\", \"description\": \"Structured data for evaluating a candidate based on experience and fit\", \"strict\": true, \"schema\": { \"type\": \"object\", \"properties\": { \"percentage\": { \"type\": \"integer\", \"description\": \"Overall suitability percentage score for the candidate\" }, \"summary\": { \"type\": \"string\", \"description\": \"A brief summary of the candidate's experience, personality, and any notable strengths or concerns\" }, \"reasons-suit\": { \"type\": \"array\", \"items\": { \"type\": \"object\", \"properties\": { \"name\": { \"type\": \"string\", \"description\": \"Title of the strength or reason for suitability\" }, \"text\": { \"type\": \"string\", \"description\": \"Description of how this experience or skill matches the job requirements\" } }, \"required\": [\"name\", \"text\"], \"additionalProperties\": false }, \"description\": \"List of reasons why the candidate is suitable for the position\" }, \"reasons-notsuit\": { \"type\": \"array\", \"items\": { \"type\": \"object\", \"properties\": { \"name\": { \"type\": \"string\", \"description\": \"Title of the concern or reason for unsuitability\" }, \"text\": { \"type\": \"string\", \"description\": \"Description of how this factor may not align with the job requirements\" } }, \"required\": [\"name\", \"text\"], \"additionalProperties\": false }, \"description\": \"List of reasons why the candidate may not be suitable for the position\" } }, \"required\": [\"percentage\", \"summary\", \"reasons-suit\", \"reasons-notsuit\"], \"additionalProperties\": false } }" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "22dedac7-c44b-430f-b9c7-57d0c55328fa", +"name": "Parsed JSON", +"type": "n8n-nodes-base.set", +"position": [ +880, +400 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "83274f6f-c73e-4d5e-946f-c6dfdf7ed1c4", +"name": "json_parsed", +"type": "object", +"value": "={{ JSON.parse($json.choices[0].message.content) }}" +} +] +} +}, +"typeVersion": 3.4 +} +], +"pinData": {}, +"connections": { +"Download File": { +"main": [ +[ +{ +"node": "Extract Document PDF", +"type": "main", +"index": 0 +} +] +] +}, +"Set Variables": { +"main": [ +[ +{ +"node": "Download File", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI - Analyze CV": { +"main": [ +[ +{ +"node": "Parsed JSON", +"type": "main", +"index": 0 +} +] +] +}, +"Extract Document PDF": { +"main": [ +[ +{ +"node": "OpenAI - Analyze CV", +"type": "main", +"index": 0 +} +] +] +}, +"When clicking ‘Test workflow’": { +"main": [ +[ +{ +"node": "Set Variables", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Daily Podcast Summary.txt b/Daily Podcast Summary.txt new file mode 100644 index 0000000..52a195e --- /dev/null +++ b/Daily Podcast Summary.txt @@ -0,0 +1,665 @@ +{ +"meta": { +"instanceId": "7858a8e25b8fc4dae485c1ef345e6fe74effb1f5060433ef500b4c186c965c18" +}, +"nodes": [ +{ +"id": "49ab7596-665e-4a0f-bb8b-9dc04525ce88", +"name": "Gmail", +"type": "n8n-nodes-base.gmail", +"position": [ +2340, +1440 +], +"parameters": { +"message": "={{ $json.html }}", +"options": {}, +"subject": "Podcast Review" +}, +"credentials": { +"gmailOAuth2": { +"id": "1MUdv1HbrQUFABiZ", +"name": "Gmail account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "40aa23f4-69d6-46e5-84a2-b46a64a3f0af", +"name": "TaddyTopDaily", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1620, +820 +], +"parameters": { +"url": "https://api.taddy.org/", +"method": "POST", +"options": {}, +"sendBody": true, +"sendHeaders": true, +"bodyParameters": { +"parameters": [ +{ +"name": "query", +"value": "=query { getTopChartsByGenres( limitPerPage:10, filterByCountry:UNITED_STATES_OF_AMERICA, taddyType:PODCASTEPISODE, genres:PODCASTSERIES_{{ $json.genre }}){ topChartsId podcastEpisodes{ uuid name audioUrl podcastSeries{ uuid name } } } }" +} +] +}, +"headerParameters": { +"parameters": [ +{ +"name": "X-USER-ID" +}, +{ +"name": "X-API-KEY" +} +] +} +}, +"typeVersion": 4.2 +}, +{ +"id": "42eea23b-b09c-49ee-af5b-12abb3960390", +"name": "Genre", +"type": "n8n-nodes-base.set", +"position": [ +1420, +820 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "e995cd5b-b91c-4a9d-8215-44d7dfe3f52f", +"name": "genre", +"type": "string", +"value": "TECHNOLOGY" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "da256fbf-ed7b-4a26-9fa8-33d1c2b717a5", +"name": "Split Out", +"type": "n8n-nodes-base.splitOut", +"position": [ +1840, +820 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "data.getTopChartsByGenres.podcastEpisodes" +}, +"typeVersion": 1 +}, +{ +"id": "069ab68c-dcd6-406f-8e7f-2597f62a04f5", +"name": "Whisper Transcribe Audio", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1880, +1120 +], +"parameters": { +"url": "https://api.openai.com/v1/audio/transcriptions", +"method": "POST", +"options": {}, +"sendBody": true, +"contentType": "multipart-form-data", +"authentication": "predefinedCredentialType", +"bodyParameters": { +"parameters": [ +{ +"name": "model", +"value": "whisper-1" +}, +{ +"name": "file", +"parameterType": "formBinaryData", +"inputDataFieldName": "data" +} +] +}, +"nodeCredentialType": "openAiApi" +}, +"credentials": { +"openAiApi": { +"id": "tTOOlpAaNT3QoKbQ", +"name": "OpenAi account" +} +}, +"typeVersion": 3 +}, +{ +"id": "ffa67b8d-8601-4e1d-8f72-b6266e6b3327", +"name": "Final Data", +"type": "n8n-nodes-base.set", +"position": [ +2320, +1120 +], +"parameters": { +"mode": "raw", +"options": {}, +"jsonOutput": "={\n\"podcast\": \"{{ $('TaddyTopDaily').item.json.data.getTopChartsByGenres.podcastEpisodes[$itemIndex].podcastSeries.name }}\",\n\"name\": \"{{ $('TaddyTopDaily').item.json.data.getTopChartsByGenres.podcastEpisodes[$itemIndex].name.replace(/\\\"/g,'\\\"') }}\",\n \"url\":\"{{ $('TaddyTopDaily').item.json.data.getTopChartsByGenres.podcastEpisodes[$itemIndex].audioUrl.replace(/\"/g,'') }}\",\n\"summary\":\"{{ $json.message.content.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\n/g, '
').replace(/\\r/g, '\\\\r').replace(/\\t/g, '\\\\t') }}\"\n \n}\n" +}, +"typeVersion": 3.4 +}, +{ +"id": "88cd1fa5-07ae-4dcd-b4f8-85cbf7c98d73", +"name": "Merge Results", +"type": "n8n-nodes-base.code", +"position": [ +1900, +1440 +], +"parameters": { +"jsCode": "return [{fields:$input.all().map(x=>x.json)}]" +}, +"typeVersion": 2 +}, +{ +"id": "4c2c80d1-750f-42f1-a0f1-343dec325b0f", +"name": "HTML", +"type": "n8n-nodes-base.html", +"position": [ +2120, +1440 +], +"parameters": { +"html": "\n\n\n \n\n\n \n \n {{ ['Podcast', 'Episode', 'Summary'].map(propname=>'').join('') }}\n \n {{ $json.fields.map(ep=>{ return ``} ) }}\n

'+propname+'

${ep.podcast}${ep.name}${ep.summary}
\n\n\n\n\n" +}, +"executeOnce": true, +"typeVersion": 1.2 +}, +{ +"id": "f1d13556-2c3a-48e5-84a1-5b82f338c6ba", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +340, +760 +], +"parameters": { +"color": 4, +"width": 547.952991050529, +"height": 683.5200847858991, +"content": "## Daily Podcast Summary\n### This workflow will summarize the content in the day's top podcasts for a certain genre, then send you the podcasts with summaries by email\n\n## Setup:\n 1. Create a free API key on Taddy here: https://taddy.org/signup/developers\n 2. Input your user number and API key into the `TaddyTopDaily` node in the header parameters X-USER-ID and X-API-KEY respectively.\n 3. Create access credentials for your Gmail as described here: https://developers.google.com/workspace/guides/create-credentials. Use the credentials from your *client_secret.json* in the `Gmail` node.\n 4. In the `Genre` node, set the genre of podcasts you want a summary for. Valid values are: TECHNOLOGY, NEWS, ARTS, COMEDY, SPORTS, FICTION, etc. Look at api.taddy.org for the full list (they will be displayed in the help docs as PODCASTSERIES_TECHNOLOGY, PODCASTSERIES_NEWS, etc.)\n 5. Enter your email address in the `Gmail` node.\n 6. Change the schedule time for sending email from `Schedule` to whichever time you want to receive the email.\n \n\n## Test:\n- Link a `Test Workflow` node in place of the `Schedule` node.\n- Hit Test Workflow.\n- Check your email for the results." +}, +"typeVersion": 1 +}, +{ +"id": "5aee7279-349e-47cd-99dc-7a32677b5a20", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1820, +1060 +], +"parameters": { +"width": 651.4454343326669, +"height": 252.64899257060446, +"content": "### Whisper transcribes and Open AI summarizes the podcast" +}, +"typeVersion": 1 +}, +{ +"id": "f8b4a203-b27f-4a11-90ef-a7e1561219f5", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1100, +760 +], +"parameters": { +"width": 1189.7320416038633, +"height": 249.2202456997519, +"content": "### Get daily list of top podcasts (according to Apple charts) and download audio, then crop for OpenAI" +}, +"typeVersion": 1 +}, +{ +"id": "7045c9c8-5509-4dc0-b167-ddd4d6c90c22", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1825, +1384 +], +"parameters": { +"width": 645.0210885124873, +"height": 227.94126205257731, +"content": "### Finally, send the email!" +}, +"typeVersion": 1 +}, +{ +"id": "8dc9583b-cec3-4ac0-a74a-329f6c3b4801", +"name": "Summarize Podcast", +"type": "n8n-nodes-base.openAi", +"position": [ +2140, +1120 +], +"parameters": { +"model": "gpt-4o-mini", +"prompt": { +"messages": [ +{ +"content": "=Summarize the major points of the following podcast: {{ $json.text }}. Start your answer by saying 'This episode focuses on', 'This episode is about', etc. Contain your answer to 3-4 paragraphs max, and focus on only key information. " +} +] +}, +"options": { +"maxTokens": 500 +}, +"resource": "chat", +"requestOptions": {} +}, +"credentials": { +"openAiApi": { +"id": "tTOOlpAaNT3QoKbQ", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "e8d122f1-29f9-41ca-9c6b-b72269686fd6", +"name": "Schedule", +"type": "n8n-nodes-base.scheduleTrigger", +"position": [ +1220, +820 +], +"parameters": { +"rule": { +"interval": [ +{ +"triggerAtHour": 8 +} +] +} +}, +"typeVersion": 1.2 +}, +{ +"id": "67bc7a5b-8d0a-4de4-918d-410551dad4d7", +"name": "Request Audio Crop", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1000, +1220 +], +"parameters": { +"url": "https://api.products.aspose.app/audio/cutter/api/cutter", +"method": "POST", +"options": {}, +"sendBody": true, +"contentType": "multipart-form-data", +"sendHeaders": true, +"bodyParameters": { +"parameters": [ +{ +"name": "1", +"parameterType": "formBinaryData", +"inputDataFieldName": "data" +}, +{ +"name": "convertOption", +"value": "{\"startTime\":\"00:08:00\",\"endTime\":\"00:24:00\",\"audioFormat\":\"mp3\"}" +} +] +}, +"headerParameters": { +"parameters": [ +{ +"name": "Accept", +"value": "*/*(" +}, +{ +"name": "Connection", +"value": "keep-alive" +}, +{ +"name": "Origin", +"value": "https://products.aspose.app" +}, +{ +"name": "Referer", +"value": "https://products.aspose.app" +}, +{ +"name": "Sec-Fetch-Dest", +"value": "empty" +}, +{ +"name": "Sec-Fetch-Mode", +"value": "cors" +}, +{ +"name": "Sec-Fetch-Site", +"value": "same-site" +} +] +} +}, +"typeVersion": 4.2 +}, +{ +"id": "0dc62507-3fea-45d7-a0dc-e92fb8e2600f", +"name": "Get Download Link", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1200, +1220 +], +"parameters": { +"url": "=https://api.products.aspose.app/audio/cutter/api/cutter/HandleStatus?fileRequestId={{ $('Request Audio Crop').item.json.Data.FileRequestId }}", +"options": {}, +"sendHeaders": true, +"headerParameters": { +"parameters": [ +{ +"name": "Accept", +"value": "application/json, text/javascript, */*; q=0.01" +}, +{ +"name": "Connection", +"value": "keep-alive" +}, +{ +"name": "Origin", +"value": "https://products.aspose.app" +}, +{ +"name": "Referer", +"value": "https://products.aspose.app" +}, +{ +"name": "Sec-Fetch-Dest", +"value": "empty" +}, +{ +"name": "Sec-Fetch-Dest", +"value": "cors" +}, +{ +"name": "Sec-Fetch-Dest", +"value": "same-site" +} +] +} +}, +"typeVersion": 4.2 +}, +{ +"id": "8aa65189-2a4b-4ac4-9915-45ccd679a5da", +"name": "Download Cut MP3", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1660, +1140 +], +"parameters": { +"url": "={{ $json.Data.DownloadLink }}", +"options": {} +}, +"typeVersion": 4.2 +}, +{ +"id": "4e7318df-dbaa-4d9f-858d-4455ead763c1", +"name": "Download Podcast", +"type": "n8n-nodes-base.httpRequest", +"position": [ +2060, +820 +], +"parameters": { +"url": "={{ $json.audioUrl }}", +"options": {} +}, +"typeVersion": 4.2 +}, +{ +"id": "ab4601c6-7387-4f2f-a2f3-4256f88c0b3e", +"name": "Wait", +"type": "n8n-nodes-base.wait", +"position": [ +1600, +1360 +], +"webhookId": "bc28bc57-d9ea-430e-88db-78d088a058cb", +"parameters": {}, +"typeVersion": 1.1 +}, +{ +"id": "a0b300b9-aaad-48f1-8319-a03700e0d298", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +920, +1100 +], +"parameters": { +"width": 898.7483569555845, +"height": 387.3779915472271, +"content": "### Crop the podcast down before analysis" +}, +"typeVersion": 1 +}, +{ +"id": "34ca89fe-4ed1-491f-b3b9-32e97040959b", +"name": "If Downloads Ready", +"type": "n8n-nodes-base.if", +"position": [ +1380, +1180 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "loose" +}, +"combinator": "and", +"conditions": [ +{ +"id": "49440938-0cb3-41c8-bcab-b7ad96973f77", +"operator": { +"type": "boolean", +"operation": "true", +"singleValue": true +}, +"leftValue": "={{ $input.all().map(x=>x.json.Data.DownloadLink).reduce((accumulator, currentValue) => accumulator && currentValue, true)\n}}", +"rightValue": "" +} +] +}, +"looseTypeValidation": true +}, +"typeVersion": 2.1 +} +], +"pinData": {}, +"connections": { +"HTML": { +"main": [ +[ +{ +"node": "Gmail", +"type": "main", +"index": 0 +} +] +] +}, +"Wait": { +"main": [ +[ +{ +"node": "Get Download Link", +"type": "main", +"index": 0 +} +] +] +}, +"Genre": { +"main": [ +[ +{ +"node": "TaddyTopDaily", +"type": "main", +"index": 0 +} +] +] +}, +"Schedule": { +"main": [ +[ +{ +"node": "Genre", +"type": "main", +"index": 0 +} +] +] +}, +"Split Out": { +"main": [ +[ +{ +"node": "Download Podcast", +"type": "main", +"index": 0 +} +] +] +}, +"Final Data": { +"main": [ +[ +{ +"node": "Merge Results", +"type": "main", +"index": 0 +} +] +] +}, +"Merge Results": { +"main": [ +[ +{ +"node": "HTML", +"type": "main", +"index": 0 +} +] +] +}, +"TaddyTopDaily": { +"main": [ +[ +{ +"node": "Split Out", +"type": "main", +"index": 0 +} +] +] +}, +"Download Cut MP3": { +"main": [ +[ +{ +"node": "Whisper Transcribe Audio", +"type": "main", +"index": 0 +} +] +] +}, +"Download Podcast": { +"main": [ +[ +{ +"node": "Request Audio Crop", +"type": "main", +"index": 0 +} +] +] +}, +"Get Download Link": { +"main": [ +[ +{ +"node": "If Downloads Ready", +"type": "main", +"index": 0 +} +] +] +}, +"Summarize Podcast": { +"main": [ +[ +{ +"node": "Final Data", +"type": "main", +"index": 0 +} +] +] +}, +"If Downloads Ready": { +"main": [ +[ +{ +"node": "Download Cut MP3", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Wait", +"type": "main", +"index": 0 +} +] +] +}, +"Request Audio Crop": { +"main": [ +[ +{ +"node": "Get Download Link", +"type": "main", +"index": 0 +} +] +] +}, +"Whisper Transcribe Audio": { +"main": [ +[ +{ +"node": "Summarize Podcast", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Daily meetings summarization with Gemini AI.txt b/Daily meetings summarization with Gemini AI.txt new file mode 100644 index 0000000..6f557ea --- /dev/null +++ b/Daily meetings summarization with Gemini AI.txt @@ -0,0 +1,245 @@ +{ +"id": "jAML9xW28lOdsObH", +"meta": { +"instanceId": "be04c66ddabda64dad2c5d4c4611c3879370cfcff746359dfed22dbbfaacfc1a", +"templateCredsSetupCompleted": true +}, +"name": "Daily meetings summarization with Gemini AI", +"tags": [], +"nodes": [ +{ +"id": "2f5c6f8b-023a-4fc0-8684-66d7f743af0a", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +100, +380 +], +"parameters": { +"color": 4, +"width": 217.47708894878716, +"height": 233, +"content": "### Gemini Flash model a base" +}, +"typeVersion": 1 +}, +{ +"id": "8c159251-d78c-4f18-a886-b930194e6459", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +600, +40 +], +"parameters": { +"color": 4, +"width": 223.7196765498655, +"height": 236.66152029520293, +"content": "### Send the response from AI back to slack channel\n" +}, +"typeVersion": 1 +}, +{ +"id": "ee7164d8-f257-4e47-9867-239440153fd4", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +0, +-20 +], +"parameters": { +"color": 4, +"width": 561, +"height": 360, +"content": "## Trigger the task daily, receive the meetings data, process the data and return response for sending\n\n\n\n\n\n\n\n\n\n\n\nNo memory assigned to the model since the model is running one task and doesn't need a followup, then send the data to the user." +}, +"typeVersion": 1 +}, +{ +"id": "30ac78b7-08ba-4df9-a67c-e6825a9de380", +"name": "Send response back to slack channel", +"type": "n8n-nodes-base.slack", +"position": [ +660, +100 +], +"webhookId": "636ae330-cc22-408b-b6a5-caf02e48897f", +"parameters": { +"text": "=Gemini : {{ $json.output.removeMarkdown() }} ", +"select": "channel", +"channelId": { +"__rl": true, +"mode": "list", +"value": "C07QMTJHR0A", +"cachedResultName": "ai-chat-gemini" +}, +"otherOptions": { +"mrkdwn": true, +"includeLinkToWorkflow": false +} +}, +"credentials": { +"slackApi": { +"id": "DFQMzAsWKIdZFCR4", +"name": "Slack account - iKemo" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "938738d6-1e2e-4e93-a5bf-70d11fd4fd32", +"name": "Google Calendar - Get Events", +"type": "n8n-nodes-base.googleCalendarTool", +"position": [ +400, +460 +], +"parameters": { +"options": { +"timeMax": "={{ $fromAI('end_date') }}", +"timeMin": "={{ $fromAI('start_date') }}" +}, +"calendar": { +"__rl": true, +"mode": "list", +"value": "john@iKemo.io", +"cachedResultName": "john@iKemo.io" +}, +"operation": "getAll", +"descriptionType": "manual", +"toolDescription": "Use this tool when you’re asked to retrieve events data." +}, +"credentials": { +"googleCalendarOAuth2Api": { +"id": "R2W7XHvEyQgyykI0", +"name": "Google Calendar - John" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "2290c30e-9e9f-471a-a882-df6856a1dd9d", +"name": "Calendar AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +240, +100 +], +"parameters": { +"text": "=summarize today's meetings.\nstartdate = {{ $now.format('yyyy-MM-dd 00:00:00') }}\nenddate = {{ $now.format('yyyy-MM-dd 23:59:59') }}", +"options": { +"systemMessage": "=You are a Google Calendar assistant.\nYour primary goal is to assist the user in managing their calendar effectively using Event Retrieval tool. \nAlways base your responses on the current date: \n{{ DateTime.local().toFormat('cccc d LLLL yyyy') }}.\nGeneral Guidelines:\nAlways mention all meetings attendees\nTool: Event Retrieval\nFormat the date range:\nstart_date: Start date and time in YYYY-MM-DD HH:mm:ss.\nend_date: End date and time in YYYY-MM-DD HH:mm:ss.\n" +}, +"promptType": "define" +}, +"typeVersion": 1.7 +}, +{ +"id": "dd63bab9-0f95-4b84-8bbd-26a1f91fe635", +"name": "Schedule Trigger", +"type": "n8n-nodes-base.scheduleTrigger", +"position": [ +20, +100 +], +"parameters": { +"rule": { +"interval": [ +{ +"triggerAtHour": 9 +} +] +} +}, +"typeVersion": 1.2 +}, +{ +"id": "06b9ecd2-83e0-498f-ad79-fbc89242a6f0", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +340, +380 +], +"parameters": { +"color": 4, +"width": 221.73584905660368, +"height": 233, +"content": "### Access Google Calendar and fetch all the data" +}, +"typeVersion": 1 +}, +{ +"id": "48679508-2af8-4507-80a9-fc0aad171169", +"name": "Google Gemini Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini", +"position": [ +160, +480 +], +"parameters": { +"options": {}, +"modelName": "models/gemini-1.5-flash-latest" +}, +"credentials": { +"googlePalmApi": { +"id": "3BBJHhMKD8W8VfL4", +"name": "Google Gemini(PaLM) Api account" +} +}, +"typeVersion": 1 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "e517b214-b0e5-4119-8aaf-77ee0655dd78", +"connections": { +"Schedule Trigger": { +"main": [ +[ +{ +"node": "Calendar AI Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Calendar AI Agent": { +"main": [ +[ +{ +"node": "Send response back to slack channel", +"type": "main", +"index": 0 +} +] +] +}, +"Google Gemini Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Calendar AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Google Calendar - Get Events": { +"ai_tool": [ +[ +{ +"node": "Calendar AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Deduplicate Scraping AI Grants for Eligibility using AI.txt b/Deduplicate Scraping AI Grants for Eligibility using AI.txt new file mode 100644 index 0000000..6c98821 --- /dev/null +++ b/Deduplicate Scraping AI Grants for Eligibility using AI.txt @@ -0,0 +1,891 @@ +{ +"nodes": [ +{ +"id": "c17e444e-0a5e-4bfe-8de6-c3185de4465d", +"name": "Grants to List", +"type": "n8n-nodes-base.splitOut", +"position": [ +-240, +-180 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "oppHits" +}, +"typeVersion": 1 +}, +{ +"id": "9251d39c-6098-42fa-aadd-3a22464dee64", +"name": "Get Grant Details", +"type": "n8n-nodes-base.httpRequest", +"position": [ +280, +-280 +], +"parameters": { +"url": "https://apply07.grants.gov/grantsws/rest/opportunity/details", +"method": "POST", +"options": {}, +"sendBody": true, +"contentType": "form-urlencoded", +"bodyParameters": { +"parameters": [ +{ +"name": "oppId", +"value": "={{ $json.id }}" +} +] +} +}, +"typeVersion": 4.2 +}, +{ +"id": "ade994d6-a1f8-45bf-a82e-83eb38da08d6", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +440, +-120 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "4d81b20e-0038-48d3-840c-3fcf8b798a0d", +"name": "Summarize Synopsis", +"type": "@n8n/n8n-nodes-langchain.informationExtractor", +"position": [ +460, +-280 +], +"parameters": { +"text": "=Agency: {{ $json.synopsis.agencyName }}\nTitle: {{ $json.opportunityTitle }}\nSynopsis: {{ $json.synopsis.synopsisDesc }}", +"options": { +"systemPromptTemplate": "You've been given a grant opportunity listing. Help summarize the opportunity in simple terms." +}, +"schemaType": "manual", +"inputSchema": "{\n\t\"type\": \"object\",\n\t\"properties\": {\n \"goal\": { \"type\": [\"string\", \"null\"] },\n \"duration\": { \"type\": \"string\" },\n \"success_criteria\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n },\n \"good_to_know\": {\n\t\t \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n }\n\t}\n}" +}, +"typeVersion": 1 +}, +{ +"id": "71e1a2e9-6690-4247-aae3-f5bd61019553", +"name": "Eligibility Factors", +"type": "@n8n/n8n-nodes-langchain.informationExtractor", +"position": [ +640, +-120 +], +"parameters": { +"text": "=Agency: {{ $json.synopsis.agencyName }}\nTitle: {{ $json.opportunityTitle }}\nSynopsis: {{ $json.synopsis.synopsisDesc }}\nEligibility: {{ $json.synopsis.applicantEligibilityDesc }}", +"options": { +"systemPromptTemplate": "Help determine if we are eligible for this grant.\n\nWe are AI Consultants Limited (“Company”) and are the controllers of your personal data. Our registered office is Unit 29, Intelligent Park, Milton Road, Cambridge Cambridgeshire CB9 RDW, and our registered company number is 1234567.\n\nWe are part of a group of companies which provides consultancy services across the globe. Our other group companies are:\n\nAI Consultants Inc. of 2 Drydock Avenue, Suite 1210, Boston, MA 02210, USA\nAI Consultants (Singapore) Pte Ltd of 300 Beach Road, Singapore 199555\nAI Consultants Japan Inc, of 3-1-3 Minamiaoyama, Minato-ku, Tokyo, 107-0062\nIn the UK we are registered with the Information Commissioner’s Office under registration number Z9888888.\n\nIn the US we are registered with the Data Privacy Framework Program (DPF). To view the Company’s certification, please visit https://www.dataprivacyframework.gov/list.\n\nWe are a leading, worldwide product development service provider. We specialise in design engineering services, professional technical services and product technical support services (“Services”).\n\nAs the deep tech powerhouse of Capgemini, CC spearheads transformative projects to solve the toughest scientific and engineering challenges. Ambitious clients collaborate with us to create new-to-the-world technologies, services and products that have never been seen before. Our unique combination of technical, commercial and market expertise yields market-leading solutions that are hard to copy. This creates valuable intellectual property that generates protectable long-term value.\n\nWe work with some of the world’s biggest brands and most ambitious technology start-up ventures across a wide range of markets. From aerospace to agritech, consumer to industry, communications to healthcare, our knowledge of one sector can often be applied to another to create new breakthroughs. We focus on our clients’ success and we are trusted as integral partners in the future of their businesses.\n\nWe do important, difficult, radical and impactful things that benefit society. We helped develop the world's first 24/7 wrist-worn activity monitor, wireless pacemaker and wireless patient monitor, as well as the first connected drug inhaler. Our work led to the most densely packed cellular network in the world – orchestrating swarms of bots across highly automated warehouses. It produced the Bluetooth chip that connects your phone to your car and the latest satellite technology that lets people in remote locations across the world keep in touch." +}, +"schemaType": "manual", +"inputSchema": "{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"eligibility_matches\": {\n\t\t \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n }\n\t}\n}" +}, +"typeVersion": 1 +}, +{ +"id": "d741ef63-dcf3-452d-978c-8cbc27f55a33", +"name": "OpenAI Chat Model1", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +600, +20 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "7354ed6d-50f5-4234-90d8-2d9d0c7eccd4", +"name": "Merge", +"type": "n8n-nodes-base.merge", +"position": [ +1000, +-120 +], +"parameters": { +"mode": "combine", +"options": {}, +"combineBy": "combineByPosition" +}, +"typeVersion": 3 +}, +{ +"id": "2dffda98-18c6-4c7b-8fc3-0e6539642ea2", +"name": "Save to Tracker", +"type": "n8n-nodes-base.airtable", +"position": [ +1420, +-20 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appiNoPRvhJxz9crl", +"cachedResultUrl": "https://airtable.com/appiNoPRvhJxz9crl", +"cachedResultName": "US Grants.gov Tracker" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblX93C9MNzizhibd", +"cachedResultUrl": "https://airtable.com/appiNoPRvhJxz9crl/tblX93C9MNzizhibd", +"cachedResultName": "Table 1" +}, +"columns": { +"value": { +"URL": "=https://grants.gov/search-results-detail/{{ $('Get Grant Details').item.json.id }}", +"Goal": "={{ $json.output.goal }}", +"Notes": "={{ $json.output.good_to_know.join('\\n') }}", +"Title": "={{ $('Get Grant Details').item.json.opportunityTitle }}", +"Agency": "={{ $('Get Grant Details').item.json.synopsis.agencyContactName }}", +"Status": "New", +"Funding": "={{ $('Get Grant Details').item.json.synopsis.estimatedFunding }}", +"Duration": "={{ $json.output.duration }}", +"Award Floor": "={{ $('Get Grant Details').item.json.synopsis.awardFloor }}", +"Posted Date": "={{ $('Get Grant Details').item.json.synopsis.postingDate }}", +"Agency Email": "={{ $('Get Grant Details').item.json.synopsis.agencyContactEmail }}", +"Agency Phone": "={{ $('Get Grant Details').item.json.synopsis.agencyContactPhone }}", +"Eligibility?": "={{ $json.output.eligibility_matches.length > 0 ? 'Yes' : 'No' }}", +"Award Ceiling": "={{ $('Get Grant Details').item.json.synopsis.awardCeiling }}", +"Response Date": "={{ $('Get Grant Details').item.json.synopsis.responseDate }}", +"Success Criteria": "={{ $json.output.success_criteria.join('\\n') }}", +"Eligibility Notes": "={{ $json.output.eligibility_matches.join('\\n') }}", +"Opportunity Number": "={{ $('Get Grant Details').item.json.opportunityNumber }}" +}, +"schema": [ +{ +"id": "Opportunity Number", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Opportunity Number", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Status", +"type": "options", +"display": true, +"options": [ +{ +"name": "New", +"value": "New" +}, +{ +"name": "Under Review", +"value": "Under Review" +}, +{ +"name": "Interested", +"value": "Interested" +}, +{ +"name": "Not Interested", +"value": "Not Interested" +} +], +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Status", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Title", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Title", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "URL", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "URL", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Goal", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Goal", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Success Criteria", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Success Criteria", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Notes", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Notes", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Eligibility?", +"type": "options", +"display": true, +"options": [ +{ +"name": "Yes", +"value": "Yes" +}, +{ +"name": "No", +"value": "No" +} +], +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Eligibility?", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Eligibility Notes", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Eligibility Notes", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Duration", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Duration", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Agency", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Agency", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Agency Email", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Agency Email", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Agency Phone", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Agency Phone", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Posted Date", +"type": "dateTime", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Posted Date", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Response Date", +"type": "dateTime", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Response Date", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Funding", +"type": "number", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Funding", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Award Ceiling", +"type": "number", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Award Ceiling", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Award Floor", +"type": "number", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Award Floor", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [] +}, +"options": {}, +"operation": "create" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "f0712788-b801-4070-a5c2-2f7ed620588e", +"name": "Only New Grants", +"type": "n8n-nodes-base.removeDuplicates", +"position": [ +-60, +-180 +], +"parameters": { +"options": {}, +"operation": "removeItemsSeenInPreviousExecutions", +"dedupeValue": "={{ $json.id }}" +}, +"typeVersion": 2 +}, +{ +"id": "fb4ac14d-0bdd-40f7-9b31-3a23450b1f0b", +"name": "AI Grants since Yesterday", +"type": "n8n-nodes-base.httpRequest", +"position": [ +-420, +-180 +], +"parameters": { +"url": "https://apply07.grants.gov/grantsws/rest/opportunities/search", +"method": "POST", +"options": {}, +"jsonBody": "{\n \"keyword\": \"ai\",\n \"cfda\": null,\n \"agencies\": null,\n \"sortBy\": \"openDate|desc\",\n \"rows\": 5000,\n \"eligibilities\": null,\n \"fundingCategories\": null,\n \"fundingInstruments\": null,\n \"dateRange\": \"1\",\n \"oppStatuses\": \"forecasted|posted\"\n}", +"sendBody": true, +"specifyBody": "json" +}, +"typeVersion": 4.2 +}, +{ +"id": "0446c882-764a-4c94-8c49-f368c50586a0", +"name": "Get New Eligible Grants Today", +"type": "n8n-nodes-base.airtable", +"position": [ +-400, +500 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appiNoPRvhJxz9crl", +"cachedResultUrl": "https://airtable.com/appiNoPRvhJxz9crl", +"cachedResultName": "US Grants.gov Tracker" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblX93C9MNzizhibd", +"cachedResultUrl": "https://airtable.com/appiNoPRvhJxz9crl/tblX93C9MNzizhibd", +"cachedResultName": "Table 1" +}, +"options": {}, +"operation": "search", +"filterByFormula": "=AND(\n {Status} = 'New',\n {Eligibility?} = 'Yes',\n IS_SAME(DATETIME_FORMAT(Created, 'YYYY-MM-DD'), DATETIME_FORMAT(TODAY(), 'YYYY-MM-DD'))\n)" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "70bca43a-d00e-4ee6-828a-9926ba1d8fdb", +"name": "Generate Email", +"type": "n8n-nodes-base.html", +"position": [ +-160, +500 +], +"parameters": { +"html": "\n\n\n\n \n \n \n \n \n \n \n \n \n\n\n\n\n \n \n \n \n \n \n \n \n
\n \n \n \n \n
\n
\n
\n \n \n\n
\n
\n
\n \n\n \n \n \n \n \n
\n \n \n

Latest AI Grants

\n \n\n
\n\n
\n
\n
\n\n \n
\n
\n
\n \n\n\n \n \n
\n
\n
\n \n \n\n
\n
\n
\n \n\n \n \n \n \n \n
\n{{\n$input.all().map((input,idx) => {\nreturn `\n
\n
\n

\n ${idx+1}. ${input.json.Title}\n

\n
\n ${input.json.Agency}\n ·\n See details\n
\n

\n Synopsis: ${input.json.Goal}\n

\n
    \n ${input.json['Success Criteria']\n .split('\\n')\n .map(text => `
  • ${text}
  • `)\n .join('')\n }\n
\n
\n Posted By ${input.json['Posted Date']\n .toDateTime()\n .format('EEE, dd MMM yyyy t')}\n
\n Respond By ${input.json['Response Date']\n .toDateTime()\n .format('EEE, dd MMM yyyy t')}\n \n
\n
\n`\n}).join('
')\n}} \n
\n\n
\n
\n
\n\n \n
\n
\n
\n \n\n\n \n \n
\n
\n
\n \n \n\n
\n
\n
\n \n\n \n \n \n \n \n
\n \n
\n

Autogenerated by n8n.

\n

Brought to you by workflow #{{ $workflow.id }}

\n
\n\n
\n\n
\n
\n
\n\n \n
\n
\n
\n \n\n\n \n
\n \n \n\n\n\n" +}, +"executeOnce": true, +"typeVersion": 1.2 +}, +{ +"id": "12bd72f5-3028-4572-b59e-1cc143e44a86", +"name": "Everyday @ 9am", +"type": "n8n-nodes-base.scheduleTrigger", +"position": [ +-720, +460 +], +"parameters": { +"rule": { +"interval": [ +{ +"triggerAtHour": 8 +} +] +} +}, +"typeVersion": 1.2 +}, +{ +"id": "ca62c507-bce5-4a63-be0e-e60591408668", +"name": "Everyday @ 8.30am", +"type": "n8n-nodes-base.scheduleTrigger", +"position": [ +-720, +-220 +], +"parameters": { +"rule": { +"interval": [ +{ +"triggerAtHour": 8, +"triggerAtMinute": 30 +} +] +} +}, +"typeVersion": 1.2 +}, +{ +"id": "032bec7e-5aff-4103-b81e-e5bc4a88ddde", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-540, +-420 +], +"parameters": { +"color": 7, +"width": 700, +"height": 480, +"content": "## 1. Fetch Latest AI Grants, Ignore Those Already Seen\n[Learn more about the Remove Duplicates node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.removeduplicates/)\n\nA cool feature of n8n's remove duplicates node is that it works across executions. What this means for this template is that the node will help us keep track of grant IDs to know if we've already processed them and if so, filter them out so we won't have duplicate alerts." +}, +"typeVersion": 1 +}, +{ +"id": "07147665-3571-4512-adce-2727dcb95240", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +180, +-520 +], +"parameters": { +"color": 7, +"width": 1000, +"height": 720, +"content": "## 2. Quickly Determine Eligibility Using AI\n[Learn more about the Information Extractor node](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.information-extractor/)\n\nQualifying Leads requires a lot of contextual reasoning taking into account many factors such as commercials, location and eligibility criteria. Whilst it's not guaranteed AI can or will solve this for your particular requirements, it can however get you a good distance of the way there!\n\nAI in this template intends to reduce time (and therefore cost) for a team member needs to spend per grant listing or increase their coverage of grants which they would otherwise miss due to capacity." +}, +"typeVersion": 1 +}, +{ +"id": "f4758b4d-727a-4ce8-b071-3388eb16b219", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1200, +-280 +], +"parameters": { +"color": 7, +"width": 520, +"height": 480, +"content": "## 3. Save Results to Grant Tracker\n[Learn more about the Airtable Node](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.airtable/)\n\nIn n8n, it's easy to send your data anywhere to manage yourself, share with your team or reuse with other workflows. Here for demonstration purposes, we'll just store each grant as a row in our Airtable database.\n\nCheck out the sample Airtable here: https://airtable.com/appiNoPRvhJxz9crl/shrRdP6zstgsxjDKL" +}, +"typeVersion": 1 +}, +{ +"id": "a7861a21-021f-4629-b863-2163c7436d13", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-540, +240 +], +"parameters": { +"color": 7, +"width": 620, +"height": 500, +"content": "## 4. Generate Latest AI Grants Alert Email\n[Learn more about the HTML Template node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.html/)\n\nUsing our freshly collected AI grants, it would be nice if we can share them with our team members via email. A nicely formatted email digest can be generated using the HTML template node, with added links for greater impact.\n\nHere in this demonstration, we will loop through all eligible new grants and compile them into a newsletter format using the HTML node.\n" +}, +"typeVersion": 1 +}, +{ +"id": "4d09af53-92cb-4288-86d7-dcf695bfb358", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +100, +240 +], +"parameters": { +"color": 7, +"width": 640, +"height": 500, +"content": "## 5. Send to a list of Subscribers\n[Learn more about the Gmail node](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.gmail/)\n\nFinally, we can source a list of subscribers to send our generated email newsletter.\n\nHere, our subscriber list is another table alongside our grants table that we can import that list using the Airtable node. You can use any email provider that supports HTML but for this demonstration, we're using Gmail for simplicity sake." +}, +"typeVersion": 1 +}, +{ +"id": "784d59f3-5b1f-4404-bc04-4bd58cf03585", +"name": "Get Subscribers", +"type": "n8n-nodes-base.airtable", +"position": [ +240, +500 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appiNoPRvhJxz9crl", +"cachedResultUrl": "https://airtable.com/appiNoPRvhJxz9crl", +"cachedResultName": "US Grants.gov Tracker" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblaS91hyhguntfaC", +"cachedResultUrl": "https://airtable.com/appiNoPRvhJxz9crl/tblaS91hyhguntfaC", +"cachedResultName": "Subscribers" +}, +"options": {}, +"operation": "search", +"filterByFormula": "AND({Status} = 'Active')" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"executeOnce": true, +"typeVersion": 2.1 +}, +{ +"id": "3be0788b-90ef-4648-aa25-1170208a685d", +"name": "Send Subscriber Email", +"type": "n8n-nodes-base.gmail", +"position": [ +480, +500 +], +"webhookId": "37eeec7a-1982-4137-8473-313bfb6c5b42", +"parameters": { +"sendTo": "={{ $json.Email }}", +"message": "={{ $('Generate Email').first().json.html }}", +"options": {}, +"subject": "Daily Newletter for Intersting US Grants" +}, +"credentials": { +"gmailOAuth2": { +"id": "Sf5Gfl9NiFTNXFWb", +"name": "Gmail account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "14a65482-b314-4a2f-9ce3-87e3aae126f9", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1280, +300 +], +"parameters": { +"color": 7, +"width": 460, +"height": 200, +"content": "## Scheduled Triggers\n[Learn more about Scheduled Triggers](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.scheduletrigger)\n\nScheduled triggers are a great way to run this template automatically in the morning ready for your team before they start their working day.\n\nFeel free to adjust the interval to a time which suits you!" +}, +"typeVersion": 1 +}, +{ +"id": "b172eb7a-58bc-4d4a-be22-796d34a59897", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1280, +-620 +], +"parameters": { +"width": 460, +"height": 900, +"content": "## Try It Out!\n\n### This n8n templates demonstrates how to automatically ingest a source of leads at regular intervals and take advantage of n8n's remove duplicates node to simplify duplicate detection.\nAdditionally after the leads are captured, a simple alerts notification can be generated and shared with team members.\n\n### How it works\n* A scheduled trigger is set to fetch a list of AI grants listed on the grants.gov website in the past day.\n* A Remove Duplicates node is used to track Grant IDs to filter out those already processed by the workflow.\n* New grants are summarized and analysed by AI nodes to determine eligibility and interest which is then saved to an Airtable database.\n* Another scheduled trigger starts a little later than the first to collect and summarize the new grants\n* The results are then compiled into an email template using the HTML node, in the form of a newsletter designed to alert and brief team members of new AI grants.\n* This email is then sent to a list of subscribers using the gmail node.\n\n## How to use\n* Make a copy of sample Airtable here: https://airtable.com/appiNoPRvhJxz9crl/shrRdP6zstgsxjDKL\n* The filters for fetching the grants is currently set to the \"AI\" category. Feel free to change this to include more categories.\n* Not interested in grants, this template can works for other sources of leads just change the endpoint and how you're defining the item ID to track.\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": "f9849413-4dad-44dc-92ec-8879d123bfd3", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +720, +40 +], +"parameters": { +"width": 320, +"height": 120, +"content": "### Add your company details here!\nCompany details are added in the system prompt to help the AI determine eligibility. The more details the better!" +}, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"Merge": { +"main": [ +[ +{ +"node": "Save to Tracker", +"type": "main", +"index": 0 +} +] +] +}, +"Everyday @ 9am": { +"main": [ +[ +{ +"node": "Get New Eligible Grants Today", +"type": "main", +"index": 0 +} +] +] +}, +"Generate Email": { +"main": [ +[ +{ +"node": "Get Subscribers", +"type": "main", +"index": 0 +} +] +] +}, +"Grants to List": { +"main": [ +[ +{ +"node": "Only New Grants", +"type": "main", +"index": 0 +} +] +] +}, +"Get Subscribers": { +"main": [ +[ +{ +"node": "Send Subscriber Email", +"type": "main", +"index": 0 +} +] +] +}, +"Only New Grants": { +"main": [ +[ +{ +"node": "Get Grant Details", +"type": "main", +"index": 0 +} +] +] +}, +"Save to Tracker": { +"main": [ +[] +] +}, +"Everyday @ 8.30am": { +"main": [ +[ +{ +"node": "AI Grants since Yesterday", +"type": "main", +"index": 0 +} +] +] +}, +"Get Grant Details": { +"main": [ +[ +{ +"node": "Summarize Synopsis", +"type": "main", +"index": 0 +}, +{ +"node": "Eligibility Factors", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Summarize Synopsis", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"OpenAI Chat Model1": { +"ai_languageModel": [ +[ +{ +"node": "Eligibility Factors", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Summarize Synopsis": { +"main": [ +[ +{ +"node": "Merge", +"type": "main", +"index": 0 +} +] +] +}, +"Eligibility Factors": { +"main": [ +[ +{ +"node": "Merge", +"type": "main", +"index": 1 +} +] +] +}, +"AI Grants since Yesterday": { +"main": [ +[ +{ +"node": "Grants to List", +"type": "main", +"index": 0 +} +] +] +}, +"Get New Eligible Grants Today": { +"main": [ +[ +{ +"node": "Generate Email", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Detect hallucinations using specialised Ollama model bespoke-minicheck.txt b/Detect hallucinations using specialised Ollama model bespoke-minicheck.txt new file mode 100644 index 0000000..f053417 --- /dev/null +++ b/Detect hallucinations using specialised Ollama model bespoke-minicheck.txt @@ -0,0 +1,478 @@ +{ +"meta": { +"instanceId": "6e361bfcd1e8378c9b07774b22409c7eaea7080f01d5248da45077c0c6108b99", +"templateCredsSetupCompleted": true +}, +"nodes": [ +{ +"id": "cbc036f7-b0e1-4eb4-94c3-7571c67a1efe", +"name": "Code", +"type": "n8n-nodes-base.code", +"position": [ +-120, +40 +], +"parameters": { +"mode": "runOnceForEachItem", +"jsCode": "// Get the input text\nconst text = $input.item.json.text;\n\n// Ensure text is not null or undefined\nif (!text) {\n throw new Error('Input text is empty');\n}\n\n// Function to split text into sentences while preserving dates and list items\nfunction splitIntoSentences(text) {\n const monthNames = '(?:Januar|Februar|März|April|Mai|Juni|Juli|August|September|Oktober|November|Dezember)';\n const datePattern = `(?:\\\\d{1,2}\\\\.\\\\s*(?:${monthNames}|\\\\d{1,2}\\\\.)\\\\s*\\\\d{2,4})`;\n \n // Split by sentence-ending punctuation, but not within dates or list items\n const regex = new RegExp(`(?<=[.!?])\\\\s+(?=[A-ZÄÖÜ]|$)(?!${datePattern}|\\\\s*[-•]\\\\s)`, 'g');\n \n return text.split(regex)\n .map(sentence => sentence.trim())\n .filter(sentence => sentence !== '');\n}\n\n// Split the text into sentences\nconst sentences = splitIntoSentences(text);\n\n// Output a single object with an array of sentences\nreturn { json: { sentences: sentences } };" +}, +"typeVersion": 2 +}, +{ +"id": "faae4740-a529-4275-be0e-b079c3bfde58", +"name": "Split Out1", +"type": "n8n-nodes-base.splitOut", +"position": [ +340, +-180 +], +"parameters": { +"options": { +"destinationFieldName": "claim" +}, +"fieldToSplitOut": "sentences" +}, +"typeVersion": 1 +}, +{ +"id": "c3944f89-e267-4df0-8fc4-9281eac4e759", +"name": "Basic LLM Chain4", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +640, +-40 +], +"parameters": { +"text": "=Document: {{ $('Merge1').item.json.facts }}\nClaim: {{ $json.claim }}", +"promptType": "define" +}, +"typeVersion": 1.5 +}, +{ +"id": "4e53c7f1-ab9f-42be-a253-9328b209fc68", +"name": "Ollama Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOllama", +"position": [ +700, +160 +], +"parameters": { +"model": "bespoke-minicheck:latest", +"options": {} +}, +"credentials": { +"ollamaApi": { +"id": "DeuK54dDNrCCnXHl", +"name": "Ollama account" +} +}, +"typeVersion": 1 +}, +{ +"id": "0252e47e-0e50-4024-92a0-74b554c8cbd1", +"name": "When clicking ‘Test workflow’", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +-760, +40 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "8dd3f67c-e36f-4b03-8f9f-9b52ea23e0ed", +"name": "Edit Fields", +"type": "n8n-nodes-base.set", +"position": [ +-460, +40 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "55748f38-486f-495f-91ec-02c1d49acf18", +"name": "facts", +"type": "string", +"value": "Sara Beery came to MIT as an assistant professor in MIT’s Department of Electrical Engineering and Computer Science (EECS) eager to focus on ecological challenges. She has fashioned her research career around the opportunity to apply her expertise in computer vision, machine learning, and data science to tackle real-world issues in conservation and sustainability. Beery was drawn to the Institute’s commitment to “computing for the planet,” and set out to bring her methods to global-scale environmental and biodiversity monitoring.\n\nIn the Pacific Northwest, salmon have a disproportionate impact on the health of their ecosystems, and their complex reproductive needs have attracted Beery’s attention. Each year, millions of salmon embark on a migration to spawn. Their journey begins in freshwater stream beds where the eggs hatch. Young salmon fry (newly hatched salmon) make their way to the ocean, where they spend several years maturing to adulthood. As adults, the salmon return to the streams where they were born in order to spawn, ensuring the continuation of their species by depositing their eggs in the gravel of the stream beds. Both male and female salmon die shortly after supplying the river habitat with the next generation of salmon." +}, +{ +"id": "7d8e29db-4a4b-47c5-8c93-fda1e72137a7", +"name": "text", +"type": "string", +"value": "MIT's AI Pioneer Tackles Salmon Conservation Professor Sara Beery, a rising star in MIT's Department of Electrical Engineering and Computer Science, is revolutionizing ecological conservation through cutting-edge technology. Specializing in computer vision, machine learning, and data science, Beery has set her sights on addressing real-world sustainability challenges. Her current focus? The vital salmon populations of the Pacific Northwest. These fish play a crucial role in their ecosystems, with their complex life cycle spanning from freshwater streams to the open ocean and back again. Beery's innovative approach uses AI to monitor salmon migration patterns, providing unprecedented insights into their behavior and habitat needs. Beery's work has led to the development of underwater AI cameras that can distinguish between different salmon species with 99.9% accuracy. Her team has also created a revolutionary \"salmon translator\" that can predict spawning locations based on fish vocalizations. As climate change threatens these delicate ecosystems, Beery's research offers hope for more effective conservation strategies. By harnessing the power of technology, she's not just studying nature – she's actively working to preserve it for future generations." +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "25849b47-1550-464c-9e70-e787712e5765", +"name": "Merge", +"type": "n8n-nodes-base.merge", +"position": [ +1120, +-160 +], +"parameters": { +"mode": "combine", +"options": {}, +"combineBy": "combineByPosition" +}, +"typeVersion": 3 +}, +{ +"id": "eaea7ef4-a5d5-42b8-b262-e9a4bd6b7281", +"name": "Filter", +"type": "n8n-nodes-base.filter", +"position": [ +1340, +-160 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "20a4ffd6-0dd0-44f9-97bc-7d891f689f4d", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.text }}", +"rightValue": "No" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "9f074bdb-b1a6-4c36-be1c-203f78092657", +"name": "When Executed by Another Workflow", +"type": "n8n-nodes-base.executeWorkflowTrigger", +"position": [ +-760, +-200 +], +"parameters": { +"workflowInputs": { +"values": [ +{ +"name": "facts" +}, +{ +"name": "text" +} +] +} +}, +"typeVersion": 1.1 +}, +{ +"id": "0a08ac40-b497-4f6e-ac2c-2213a00d63f2", +"name": "Aggregate", +"type": "n8n-nodes-base.aggregate", +"position": [ +1560, +-160 +], +"parameters": { +"options": {}, +"aggregate": "aggregateAllItemData" +}, +"typeVersion": 1 +}, +{ +"id": "b0d79886-01fc-43c7-88fe-a7a5b8b56b35", +"name": "Merge1", +"type": "n8n-nodes-base.merge", +"position": [ +80, +-180 +], +"parameters": { +"mode": "combine", +"options": {}, +"combineBy": "combineByPosition" +}, +"typeVersion": 3 +}, +{ +"id": "82640408-9db4-4a12-9136-1a22985b609b", +"name": "Basic LLM Chain", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +1780, +-160 +], +"parameters": { +"text": "={{ $json.data }}", +"messages": { +"messageValues": [ +{ +"message": "You are a fact-checking assistant. Your task is to analyze a list of statements, each accompanied by a \"yes\" or \"no\" indicating whether the statement is correct. Follow these guidelines:\n\n1. Review Process:\n a) Carefully read through each statement and its corresponding yes/no answer.\n b) Identify which statements are marked as incorrect (no).\n c) Ignore chit-chat sentences or statements that don't contain factual information.\n d) Count the total number of incorrect factual statements.\n\n2. Statement Classification:\n - Factual Statements: Contains specific information, data, or claims that can be verified.\n - Chit-chat/Non-factual: General comments, introductions, or transitions that don't present verifiable facts.\n\n3. Summary Structure:\n a) Overview: Provide a brief summary of the number of factual errors found.\n b) List of Problems: Enumerate the incorrect factual statements.\n c) Final Assessment: Offer a concise evaluation of the overall state of the article's factual accuracy.\n\n4. Prioritization:\n - Focus only on the factual statements marked as incorrect (no).\n - Ignore statements marked as correct (yes) and non-factual chit-chat.\n\n5. Feedback Tone:\n - Maintain a neutral and objective tone.\n - Present the information factually without additional commentary.\n\n6. Output Format:\n Present your summary in the following structure:\n\n ## Problem Summary\n [Number] incorrect factual statements were identified in the article.\n\n ## List of Incorrect Factual Statements\n 1. [First incorrect factual statement]\n 2. [Second incorrect factual statement]\n 3. [Third incorrect factual statement]\n (Continue listing all incorrect factual statements)\n\n ## Final Assessment\n Based on the number of incorrect factual statements:\n - If 0-1 errors: The article appears to be highly accurate and may only need minor factual adjustments.\n - If 2-3 errors: The article requires some revision to address these factual inaccuracies.\n - If 4 or more errors: The article needs significant revision to improve its factual accuracy.\n\nRemember, your role is to provide a clear, concise summary of the incorrect factual statements to help the writing team quickly understand what needs to be addressed. Ignore any chit-chat or non-factual statements in your analysis and summary." +} +] +}, +"promptType": "define" +}, +"typeVersion": 1.5 +}, +{ +"id": "719054ef-0863-4e52-8390-23313c750aac", +"name": "Ollama Model", +"type": "@n8n/n8n-nodes-langchain.lmOllama", +"position": [ +1880, +60 +], +"parameters": { +"model": "qwen2.5:1.5b", +"options": {} +}, +"credentials": { +"ollamaApi": { +"id": "DeuK54dDNrCCnXHl", +"name": "Ollama account" +} +}, +"typeVersion": 1 +}, +{ +"id": "6595eb25-32ce-49f5-a013-b87d7f3c65d3", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1480, +-320 +], +"parameters": { +"width": 860, +"height": 600, +"content": "## Build a summary\n\nThis is useful to run it in an agentic workflow. You may remove the summary part and return the raw array with the found issues." +}, +"typeVersion": 1 +}, +{ +"id": "9f6cde97-d2a7-44e4-b715-321ec1e68bd3", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-240, +-320 +], +"parameters": { +"width": 760, +"height": 600, +"content": "## Split into sentences" +}, +"typeVersion": 1 +}, +{ +"id": "1ceb8f3c-c00b-4496-82b2-20578550c4be", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +540, +-320 +], +"parameters": { +"width": 920, +"height": 600, +"content": "## Fact checking\n\nThis use a small ollama model that is specialized on that task: https://ollama.com/library/bespoke-minicheck\n\nYou have to install it before use with `ollama pull bespoke-minicheck`." +}, +"typeVersion": 1 +}, +{ +"id": "6e340925-d4e5-4fe1-ba9d-a89a23b68226", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-860, +-20 +], +"parameters": { +"width": 600, +"height": 300, +"content": "## Test workflow\n" +}, +"typeVersion": 1 +}, +{ +"id": "5561d606-93d2-4887-839d-8ce2230ff30c", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-860, +-320 +], +"parameters": { +"width": 600, +"height": 280, +"content": "## Entrypoint to use in other workflows\n" +}, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"Code": { +"main": [ +[ +{ +"node": "Merge1", +"type": "main", +"index": 1 +} +] +] +}, +"Merge": { +"main": [ +[ +{ +"node": "Filter", +"type": "main", +"index": 0 +} +] +] +}, +"Filter": { +"main": [ +[ +{ +"node": "Aggregate", +"type": "main", +"index": 0 +} +] +] +}, +"Merge1": { +"main": [ +[ +{ +"node": "Split Out1", +"type": "main", +"index": 0 +} +] +] +}, +"Aggregate": { +"main": [ +[ +{ +"node": "Basic LLM Chain", +"type": "main", +"index": 0 +} +] +] +}, +"Split Out1": { +"main": [ +[ +{ +"node": "Merge", +"type": "main", +"index": 0 +}, +{ +"node": "Basic LLM Chain4", +"type": "main", +"index": 0 +} +] +] +}, +"Edit Fields": { +"main": [ +[ +{ +"node": "Code", +"type": "main", +"index": 0 +}, +{ +"node": "Merge1", +"type": "main", +"index": 0 +} +] +] +}, +"Ollama Model": { +"ai_languageModel": [ +[ +{ +"node": "Basic LLM Chain", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Basic LLM Chain4": { +"main": [ +[ +{ +"node": "Merge", +"type": "main", +"index": 1 +} +] +] +}, +"Ollama Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Basic LLM Chain4", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"When Executed by Another Workflow": { +"main": [ +[ +{ +"node": "Code", +"type": "main", +"index": 0 +}, +{ +"node": "Merge1", +"type": "main", +"index": 0 +} +] +] +}, +"When clicking ‘Test workflow’": { +"main": [ +[ +{ +"node": "Edit Fields", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Detect toxic language in Telegram messages.txt b/Detect toxic language in Telegram messages.txt new file mode 100644 index 0000000..8b4622b --- /dev/null +++ b/Detect toxic language in Telegram messages.txt @@ -0,0 +1,148 @@ +{ +"nodes": [ +{ +"name": "Telegram Trigger", +"type": "n8n-nodes-base.telegramTrigger", +"position": [ +600, +300 +], +"webhookId": "2d0805da-143e-40c9-b327-242b1f052c31", +"parameters": { +"updates": [ +"message", +"edited_message", +"channel_post", +"edited_channel_post" +], +"additionalFields": {} +}, +"credentials": { +"telegramApi": "telegram_habot" +}, +"typeVersion": 1 +}, +{ +"name": "Google Perspective", +"type": "n8n-nodes-base.googlePerspective", +"position": [ +800, +300 +], +"parameters": { +"text": "={{$json[\"message\"][\"text\"]}}", +"options": { +"languages": "en" +}, +"requestedAttributesUi": { +"requestedAttributesValues": [ +{ +"attributeName": "identity_attack" +}, +{ +"attributeName": "threat" +}, +{ +"attributeName": "profanity" +} +] +} +}, +"credentials": { +"googlePerspectiveOAuth2Api": "perspective_api" +}, +"typeVersion": 1 +}, +{ +"name": "IF", +"type": "n8n-nodes-base.if", +"position": [ +1000, +300 +], +"parameters": { +"conditions": { +"number": [ +{ +"value1": "={{$json[\"attributeScores\"][\"PROFANITY\"][\"summaryScore\"][\"value\"]}}", +"value2": 0.7, +"operation": "larger" +} +] +} +}, +"typeVersion": 1 +}, +{ +"name": "Telegram", +"type": "n8n-nodes-base.telegram", +"position": [ +1200, +150 +], +"parameters": { +"text": "I don't tolerate toxic language!", +"chatId": "={{$node[\"Telegram Trigger\"].json[\"message\"][\"chat\"][\"id\"]}}", +"additionalFields": { +"reply_to_message_id": "={{$node[\"Telegram Trigger\"].json[\"message\"][\"message_id\"]}}" +} +}, +"credentials": { +"telegramApi": "telegram_habot" +}, +"typeVersion": 1 +}, +{ +"name": "NoOp", +"type": "n8n-nodes-base.noOp", +"position": [ +1200, +400 +], +"parameters": {}, +"typeVersion": 1 +} +], +"connections": { +"IF": { +"main": [ +[ +{ +"node": "Telegram", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "NoOp", +"type": "main", +"index": 0 +} +] +] +}, +"Telegram Trigger": { +"main": [ +[ +{ +"node": "Google Perspective", +"type": "main", +"index": 0 +} +] +] +}, +"Google Perspective": { +"main": [ +[ +{ +"node": "IF", +"type": "main", +"index": 0 +} +] +] +} +} +}sDetect toxic language in Telegram messages \ No newline at end of file diff --git a/Discord AI-powered bot.txt b/Discord AI-powered bot.txt new file mode 100644 index 0000000..1dc42cf --- /dev/null +++ b/Discord AI-powered bot.txt @@ -0,0 +1,265 @@ +{ +"id": "180", +"meta": { +"instanceId": "fb924c73af8f703905bc09c9ee8076f48c17b596ed05b18c0ff86915ef8a7c4a" +}, +"name": "Discord AI bot", +"tags": [], +"nodes": [ +{ +"id": "6f188270-2c08-491f-bf52-c4a152b33aa0", +"name": "When clicking \"Execute Workflow\"", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +1220, +780 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "e4839de2-fc04-40b0-b6bc-596455ad93fe", +"name": "Webhook", +"type": "n8n-nodes-base.webhook", +"position": [ +1220, +580 +], +"webhookId": "d0cdd428-be96-4821-85bc-65342cf928d0", +"parameters": { +"path": "d0cdd428-be96-4821-85bc-65342cf928d0", +"options": {}, +"httpMethod": "POST" +}, +"typeVersion": 1 +}, +{ +"id": "15dcafe1-6361-4775-ace0-e34fd2a143b4", +"name": "No Operation, do nothing", +"type": "n8n-nodes-base.noOp", +"position": [ +2120, +940 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "0d28fe8e-da80-458b-9a75-d316019cb3ae", +"name": "Analyze user request", +"type": "n8n-nodes-base.openAi", +"position": [ +1420, +680 +], +"parameters": { +"model": "gpt-4", +"prompt": { +"messages": [ +{ +"role": "system", +"content": "Act as a service desk agent and help to categorize user messages. Return back only JSON without quotations. Do not return anything else." +}, +{ +"content": "=Here is a user feedback: \"{{ $json.body.feedback }}\". Please analyse it and put into one of the categories:\n1. \"success-story\" for user appraisal or success story. this will be processed by customer success department\n2. \"urgent-issue\" for extreme dissatisfaction or an urgent problem. this will be escalated to the IT team. Please assess if the request is really urgent and whether it has an immediate impact on the client. If the ticket doesn't look like an immediate problem or an extreme dissatisfaction then proceed as a normal ticket.\n3. \"ticket\" for everything else. This will be processed as normal by customer support team.\n\nPlease return back a JSON with the following structure: category (string), feedback (string), instruction (string).\nCategory must match the analysed category. feedback must match the original text. instruction should contain a text for a department according to the category with a one sentense summary of the feedback. Please be polite and friendly to the colleagues." +} +] +}, +"options": { +"maxTokens": 500, +"temperature": 0.5 +}, +"resource": "chat" +}, +"credentials": { +"openAiApi": { +"id": "63", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "ce1c4198-ce21-4436-9ccb-4a2a078cd06e", +"name": "Select category", +"type": "n8n-nodes-base.switch", +"position": [ +1840, +680 +], +"parameters": { +"rules": { +"rules": [ +{ +"value2": "success-story" +}, +{ +"output": 1, +"value2": "urgent-issue" +}, +{ +"output": 2, +"value2": "ticket" +} +] +}, +"value1": "={{ $json.gpt_reply.category.toLowerCase() }}", +"dataType": "string", +"fallbackOutput": 3 +}, +"typeVersion": 1 +}, +{ +"id": "839cc38d-b393-4fc1-a068-47a8fcf55e3f", +"name": "Parse JSON", +"type": "n8n-nodes-base.set", +"position": [ +1640, +680 +], +"parameters": { +"values": { +"string": [ +{ +"name": "gpt_reply", +"value": "={{ JSON.parse( $json.message.content.replace(/\\n(?=[^\"]*\"(?:[^\"]*\"[^\"]*\")*[^\"]*$)/g, '\\\\n')) }}" +} +] +}, +"options": {} +}, +"typeVersion": 2 +}, +{ +"id": "4c150439-89af-42bd-bbdc-905d13ada76b", +"name": "User Success Dept", +"type": "n8n-nodes-base.discord", +"position": [ +2120, +460 +], +"parameters": { +"text": "={{ $json.gpt_reply.instruction }}", +"options": {}, +"webhookUri": "https://discord.com/api/webhooks/" +}, +"typeVersion": 1 +}, +{ +"id": "9a5e5335-9e6c-4f1f-a0f0-b1b022956549", +"name": "IT Dept", +"type": "n8n-nodes-base.discord", +"position": [ +2120, +620 +], +"parameters": { +"text": "={{ $json.gpt_reply.instruction }}", +"options": {}, +"webhookUri": "https://discord.com/api/webhooks/" +}, +"typeVersion": 1 +}, +{ +"id": "d6d6250a-3a24-49f1-a597-47ebc179949c", +"name": "Helpdesk", +"type": "n8n-nodes-base.discord", +"position": [ +2120, +780 +], +"parameters": { +"text": "={{ $json.gpt_reply.instruction }}", +"options": {}, +"webhookUri": "https://discord.com/api/webhooks/" +}, +"typeVersion": 1 +} +], +"active": false, +"pinData": {}, +"settings": { +"callerPolicy": "workflowsFromSameOwner", +"saveManualExecutions": true, +"saveDataSuccessExecution": "all" +}, +"versionId": "8871171e-7e18-49ee-a570-facbe97afb79", +"connections": { +"Webhook": { +"main": [ +[ +{ +"node": "Analyze user request", +"type": "main", +"index": 0 +} +] +] +}, +"Parse JSON": { +"main": [ +[ +{ +"node": "Select category", +"type": "main", +"index": 0 +} +] +] +}, +"Select category": { +"main": [ +[ +{ +"node": "User Success Dept", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "IT Dept", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Helpdesk", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "No Operation, do nothing", +"type": "main", +"index": 0 +} +] +] +}, +"Analyze user request": { +"main": [ +[ +{ +"node": "Parse JSON", +"type": "main", +"index": 0 +} +] +] +}, +"When clicking \"Execute Workflow\"": { +"main": [ +[ +{ +"node": "Analyze user request", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Dynamically generate a webpage from user request using OpenAI Structured Output (1).txt b/Dynamically generate a webpage from user request using OpenAI Structured Output (1).txt new file mode 100644 index 0000000..0d516e7 --- /dev/null +++ b/Dynamically generate a webpage from user request using OpenAI Structured Output (1).txt @@ -0,0 +1,224 @@ +{ +"id": "eXiaTDyKfXpMeyLh", +"meta": { +"instanceId": "f4f5d195bb2162a0972f737368404b18be694648d365d6c6771d7b4909d28167", +"templateCredsSetupCompleted": true +}, +"name": "Dynamically generate HTML page from user request using OpenAI Structured Output", +"tags": [], +"nodes": [ +{ +"id": "b1d9659f-4cd0-4f87-844d-32b2af1dcf13", +"name": "Respond to Webhook", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +2160, +380 +], +"parameters": { +"options": { +"responseHeaders": { +"entries": [ +{ +"name": "Content-Type", +"value": "text/html; charset=UTF-8" +} +] +} +}, +"respondWith": "text", +"responseBody": "={{ $json.html }}" +}, +"typeVersion": 1.1 +}, +{ +"id": "5ca8ad3e-7702-4f07-af24-d38e94fdc4ec", +"name": "Open AI - Using Structured Output", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1240, +380 +], +"parameters": { +"url": "https://api.openai.com/v1/chat/completions", +"method": "POST", +"options": {}, +"jsonBody": "={\n \"model\": \"gpt-4o-2024-08-06\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a user interface designer and copy writter. Your job is to help users visualize their website ideas. You design elegant and simple webs, with professional text. You use Tailwind framework\"\n },\n {\n \"role\": \"user\",\n \"content\": \"{{ $json.query.query }}\"\n }\n ],\n \"response_format\":\n{\n \"type\": \"json_schema\",\n \"json_schema\": {\n \"name\": \"ui\",\n \"description\": \"Dynamically generated UI\",\n \"strict\": true,\n \"schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"type\": {\n \"type\": \"string\",\n \"description\": \"The type of the UI component\",\n \"enum\": [\n \"div\",\n \"span\",\n \"a\",\n \"p\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"ul\",\n \"ol\",\n \"li\",\n \"img\",\n \"button\",\n \"input\",\n \"textarea\",\n \"select\",\n \"option\",\n \"label\",\n \"form\",\n \"table\",\n \"thead\",\n \"tbody\",\n \"tr\",\n \"th\",\n \"td\",\n \"nav\",\n \"header\",\n \"footer\",\n \"section\",\n \"article\",\n \"aside\",\n \"main\",\n \"figure\",\n \"figcaption\",\n \"blockquote\",\n \"q\",\n \"hr\",\n \"code\",\n \"pre\",\n \"iframe\",\n \"video\",\n \"audio\",\n \"canvas\",\n \"svg\",\n \"path\",\n \"circle\",\n \"rect\",\n \"line\",\n \"polyline\",\n \"polygon\",\n \"g\",\n \"use\",\n \"symbol\"\n]\n },\n \"label\": {\n \"type\": \"string\",\n \"description\": \"The label of the UI component, used for buttons or form fields\"\n },\n \"children\": {\n \"type\": \"array\",\n \"description\": \"Nested UI components\",\n \"items\": {\n \"$ref\": \"#\"\n }\n },\n \"attributes\": {\n \"type\": \"array\",\n \"description\": \"Arbitrary attributes for the UI component, suitable for any element using Tailwind framework\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\",\n \"description\": \"The name of the attribute, for example onClick or className\"\n },\n \"value\": {\n \"type\": \"string\",\n \"description\": \"The value of the attribute using the Tailwind framework classes\"\n }\n },\n \"additionalProperties\": false,\n \"required\": [\"name\", \"value\"]\n }\n }\n },\n \"required\": [\"type\", \"label\", \"children\", \"attributes\"],\n \"additionalProperties\": false\n }\n }\n}\n}", +"sendBody": true, +"sendHeaders": true, +"specifyBody": "json", +"authentication": "predefinedCredentialType", +"headerParameters": { +"parameters": [ +{ +"name": "Content-Type", +"value": "application/json" +} +] +}, +"nodeCredentialType": "openAiApi" +}, +"credentials": { +"openAiApi": { +"id": "WqzqjezKh8VtxdqA", +"name": "OpenAi account - Baptiste" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "24e5ca73-a3b3-4096-8c66-d84838d89b0c", +"name": "OpenAI - JSON to HTML", +"type": "@n8n/n8n-nodes-langchain.openAi", +"position": [ +1420, +380 +], +"parameters": { +"modelId": { +"__rl": true, +"mode": "list", +"value": "gpt-4o-mini", +"cachedResultName": "GPT-4O-MINI" +}, +"options": { +"temperature": 0.2 +}, +"messages": { +"values": [ +{ +"role": "system", +"content": "You convert a JSON to HTML. \nThe JSON output has the following fields:\n- html: the page HTML\n- title: the page title" +}, +{ +"content": "={{ $json.choices[0].message.content }}" +} +] +}, +"jsonOutput": true +}, +"credentials": { +"openAiApi": { +"id": "WqzqjezKh8VtxdqA", +"name": "OpenAi account - Baptiste" +} +}, +"typeVersion": 1.3 +}, +{ +"id": "c50bdc84-ba59-4f30-acf7-496cee25068d", +"name": "Format the HTML result", +"type": "n8n-nodes-base.html", +"position": [ +1940, +380 +], +"parameters": { +"html": "\n\n\n\n \n \n {{ $json.message.content.title }}\n\n\n{{ $json.message.content.html }}\n\n" +}, +"typeVersion": 1.2 +}, +{ +"id": "193093f4-b1ce-4964-ab10-c3208e343c69", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1134, +62 +], +"parameters": { +"color": 7, +"width": 638, +"height": 503, +"content": "## Generate HTML from user query\n\n**HTTP Request node**\n- Send the user query to OpenAI, with a defined JSON response format - *using HTTP Request node as it has not yet been implemented in the OpenAI nodes*\n- The response format is inspired by the [Structured Output defined in OpenAI Introduction post](https://openai.com/index/introducing-structured-outputs-in-the-api)\n- The output is a JSON containing HTML components and attributed\n\n\n**OpenAI node**\n- Format the response from the previous node from JSON format to HTML format" +}, +"typeVersion": 1 +}, +{ +"id": "0371156a-211f-4d92-82b1-f14fe60d4b6b", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +0, +60 +], +"parameters": { +"color": 7, +"width": 768, +"height": 503, +"content": "## Workflow: Dynamically generate an HTML page from a user request using OpenAI Structured Output\n\n**Overview**\n- This workflow is a experiment to build HTML pages from a user input using the new Structured Output from OpenAI.\n- The Structured Output could be used in a variety of cases. Essentially, it guarantees the output from the GPT will follow a defined structure (JSON object).\n- It uses Tailwind CSS to make it slightly nicer, but any\n\n**How it works**\n- Once active, go to the production URL and add what you'd like to build as the parameter \"query\"\n- Example: https://production_url.com?query=a%20signup%20form\n- OpenAI nodes will first output the UI as a JSON then convert it to HTML\n- Finally, the response is integrated in a HTML container and rendered to the user\n\n**Further thoughts**\n- Results are not yet amazing, it is hard to see the direct value of such an experiment\n- But it showcase the potential of the Structured Output. Being able to guarantee the output format is key to build robust AI applications." +}, +"typeVersion": 1 +}, +{ +"id": "06380781-5189-4d99-9ecd-d8913ce40fd5", +"name": "Webhook", +"type": "n8n-nodes-base.webhook", +"position": [ +820, +380 +], +"webhookId": "d962c916-6369-431a-9d80-af6e6a50fdf5", +"parameters": { +"path": "d962c916-6369-431a-9d80-af6e6a50fdf5", +"options": { +"allowedOrigins": "*" +}, +"responseMode": "responseNode" +}, +"typeVersion": 2 +} +], +"active": true, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "d2307a2a-5427-4769-94a6-10eab703a788", +"connections": { +"Webhook": { +"main": [ +[ +{ +"node": "Open AI - Using Structured Output", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI - JSON to HTML": { +"main": [ +[ +{ +"node": "Format the HTML result", +"type": "main", +"index": 0 +} +] +] +}, +"Format the HTML result": { +"main": [ +[ +{ +"node": "Respond to Webhook", +"type": "main", +"index": 0 +} +] +] +}, +"Open AI - Using Structured Output": { +"main": [ +[ +{ +"node": "OpenAI - JSON to HTML", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Dynamically generate a webpage from user request using OpenAI Structured Output.txt b/Dynamically generate a webpage from user request using OpenAI Structured Output.txt new file mode 100644 index 0000000..0d516e7 --- /dev/null +++ b/Dynamically generate a webpage from user request using OpenAI Structured Output.txt @@ -0,0 +1,224 @@ +{ +"id": "eXiaTDyKfXpMeyLh", +"meta": { +"instanceId": "f4f5d195bb2162a0972f737368404b18be694648d365d6c6771d7b4909d28167", +"templateCredsSetupCompleted": true +}, +"name": "Dynamically generate HTML page from user request using OpenAI Structured Output", +"tags": [], +"nodes": [ +{ +"id": "b1d9659f-4cd0-4f87-844d-32b2af1dcf13", +"name": "Respond to Webhook", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +2160, +380 +], +"parameters": { +"options": { +"responseHeaders": { +"entries": [ +{ +"name": "Content-Type", +"value": "text/html; charset=UTF-8" +} +] +} +}, +"respondWith": "text", +"responseBody": "={{ $json.html }}" +}, +"typeVersion": 1.1 +}, +{ +"id": "5ca8ad3e-7702-4f07-af24-d38e94fdc4ec", +"name": "Open AI - Using Structured Output", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1240, +380 +], +"parameters": { +"url": "https://api.openai.com/v1/chat/completions", +"method": "POST", +"options": {}, +"jsonBody": "={\n \"model\": \"gpt-4o-2024-08-06\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a user interface designer and copy writter. Your job is to help users visualize their website ideas. You design elegant and simple webs, with professional text. You use Tailwind framework\"\n },\n {\n \"role\": \"user\",\n \"content\": \"{{ $json.query.query }}\"\n }\n ],\n \"response_format\":\n{\n \"type\": \"json_schema\",\n \"json_schema\": {\n \"name\": \"ui\",\n \"description\": \"Dynamically generated UI\",\n \"strict\": true,\n \"schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"type\": {\n \"type\": \"string\",\n \"description\": \"The type of the UI component\",\n \"enum\": [\n \"div\",\n \"span\",\n \"a\",\n \"p\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"ul\",\n \"ol\",\n \"li\",\n \"img\",\n \"button\",\n \"input\",\n \"textarea\",\n \"select\",\n \"option\",\n \"label\",\n \"form\",\n \"table\",\n \"thead\",\n \"tbody\",\n \"tr\",\n \"th\",\n \"td\",\n \"nav\",\n \"header\",\n \"footer\",\n \"section\",\n \"article\",\n \"aside\",\n \"main\",\n \"figure\",\n \"figcaption\",\n \"blockquote\",\n \"q\",\n \"hr\",\n \"code\",\n \"pre\",\n \"iframe\",\n \"video\",\n \"audio\",\n \"canvas\",\n \"svg\",\n \"path\",\n \"circle\",\n \"rect\",\n \"line\",\n \"polyline\",\n \"polygon\",\n \"g\",\n \"use\",\n \"symbol\"\n]\n },\n \"label\": {\n \"type\": \"string\",\n \"description\": \"The label of the UI component, used for buttons or form fields\"\n },\n \"children\": {\n \"type\": \"array\",\n \"description\": \"Nested UI components\",\n \"items\": {\n \"$ref\": \"#\"\n }\n },\n \"attributes\": {\n \"type\": \"array\",\n \"description\": \"Arbitrary attributes for the UI component, suitable for any element using Tailwind framework\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\",\n \"description\": \"The name of the attribute, for example onClick or className\"\n },\n \"value\": {\n \"type\": \"string\",\n \"description\": \"The value of the attribute using the Tailwind framework classes\"\n }\n },\n \"additionalProperties\": false,\n \"required\": [\"name\", \"value\"]\n }\n }\n },\n \"required\": [\"type\", \"label\", \"children\", \"attributes\"],\n \"additionalProperties\": false\n }\n }\n}\n}", +"sendBody": true, +"sendHeaders": true, +"specifyBody": "json", +"authentication": "predefinedCredentialType", +"headerParameters": { +"parameters": [ +{ +"name": "Content-Type", +"value": "application/json" +} +] +}, +"nodeCredentialType": "openAiApi" +}, +"credentials": { +"openAiApi": { +"id": "WqzqjezKh8VtxdqA", +"name": "OpenAi account - Baptiste" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "24e5ca73-a3b3-4096-8c66-d84838d89b0c", +"name": "OpenAI - JSON to HTML", +"type": "@n8n/n8n-nodes-langchain.openAi", +"position": [ +1420, +380 +], +"parameters": { +"modelId": { +"__rl": true, +"mode": "list", +"value": "gpt-4o-mini", +"cachedResultName": "GPT-4O-MINI" +}, +"options": { +"temperature": 0.2 +}, +"messages": { +"values": [ +{ +"role": "system", +"content": "You convert a JSON to HTML. \nThe JSON output has the following fields:\n- html: the page HTML\n- title: the page title" +}, +{ +"content": "={{ $json.choices[0].message.content }}" +} +] +}, +"jsonOutput": true +}, +"credentials": { +"openAiApi": { +"id": "WqzqjezKh8VtxdqA", +"name": "OpenAi account - Baptiste" +} +}, +"typeVersion": 1.3 +}, +{ +"id": "c50bdc84-ba59-4f30-acf7-496cee25068d", +"name": "Format the HTML result", +"type": "n8n-nodes-base.html", +"position": [ +1940, +380 +], +"parameters": { +"html": "\n\n\n\n \n \n {{ $json.message.content.title }}\n\n\n{{ $json.message.content.html }}\n\n" +}, +"typeVersion": 1.2 +}, +{ +"id": "193093f4-b1ce-4964-ab10-c3208e343c69", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1134, +62 +], +"parameters": { +"color": 7, +"width": 638, +"height": 503, +"content": "## Generate HTML from user query\n\n**HTTP Request node**\n- Send the user query to OpenAI, with a defined JSON response format - *using HTTP Request node as it has not yet been implemented in the OpenAI nodes*\n- The response format is inspired by the [Structured Output defined in OpenAI Introduction post](https://openai.com/index/introducing-structured-outputs-in-the-api)\n- The output is a JSON containing HTML components and attributed\n\n\n**OpenAI node**\n- Format the response from the previous node from JSON format to HTML format" +}, +"typeVersion": 1 +}, +{ +"id": "0371156a-211f-4d92-82b1-f14fe60d4b6b", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +0, +60 +], +"parameters": { +"color": 7, +"width": 768, +"height": 503, +"content": "## Workflow: Dynamically generate an HTML page from a user request using OpenAI Structured Output\n\n**Overview**\n- This workflow is a experiment to build HTML pages from a user input using the new Structured Output from OpenAI.\n- The Structured Output could be used in a variety of cases. Essentially, it guarantees the output from the GPT will follow a defined structure (JSON object).\n- It uses Tailwind CSS to make it slightly nicer, but any\n\n**How it works**\n- Once active, go to the production URL and add what you'd like to build as the parameter \"query\"\n- Example: https://production_url.com?query=a%20signup%20form\n- OpenAI nodes will first output the UI as a JSON then convert it to HTML\n- Finally, the response is integrated in a HTML container and rendered to the user\n\n**Further thoughts**\n- Results are not yet amazing, it is hard to see the direct value of such an experiment\n- But it showcase the potential of the Structured Output. Being able to guarantee the output format is key to build robust AI applications." +}, +"typeVersion": 1 +}, +{ +"id": "06380781-5189-4d99-9ecd-d8913ce40fd5", +"name": "Webhook", +"type": "n8n-nodes-base.webhook", +"position": [ +820, +380 +], +"webhookId": "d962c916-6369-431a-9d80-af6e6a50fdf5", +"parameters": { +"path": "d962c916-6369-431a-9d80-af6e6a50fdf5", +"options": { +"allowedOrigins": "*" +}, +"responseMode": "responseNode" +}, +"typeVersion": 2 +} +], +"active": true, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "d2307a2a-5427-4769-94a6-10eab703a788", +"connections": { +"Webhook": { +"main": [ +[ +{ +"node": "Open AI - Using Structured Output", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI - JSON to HTML": { +"main": [ +[ +{ +"node": "Format the HTML result", +"type": "main", +"index": 0 +} +] +] +}, +"Format the HTML result": { +"main": [ +[ +{ +"node": "Respond to Webhook", +"type": "main", +"index": 0 +} +] +] +}, +"Open AI - Using Structured Output": { +"main": [ +[ +{ +"node": "OpenAI - JSON to HTML", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/ETL pipeline for text processing.txt b/ETL pipeline for text processing.txt new file mode 100644 index 0000000..3afc601 --- /dev/null +++ b/ETL pipeline for text processing.txt @@ -0,0 +1,258 @@ +{ +"id": "6", +"name": "ETL pipeline", +"nodes": [ +{ +"name": "Twitter", +"type": "n8n-nodes-base.twitter", +"position": [ +300, +300 +], +"parameters": { +"limit": 3, +"operation": "search", +"searchText": "=#OnThisDay", +"additionalFields": {} +}, +"credentials": { +"twitterOAuth1Api": "twitter_api" +}, +"typeVersion": 1 +}, +{ +"name": "Postgres", +"type": "n8n-nodes-base.postgres", +"position": [ +1100, +300 +], +"parameters": { +"table": "tweets", +"columns": "text, score, magnitude", +"returnFields": "=*" +}, +"credentials": { +"postgres": "postgres" +}, +"typeVersion": 1 +}, +{ +"name": "MongoDB", +"type": "n8n-nodes-base.mongoDb", +"position": [ +500, +300 +], +"parameters": { +"fields": "text", +"options": {}, +"operation": "insert", +"collection": "tweets" +}, +"credentials": { +"mongoDb": "mongodb" +}, +"typeVersion": 1 +}, +{ +"name": "Slack", +"type": "n8n-nodes-base.slack", +"position": [ +1500, +200 +], +"parameters": { +"text": "=🐦 NEW TWEET with sentiment score {{$json[\"score\"]}} and magnitude {{$json[\"magnitude\"]}} ⬇️\n{{$json[\"text\"]}}", +"channel": "tweets", +"attachments": [], +"otherOptions": {} +}, +"credentials": { +"slackApi": "slack" +}, +"typeVersion": 1 +}, +{ +"name": "IF", +"type": "n8n-nodes-base.if", +"position": [ +1300, +300 +], +"parameters": { +"conditions": { +"number": [ +{ +"value1": "={{$json[\"score\"]}}", +"operation": "larger" +} +] +} +}, +"typeVersion": 1 +}, +{ +"name": "NoOp", +"type": "n8n-nodes-base.noOp", +"position": [ +1500, +400 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"name": "Google Cloud Natural Language", +"type": "n8n-nodes-base.googleCloudNaturalLanguage", +"position": [ +700, +300 +], +"parameters": { +"content": "={{$node[\"MongoDB\"].json[\"text\"]}}", +"options": {} +}, +"credentials": { +"googleCloudNaturalLanguageOAuth2Api": "google_nlp" +}, +"typeVersion": 1 +}, +{ +"name": "Set", +"type": "n8n-nodes-base.set", +"position": [ +900, +300 +], +"parameters": { +"values": { +"number": [ +{ +"name": "score", +"value": "={{$json[\"documentSentiment\"][\"score\"]}}" +}, +{ +"name": "magnitude", +"value": "={{$json[\"documentSentiment\"][\"magnitude\"]}}" +} +], +"string": [ +{ +"name": "text", +"value": "={{$node[\"Twitter\"].json[\"text\"]}}" +} +] +}, +"options": {} +}, +"typeVersion": 1 +}, +{ +"name": "Cron", +"type": "n8n-nodes-base.cron", +"position": [ +100, +300 +], +"parameters": { +"triggerTimes": { +"item": [ +{ +"hour": 6 +} +] +} +}, +"typeVersion": 1 +} +], +"active": false, +"settings": {}, +"connections": { +"IF": { +"main": [ +[ +{ +"node": "Slack", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "NoOp", +"type": "main", +"index": 0 +} +] +] +}, +"Set": { +"main": [ +[ +{ +"node": "Postgres", +"type": "main", +"index": 0 +} +] +] +}, +"Cron": { +"main": [ +[ +{ +"node": "Twitter", +"type": "main", +"index": 0 +} +] +] +}, +"MongoDB": { +"main": [ +[ +{ +"node": "Google Cloud Natural Language", +"type": "main", +"index": 0 +} +] +] +}, +"Twitter": { +"main": [ +[ +{ +"node": "MongoDB", +"type": "main", +"index": 0 +} +] +] +}, +"Postgres": { +"main": [ +[ +{ +"node": "IF", +"type": "main", +"index": 0 +} +] +] +}, +"Google Cloud Natural Language": { +"main": [ +[ +{ +"node": "Set", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Easy Image Captioning with Gemini 1.5 Pro.txt b/Easy Image Captioning with Gemini 1.5 Pro.txt new file mode 100644 index 0000000..51996a1 --- /dev/null +++ b/Easy Image Captioning with Gemini 1.5 Pro.txt @@ -0,0 +1,401 @@ +{ +"meta": { +"instanceId": "408f9fb9940c3cb18ffdef0e0150fe342d6e655c3a9fac21f0f644e8bedabcd9" +}, +"nodes": [ +{ +"id": "0b64edf1-57e0-4704-b78c-c8ab2b91f74d", +"name": "When clicking ‘Test workflow’", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +480, +300 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "a875d1c5-ccfe-4bbf-b429-56a42b0ca778", +"name": "Google Gemini Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini", +"position": [ +1280, +720 +], +"parameters": { +"options": {}, +"modelName": "models/gemini-1.5-flash" +}, +"credentials": { +"googlePalmApi": { +"id": "dSxo6ns5wn658r8N", +"name": "Google Gemini(PaLM) Api account" +} +}, +"typeVersion": 1 +}, +{ +"id": "a5e00543-dbaa-4e62-afb0-825ebefae3f3", +"name": "Structured Output Parser", +"type": "@n8n/n8n-nodes-langchain.outputParserStructured", +"position": [ +1480, +720 +], +"parameters": { +"jsonSchemaExample": "{\n\t\"caption_title\": \"\",\n\t\"caption_text\": \"\"\n}" +}, +"typeVersion": 1.2 +}, +{ +"id": "bb9af9c6-6c81-4e92-a29f-18ab3afbe327", +"name": "Get Info", +"type": "n8n-nodes-base.editImage", +"position": [ +1100, +400 +], +"parameters": { +"operation": "information" +}, +"typeVersion": 1 +}, +{ +"id": "8a0dbd5d-5886-484a-80a0-486f349a9856", +"name": "Resize For AI", +"type": "n8n-nodes-base.editImage", +"position": [ +1100, +560 +], +"parameters": { +"width": 512, +"height": 512, +"options": {}, +"operation": "resize" +}, +"typeVersion": 1 +}, +{ +"id": "d29f254a-5fa3-46fa-b153-19dfd8e8c6a7", +"name": "Calculate Positioning", +"type": "n8n-nodes-base.code", +"position": [ +2020, +720 +], +"parameters": { +"mode": "runOnceForEachItem", +"jsCode": "const { size, output } = $input.item.json;\n\nconst lineHeight = 35;\nconst fontSize = Math.round(size.height / lineHeight);\nconst maxLineLength = Math.round(size.width/fontSize) * 2;\nconst text = `\"${output.caption_title}\". ${output.caption_text}`;\nconst numLinesOccupied = Math.round(text.length / maxLineLength);\n\nconst verticalPadding = size.height * 0.02;\nconst horizontalPadding = size.width * 0.02;\nconst rectPosX = 0;\nconst rectPosY = size.height - (verticalPadding * 2.5) - (numLinesOccupied * fontSize);\nconst textPosX = horizontalPadding;\nconst textPosY = size.height - (numLinesOccupied * fontSize) - (verticalPadding/2);\n\nreturn {\n caption: {\n fontSize,\n maxLineLength,\n numLinesOccupied,\n rectPosX,\n rectPosY,\n textPosX,\n textPosY,\n verticalPadding,\n horizontalPadding,\n }\n}\n" +}, +"typeVersion": 2 +}, +{ +"id": "12a7f2d6-8684-48a5-aa41-40a8a4f98c79", +"name": "Apply Caption to Image", +"type": "n8n-nodes-base.editImage", +"position": [ +2380, +560 +], +"parameters": { +"options": {}, +"operation": "multiStep", +"operations": { +"operations": [ +{ +"color": "=#0000008c", +"operation": "draw", +"endPositionX": "={{ $json.size.width }}", +"endPositionY": "={{ $json.size.height }}", +"startPositionX": "={{ $json.caption.rectPosX }}", +"startPositionY": "={{ $json.caption.rectPosY }}" +}, +{ +"font": "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", +"text": "=\"{{ $json.output.caption_title }}\". {{ $json.output.caption_text }}", +"fontSize": "={{ $json.caption.fontSize }}", +"fontColor": "#FFFFFF", +"operation": "text", +"positionX": "={{ $json.caption.textPosX }}", +"positionY": "={{ $json.caption.textPosY }}", +"lineLength": "={{ $json.caption.maxLineLength }}" +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "4d569ec8-04c2-4d21-96e1-86543b26892d", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-120, +80 +], +"parameters": { +"width": 423.75, +"height": 431.76353488372104, +"content": "## Try it out!\n\n### This workflow takes an image and generates a caption for it using AI. The OpenAI node has been able to do this for a while but this workflow demonstrates how to achieve the same with other multimodal vision models such as Google's Gemini.\n\nAdditional, we'll use the Edit Image node to overlay the generated caption onto the image. This can be useful for publications or can be repurposed for copyrights and/or watermarks.\n\n### Need Help?\nJoin the [Discord](https://discord.com/invite/XPKeKXeB7d) or ask in the [Forum](https://community.n8n.io/)!\n" +}, +"typeVersion": 1 +}, +{ +"id": "45d37945-5a7a-42eb-8c8c-5940ea276072", +"name": "Merge Image & Caption", +"type": "n8n-nodes-base.merge", +"position": [ +1620, +400 +], +"parameters": { +"mode": "combine", +"options": {}, +"combineBy": "combineByPosition" +}, +"typeVersion": 3 +}, +{ +"id": "53a26842-ad56-4c8d-a59d-4f6d3f9e2407", +"name": "Merge Caption & Positions", +"type": "n8n-nodes-base.merge", +"position": [ +2200, +560 +], +"parameters": { +"mode": "combine", +"options": {}, +"combineBy": "combineByPosition" +}, +"typeVersion": 3 +}, +{ +"id": "b6c28913-b16a-4c59-aa49-47e9bb97f86d", +"name": "Get Image", +"type": "n8n-nodes-base.httpRequest", +"position": [ +680, +300 +], +"parameters": { +"url": "https://images.pexels.com/photos/1267338/pexels-photo-1267338.jpeg?auto=compress&cs=tinysrgb&w=600", +"options": {} +}, +"typeVersion": 4.2 +}, +{ +"id": "6c25054d-8103-4be9-bea7-6c3dd47f49a3", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +340, +80 +], +"parameters": { +"color": 7, +"width": 586.25, +"height": 486.25, +"content": "## 1. Import an Image \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 grab an image off Pexels.com - a popular free stock photography site - by using the HTTP request node to download.\n\nIn your own workflows, this can be replaces by other triggers such as webhooks." +}, +"typeVersion": 1 +}, +{ +"id": "d1b708e2-31c3-4cd1-a353-678bc33d4022", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +960, +140 +], +"parameters": { +"color": 7, +"width": 888.75, +"height": 783.75, +"content": "## 2. Using Vision Model to Generate Caption\n[Learn more about the Basic LLM Chain](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.chainllm)\n\nn8n's basic LLM node supports multimodal input by allowing you to specify either a binary or an image url to send to a compatible LLM. This makes it easy to start utilising this powerful feature for visual classification or OCR tasks which have previously depended on more dedicated OCR models.\n\nHere, we've simply passed our image binary as a \"user message\" option, asking the LLM to help us generate a caption title and text which is appropriate for the given subject. Once generated, we'll pass this text along with the image to combine them both." +}, +"typeVersion": 1 +}, +{ +"id": "36a39871-340f-4c44-90e6-74393b9be324", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1880, +280 +], +"parameters": { +"color": 7, +"width": 753.75, +"height": 635, +"content": "## 3. Overlay Caption on Image \n[Read more about the Edit Image node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.editimage)\n\nFinally, we’ll perform some basic calculations to place the generated caption onto the image. With n8n's user-friendly image editing features, this can be done entirely within the workflow!\n\nThe Code node tool is ideal for these types of calculations and is used here to position the caption at the bottom of the image. To create the overlay, the Edit Image node enables us to insert text onto the image, which we’ll use to add the generated caption." +}, +"typeVersion": 1 +}, +{ +"id": "d175fe97-064e-41da-95fd-b15668c330c4", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2660, +280 +], +"parameters": { +"width": 563.75, +"height": 411.25, +"content": "**FIG 1.** Example input image with AI generated caption\n![Example Output](https://res.cloudinary.com/daglih2g8/image/upload/f_auto,q_auto/v1/n8n-workflows/l5xbb4ze4wyxwwefqmnc#full-width)" +}, +"typeVersion": 1 +}, +{ +"id": "23db0c90-45b6-4b85-b017-a52ad5a9ad5b", +"name": "Image Captioning Agent", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +1280, +560 +], +"parameters": { +"text": "Generate a caption for this image.", +"messages": { +"messageValues": [ +{ +"message": "=You role is to provide an appropriate image caption for user provided images.\n\nThe individual components of a caption are as follows: who, when, where, context and miscellaneous. For a really good caption, follow this template: who + when + where + context + miscellaneous\n\nGive the caption a punny title." +}, +{ +"type": "HumanMessagePromptTemplate", +"messageType": "imageBinary" +} +] +}, +"promptType": "define", +"hasOutputParser": true +}, +"typeVersion": 1.4 +} +], +"pinData": {}, +"connections": { +"Get Info": { +"main": [ +[ +{ +"node": "Merge Image & Caption", +"type": "main", +"index": 0 +} +] +] +}, +"Get Image": { +"main": [ +[ +{ +"node": "Resize For AI", +"type": "main", +"index": 0 +}, +{ +"node": "Get Info", +"type": "main", +"index": 0 +} +] +] +}, +"Resize For AI": { +"main": [ +[ +{ +"node": "Image Captioning Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Calculate Positioning": { +"main": [ +[ +{ +"node": "Merge Caption & Positions", +"type": "main", +"index": 1 +} +] +] +}, +"Merge Image & Caption": { +"main": [ +[ +{ +"node": "Calculate Positioning", +"type": "main", +"index": 0 +}, +{ +"node": "Merge Caption & Positions", +"type": "main", +"index": 0 +} +] +] +}, +"Image Captioning Agent": { +"main": [ +[ +{ +"node": "Merge Image & Caption", +"type": "main", +"index": 1 +} +] +] +}, +"Google Gemini Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Image Captioning Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Structured Output Parser": { +"ai_outputParser": [ +[ +{ +"node": "Image Captioning Agent", +"type": "ai_outputParser", +"index": 0 +} +] +] +}, +"Merge Caption & Positions": { +"main": [ +[ +{ +"node": "Apply Caption to Image", +"type": "main", +"index": 0 +} +] +] +}, +"When clicking ‘Test workflow’": { +"main": [ +[ +{ +"node": "Get Image", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Effortless Email Management with AI-Powered Summarization & Review.txt b/Effortless Email Management with AI-Powered Summarization & Review.txt new file mode 100644 index 0000000..9a1d8c3 --- /dev/null +++ b/Effortless Email Management with AI-Powered Summarization & Review.txt @@ -0,0 +1,892 @@ +{ +"id": "nkPjDxMrrkKbgHaV", +"meta": { +"instanceId": "a4bfc93e975ca233ac45ed7c9227d84cf5a2329310525917adaf3312e10d5462", +"templateCredsSetupCompleted": true +}, +"name": "Effortless Email Management with AI", +"tags": [], +"nodes": [ +{ +"id": "9d77e26f-de2b-4bd4-b0f0-9924a8f459a6", +"name": "Email Trigger (IMAP)", +"type": "n8n-nodes-base.emailReadImap", +"position": [ +-2000, +-180 +], +"parameters": { +"options": {} +}, +"credentials": { +"imap": { +"id": "k31W9oGddl9pMDy4", +"name": "IMAP info@n3witalia.com" +} +}, +"typeVersion": 2 +}, +{ +"id": "cf2d020b-b125-4a20-8694-8ed0f7acf755", +"name": "Markdown", +"type": "n8n-nodes-base.markdown", +"position": [ +-1740, +-180 +], +"parameters": { +"html": "={{ $json.textHtml }}", +"options": {} +}, +"typeVersion": 1 +}, +{ +"id": "41bfceff-0155-4643-be60-ee301e2d69e1", +"name": "Send Email", +"type": "n8n-nodes-base.emailSend", +"position": [ +400, +-320 +], +"webhookId": "a79ae1b4-648c-4cb4-b6cd-04ea3c1d9314", +"parameters": { +"html": "={{ $('Edit Fields').item.json.email }}", +"options": {}, +"subject": "=Re: {{ $('Email Trigger (IMAP)').item.json.subject }}", +"toEmail": "={{ $('Email Trigger (IMAP)').item.json.from }}", +"fromEmail": "={{ $('Email Trigger (IMAP)').item.json.to }}" +}, +"credentials": { +"smtp": { +"id": "hRjP3XbDiIQqvi7x", +"name": "SMTP info@n3witalia.com" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "2aff581a-8b64-405c-b62f-74bf189fd7b1", +"name": "Qdrant Vector Store", +"type": "@n8n/n8n-nodes-langchain.vectorStoreQdrant", +"position": [ +-320, +600 +], +"parameters": { +"mode": "retrieve-as-tool", +"options": {}, +"toolName": "company_knowladge_base", +"toolDescription": "Extracts information regarding the request made.", +"qdrantCollection": { +"__rl": true, +"mode": "id", +"value": "=COLLECTION" +}, +"includeDocumentMetadata": false +}, +"credentials": { +"qdrantApi": { +"id": "iyQ6MQiVaF3VMBmt", +"name": "QdrantApi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "6e3f6df0-8924-47d9-855c-51205d19e86d", +"name": "Embeddings OpenAI", +"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi", +"position": [ +-440, +800 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "CDX6QM4gLYanh0P4", +"name": "OpenAi account" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "37ac411b-4a74-44d1-917e-b07d1c9ca221", +"name": "Email Summarization Chain", +"type": "@n8n/n8n-nodes-langchain.chainSummarization", +"position": [ +-1480, +-180 +], +"parameters": { +"options": { +"binaryDataKey": "={{ $json.data }}", +"summarizationMethodAndPrompts": { +"values": { +"prompt": "=Write a concise summary of the following in max 100 words:\n\n\"{{ $json.data }}\"\n\nDo not enter the total number of words used.", +"combineMapPrompt": "=Write a concise summary of the following in max 100 words:\n\n\"{{ $json.data }}\"\n\nDo not enter the total number of words used." +} +} +}, +"operationMode": "nodeInputBinary" +}, +"typeVersion": 2 +}, +{ +"id": "91edbac9-847b-4f31-a8dd-09418bd93642", +"name": "Write email", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +-1040, +-180 +], +"parameters": { +"text": "=Write the text to reply to the following email:\n\n{{ $json.response.text }}", +"options": { +"systemMessage": "You are an expert at answering emails. You need to answer them professionally based on the information you have. This is a business email. Be concise and never exceed 100 words. Only the body of the email, not create the subject" +}, +"promptType": "define", +"hasOutputParser": true +}, +"typeVersion": 1.7 +}, +{ +"id": "1da0e72a-db97-4216-a1a5-038cebaf7e10", +"name": "OpenAI", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +-180, +280 +], +"parameters": { +"model": { +"__rl": true, +"mode": "list", +"value": "gpt-4o-mini", +"cachedResultName": "gpt-4o-mini" +}, +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "CDX6QM4gLYanh0P4", +"name": "OpenAi account" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "af2d6284-4c8f-4a07-b689-d0f55aaabd26", +"name": "Gmail", +"type": "n8n-nodes-base.gmail", +"position": [ +-300, +-180 +], +"webhookId": "d6dd2e7c-90ea-4b65-9c64-523d2541a054", +"parameters": { +"sendTo": "info@n3w.it", +"message": "=

MESSAGE

\n{{ $('Email Trigger (IMAP)').item.json.textHtml }}\n\n

AI RESPONSE

\n{{ $json.email }}", +"options": {}, +"subject": "=[Approval Required] {{ $('Email Trigger (IMAP)').item.json.subject }}", +"operation": "sendAndWait", +"responseType": "freeText" +}, +"credentials": { +"gmailOAuth2": { +"id": "nyuHvSX5HuqfMPlW", +"name": "Gmail account (n3w.it)" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "aaccc4a6-ce53-4813-8247-65bd1a9d5639", +"name": "Text Classifier", +"type": "@n8n/n8n-nodes-langchain.textClassifier", +"position": [ +-60, +-180 +], +"parameters": { +"options": { +"systemPromptTemplate": "Please classify the text provided by the user into one of the following categories: {categories}, and use the provided formatting instructions below. Don't explain, and only output the json." +}, +"inputText": "={{ $json.data.text }}", +"categories": { +"categories": [ +{ +"category": "Approved", +"description": "The email has been reviewed and accepted as-is. The human explicitly or implicity express approva, indicating that no changes ar needed.\n\nExample:\n\"Ok\",\n\"Approvato\",\n\"Invia\"" +}, +{ +"category": "Declined", +"description": "The email has been reviewd, but the human request modifications before it sent link tweaks, removing parts, rewording etc... This could include suggested edits, rewording or major revision." +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "b46de5d9-1a2e-4d28-930b-e18fb1d7876e", +"name": "Edit Fields", +"type": "n8n-nodes-base.set", +"position": [ +-580, +-180 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "35d7c303-42f4-4dd1-b41e-6eb087c23c3d", +"name": "email", +"type": "string", +"value": "={{ $json.output }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "36ce51c6-8ee1-4230-84c0-40e259eafb1a", +"name": "When clicking ‘Test workflow’", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +-1340, +-1300 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "21a0c991-65dc-483e-9b98-5cedaba7ae13", +"name": "Create collection", +"type": "n8n-nodes-base.httpRequest", +"position": [ +-1040, +-1440 +], +"parameters": { +"url": "https://QDRANTURL/collections/COLLECTION", +"method": "POST", +"options": {}, +"jsonBody": "{\n \"filter\": {}\n}", +"sendBody": true, +"sendHeaders": true, +"specifyBody": "json", +"authentication": "genericCredentialType", +"genericAuthType": "httpHeaderAuth", +"headerParameters": { +"parameters": [ +{ +"name": "Content-Type", +"value": "application/json" +} +] +} +}, +"credentials": { +"httpHeaderAuth": { +"id": "qhny6r5ql9wwotpn", +"name": "Qdrant API (Hetzner)" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "9a048d7d-bcdf-40b7-b33a-94b811083eac", +"name": "Refresh collection", +"type": "n8n-nodes-base.httpRequest", +"position": [ +-1040, +-1180 +], +"parameters": { +"url": "https://QDRANTURL/collections/COLLECTION/points/delete", +"method": "POST", +"options": {}, +"jsonBody": "{\n \"filter\": {}\n}", +"sendBody": true, +"sendHeaders": true, +"specifyBody": "json", +"authentication": "genericCredentialType", +"genericAuthType": "httpHeaderAuth", +"headerParameters": { +"parameters": [ +{ +"name": "Content-Type", +"value": "application/json" +} +] +} +}, +"credentials": { +"httpHeaderAuth": { +"id": "qhny6r5ql9wwotpn", +"name": "Qdrant API (Hetzner)" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "db494d2d-5390-4f83-9b87-3409fef31a7d", +"name": "Get folder", +"type": "n8n-nodes-base.googleDrive", +"position": [ +-820, +-1180 +], +"parameters": { +"filter": { +"driveId": { +"__rl": true, +"mode": "list", +"value": "My Drive", +"cachedResultUrl": "https://drive.google.com/drive/my-drive", +"cachedResultName": "My Drive" +}, +"folderId": { +"__rl": true, +"mode": "id", +"value": "=test-whatsapp" +} +}, +"options": {}, +"resource": "fileFolder" +}, +"credentials": { +"googleDriveOAuth2Api": { +"id": "HEy5EuZkgPZVEa9w", +"name": "Google Drive account" +} +}, +"typeVersion": 3 +}, +{ +"id": "e30dbe6f-482e-47f9-b5b8-62c1113e6c8b", +"name": "Download Files", +"type": "n8n-nodes-base.googleDrive", +"position": [ +-600, +-1180 +], +"parameters": { +"fileId": { +"__rl": true, +"mode": "id", +"value": "={{ $json.id }}" +}, +"options": { +"googleFileConversion": { +"conversion": { +"docsToFormat": "text/plain" +} +} +}, +"operation": "download" +}, +"credentials": { +"googleDriveOAuth2Api": { +"id": "HEy5EuZkgPZVEa9w", +"name": "Google Drive account" +} +}, +"typeVersion": 3 +}, +{ +"id": "492d48d8-4997-4f04-902b-041da3210417", +"name": "Default Data Loader", +"type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader", +"position": [ +-200, +-980 +], +"parameters": { +"options": {}, +"dataType": "binary" +}, +"typeVersion": 1 +}, +{ +"id": "0cf45d10-3cbf-4eb6-ab30-11f264b3aa8d", +"name": "Token Splitter", +"type": "@n8n/n8n-nodes-langchain.textSplitterTokenSplitter", +"position": [ +-240, +-820 +], +"parameters": { +"chunkSize": 300, +"chunkOverlap": 30 +}, +"typeVersion": 1 +}, +{ +"id": "7d60f569-c34e-49a8-ba9a-88cf33083136", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-840, +-1500 +], +"parameters": { +"color": 6, +"width": 880, +"height": 220, +"content": "# STEP 1\n\n## Create Qdrant Collection\nChange:\n- QDRANTURL\n- COLLECTION" +}, +"typeVersion": 1 +}, +{ +"id": "e86b18c4-d7e8-4e81-b520-dbd8125edf38", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1060, +-1240 +], +"parameters": { +"color": 4, +"width": 620, +"height": 400, +"content": "# STEP 2\n\n\n\n\n\n\n\n\n\n\n\n\n## Documents vectorization with Qdrant and Google Drive\nChange:\n- QDRANTURL\n- COLLECTION" +}, +"typeVersion": 1 +}, +{ +"id": "05f65120-ef31-4c67-ac18-e68a8353909c", +"name": "Qdrant Vector Store1", +"type": "@n8n/n8n-nodes-langchain.vectorStoreQdrant", +"position": [ +-360, +-1180 +], +"parameters": { +"mode": "insert", +"options": {}, +"qdrantCollection": { +"__rl": true, +"mode": "id", +"value": "=COLLECTION" +} +}, +"credentials": { +"qdrantApi": { +"id": "iyQ6MQiVaF3VMBmt", +"name": "QdrantApi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "c15fd52f-b142-408e-af06-aeed10a1cf85", +"name": "Embeddings OpenAI1", +"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi", +"position": [ +-380, +-980 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "CDX6QM4gLYanh0P4", +"name": "OpenAi account" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "3e47224f-3deb-450b-b825-f16c5f860f28", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-2020, +-600 +], +"parameters": { +"color": 3, +"width": 580, +"height": 260, +"content": "# STEP 3 - MAIN FLOW\n\n\n## How it works\nThis workflow automates the handling of incoming emails, summarizes their content, generates appropriate responses using a retrieval-augmented generation (RAG) approach, and obtains approval or suggestions before sending replies. \n\nYou can quickly integrate Gmail and Outlook via the appropriate trigger nodes" +}, +"typeVersion": 1 +}, +{ +"id": "63097039-58cb-4e0f-9fb6-6bf868275519", +"name": "DeepSeek Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatDeepSeek", +"position": [ +-1560, +40 +], +"parameters": { +"options": {} +}, +"credentials": { +"deepSeekApi": { +"id": "sxh1rfZxonXV83hS", +"name": "DeepSeek account" +} +}, +"typeVersion": 1 +}, +{ +"id": "c86d6eeb-cf08-429f-b5b4-60b317071035", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1500, +-260 +], +"parameters": { +"width": 320, +"height": 240, +"content": "Chain that summarizes the received email" +}, +"typeVersion": 1 +}, +{ +"id": "4afc8b00-d1e5-473c-a71e-1299c84c546e", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1060, +-260 +], +"parameters": { +"width": 340, +"height": 240, +"content": "Agent that retrieves business information from a vector database and processes the response" +}, +"typeVersion": 1 +}, +{ +"id": "be1762ff-729b-4b83-9139-16f835b748f2", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1800, +-260 +], +"parameters": { +"height": 240, +"content": "Convert email to Markdown format for better understanding of LLM models" +}, +"typeVersion": 1 +}, +{ +"id": "f818ede7-895a-4860-91d3-f08cc32ec0e3", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-380, +-380 +], +"parameters": { +"color": 4, +"height": 360, +"content": "## IMPORTANT\n\nFor the \"Send Draft\" node, you need to send the draft email to a Gmail address because it is the only one that allows the \"Send and wait for response\" function." +}, +"typeVersion": 1 +}, +{ +"id": "929b525a-912b-4f7b-a6e7-dfeb88a446c8", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-100, +-260 +], +"parameters": { +"width": 360, +"height": 240, +"content": "Based on the suggestion received, the text classifier can understand whether the feedback received approves the generated email or not." +}, +"typeVersion": 1 +}, +{ +"id": "2468e643-013f-4925-ab35-c8ef4ee6eed2", +"name": "Email Reviewer", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +380, +-40 +], +"parameters": { +"text": "=Review at the following email:\n{{ $('Edit Fields').item.json.email }}\n\nFeedback from human:\n{{ $json.data.text }}", +"options": { +"systemMessage": "If you are an expert in reviewing emails before sending them. You need to review and structure them in such a way that you can send them. It must be in HTML format and you can insert (if you think it is appropriate) only HTML characters such as
, , ,

where necessary. Be concise and never exceed 100 words. Only the body of the email" +}, +"promptType": "define", +"hasOutputParser": true +}, +"typeVersion": 1.7 +}, +{ +"id": "ecd9d3f8-2e79-4e5f-a73d-48de60441376", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +340, +-120 +], +"parameters": { +"width": 340, +"height": 220, +"content": "The Email Reviewer agent, taking inspiration from human feedback, rewrites the email" +}, +"typeVersion": 1 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "de11da52-1513-4797-8070-b64e84b84158", +"connections": { +"Gmail": { +"main": [ +[ +{ +"node": "Text Classifier", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI": { +"ai_languageModel": [ +[ +{ +"node": "Write email", +"type": "ai_languageModel", +"index": 0 +}, +{ +"node": "Email Reviewer", +"type": "ai_languageModel", +"index": 0 +}, +{ +"node": "Text Classifier", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Markdown": { +"main": [ +[ +{ +"node": "Email Summarization Chain", +"type": "main", +"index": 0 +} +] +] +}, +"Get folder": { +"main": [ +[ +{ +"node": "Download Files", +"type": "main", +"index": 0 +} +] +] +}, +"Edit Fields": { +"main": [ +[ +{ +"node": "Gmail", +"type": "main", +"index": 0 +} +] +] +}, +"Write email": { +"main": [ +[ +{ +"node": "Edit Fields", +"type": "main", +"index": 0 +} +] +] +}, +"Download Files": { +"main": [ +[ +{ +"node": "Qdrant Vector Store1", +"type": "main", +"index": 0 +} +] +] +}, +"Email Reviewer": { +"main": [ +[ +{ +"node": "Edit Fields", +"type": "main", +"index": 0 +} +] +] +}, +"Token Splitter": { +"ai_textSplitter": [ +[ +{ +"node": "Default Data Loader", +"type": "ai_textSplitter", +"index": 0 +} +] +] +}, +"Text Classifier": { +"main": [ +[ +{ +"node": "Send Email", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Email Reviewer", +"type": "main", +"index": 0 +} +] +] +}, +"Embeddings OpenAI": { +"ai_embedding": [ +[ +{ +"node": "Qdrant Vector Store", +"type": "ai_embedding", +"index": 0 +} +] +] +}, +"Embeddings OpenAI1": { +"ai_embedding": [ +[ +{ +"node": "Qdrant Vector Store1", +"type": "ai_embedding", +"index": 0 +} +] +] +}, +"Refresh collection": { +"main": [ +[ +{ +"node": "Get folder", +"type": "main", +"index": 0 +} +] +] +}, +"DeepSeek Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Email Summarization Chain", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Default Data Loader": { +"ai_document": [ +[ +{ +"node": "Qdrant Vector Store1", +"type": "ai_document", +"index": 0 +} +] +] +}, +"Qdrant Vector Store": { +"ai_tool": [ +[ +{ +"node": "Write email", +"type": "ai_tool", +"index": 0 +}, +{ +"node": "Email Reviewer", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Email Trigger (IMAP)": { +"main": [ +[ +{ +"node": "Markdown", +"type": "main", +"index": 0 +} +] +] +}, +"Email Summarization Chain": { +"main": [ +[ +{ +"node": "Write email", +"type": "main", +"index": 0 +} +] +] +}, +"When clicking ‘Test workflow’": { +"main": [ +[ +{ +"node": "Create collection", +"type": "main", +"index": 0 +}, +{ +"node": "Refresh collection", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Email Subscription Service with n8n Forms, Airtable and AI (1).txt b/Email Subscription Service with n8n Forms, Airtable and AI (1).txt new file mode 100644 index 0000000..c268937 --- /dev/null +++ b/Email Subscription Service with n8n Forms, Airtable and AI (1).txt @@ -0,0 +1,1536 @@ +{ +"nodes": [ +{ +"id": "4dd52c72-9a9b-4db4-8de5-5b12b1e5c4be", +"name": "Schedule Trigger", +"type": "n8n-nodes-base.scheduleTrigger", +"position": [ +180, +1480 +], +"parameters": { +"rule": { +"interval": [ +{ +"triggerAtHour": 9 +} +] +} +}, +"typeVersion": 1.2 +}, +{ +"id": "9226181c-b84c-4ea1-a5b4-eedb6c62037b", +"name": "Search daily", +"type": "n8n-nodes-base.airtable", +"position": [ +440, +1480 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appL3dptT6ZTSzY9v", +"cachedResultUrl": "https://airtable.com/appL3dptT6ZTSzY9v", +"cachedResultName": "Scheduled Emails" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblzR9vSuFUzlQNMI", +"cachedResultUrl": "https://airtable.com/appL3dptT6ZTSzY9v/tblzR9vSuFUzlQNMI", +"cachedResultName": "Table 1" +}, +"options": {}, +"operation": "search", +"filterByFormula": "AND({Status} = 'active', {Interval} = 'daily')" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "1a3b6224-2f66-41c6-8b3d-be286cf16370", +"name": "Search weekly", +"type": "n8n-nodes-base.airtable", +"position": [ +440, +1660 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appL3dptT6ZTSzY9v", +"cachedResultUrl": "https://airtable.com/appL3dptT6ZTSzY9v", +"cachedResultName": "Scheduled Emails" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblzR9vSuFUzlQNMI", +"cachedResultUrl": "https://airtable.com/appL3dptT6ZTSzY9v/tblzR9vSuFUzlQNMI", +"cachedResultName": "Table 1" +}, +"options": {}, +"operation": "search", +"filterByFormula": "=AND(\n {Status} = 'active', \n {Interval} = 'weekly', \n {Last Sent} <= DATEADD(TODAY(), -7, 'days')\n)" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "1ea47e14-0a28-4780-95c7-31e24eb724d5", +"name": "confirmation email1", +"type": "n8n-nodes-base.gmail", +"position": [ +620, +820 +], +"webhookId": "dd8bd6df-2013-4f8d-a2cc-cd9b3913e3d2", +"parameters": { +"sendTo": "={{ $('Subscribe Form').item.json.email }}", +"message": "=This is to confirm your request to subscribe to \"Learn something every day!\" - a free service to send you facts about your favourite topics.\n\nTopic: {{ $('Subscribe Form').item.json.topic }}\nSchedule: {{ $('Subscribe Form').item.json.frequency }}", +"options": { +"appendAttribution": false +}, +"subject": "Learn something every day confirmation" +}, +"credentials": { +"gmailOAuth2": { +"id": "Sf5Gfl9NiFTNXFWb", +"name": "Gmail account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "d95262af-1b52-4f9c-8346-183b4eee8544", +"name": "Execute Workflow", +"type": "n8n-nodes-base.executeWorkflow", +"position": [ +1140, +1480 +], +"parameters": { +"mode": "each", +"options": { +"waitForSubWorkflow": false +}, +"workflowId": { +"__rl": true, +"mode": "id", +"value": "={{ $workflow.id }}" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "075292af-7a66-4275-ac2d-3c392189a10c", +"name": "Create Event", +"type": "n8n-nodes-base.set", +"position": [ +980, +1480 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "b28a0142-a028-471a-8180-9883e930feea", +"name": "email", +"type": "string", +"value": "={{ $json.Email }}" +}, +{ +"id": "970f5495-05df-42b6-a422-b2ac27f8eb95", +"name": "topic", +"type": "string", +"value": "={{ $json.Topic }}" +}, +{ +"id": "e871c431-948f-4b80-aa17-1e4266674663", +"name": "interval", +"type": "string", +"value": "={{ $json.Interval }}" +}, +{ +"id": "9b72597d-1446-4ef3-86e5-0a071c69155b", +"name": "id", +"type": "string", +"value": "={{ $json.id }}" +}, +{ +"id": "b17039c2-14a2-4811-9528-88ae963e44f7", +"name": "created_at", +"type": "string", +"value": "={{ $json.Created }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "28776aaf-6bd9-4f9f-bcf0-3d4401a74219", +"name": "Execute Workflow Trigger", +"type": "n8n-nodes-base.executeWorkflowTrigger", +"position": [ +1360, +1480 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "0eb62e75-228b-452b-80ab-f9ef3ad33204", +"name": "Unsubscribe Form", +"type": "n8n-nodes-base.formTrigger", +"position": [ +180, +1160 +], +"webhookId": "e64db96d-5e61-40d5-88fb-761621a829ab", +"parameters": { +"options": { +"path": "free-factoids-unsubscribe" +}, +"formTitle": "Unsubscribe from Learn Something Every Day", +"formFields": { +"values": [ +{ +"fieldLabel": "ID", +"requiredField": true +}, +{ +"fieldType": "dropdown", +"fieldLabel": "Reason For Unsubscribe", +"multiselect": true, +"fieldOptions": { +"values": [ +{ +"option": "Emails not relevant" +}, +{ +"option": "Too many Emails" +}, +{ +"option": "I did not sign up to this service" +} +] +} +} +] +}, +"formDescription": "We're sorry to see you go! Please take a moment to help us improve the service." +}, +"typeVersion": 2.2 +}, +{ +"id": "f889efe9-dc3c-428b-ad8e-4f7d17f23e75", +"name": "Set Email Vars", +"type": "n8n-nodes-base.set", +"position": [ +2500, +1480 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "62a684fb-16f9-4326-8eeb-777d604b305a", +"name": "to", +"type": "string", +"value": "={{ $('Execute Workflow Trigger').first().json.email }},jim@height.io" +}, +{ +"id": "4270849e-c805-4580-9088-e8d1c3ef2fb4", +"name": "subject", +"type": "string", +"value": "=Your {{ $('Execute Workflow Trigger').first().json.interval }} factoid" +}, +{ +"id": "81d0e897-2496-4a3c-b16c-9319338f899f", +"name": "message", +"type": "string", +"value": "=

\nYou asked about \"{{ $('Execution Data').first().json.topic.replace('\"','') }}\"\n

\n

\n{{ $('Content Generation Agent').first().json.output }}\n

" +}, +{ +"id": "ee05de7b-5342-4deb-8118-edaf235d92cc", +"name": "unsubscribe_link", +"type": "string", +"value": "=https:///form/inspiration-unsubscribe?ID={{ $('Execute Workflow Trigger').first().json.id }}" +} +] +}, +"includeOtherFields": true +}, +"typeVersion": 3.4 +}, +{ +"id": "84741e6d-f5be-440d-8633-4eb30ccce170", +"name": "Log Last Sent", +"type": "n8n-nodes-base.airtable", +"position": [ +2860, +1480 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appL3dptT6ZTSzY9v", +"cachedResultUrl": "https://airtable.com/appL3dptT6ZTSzY9v", +"cachedResultName": "Scheduled Emails" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblzR9vSuFUzlQNMI", +"cachedResultUrl": "https://airtable.com/appL3dptT6ZTSzY9v/tblzR9vSuFUzlQNMI", +"cachedResultName": "Table 1" +}, +"columns": { +"value": { +"id": "={{ $('Execute Workflow Trigger').first().json.id }}", +"Last Sent": "2024-11-29T13:34:11" +}, +"schema": [ +{ +"id": "id", +"type": "string", +"display": true, +"removed": false, +"readOnly": true, +"required": false, +"displayName": "id", +"defaultMatch": true +}, +{ +"id": "Name", +"type": "string", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Name", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Email", +"type": "string", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Email", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Status", +"type": "options", +"display": true, +"options": [ +{ +"name": "inactive", +"value": "inactive" +}, +{ +"name": "active", +"value": "active" +} +], +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Status", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Interval", +"type": "options", +"display": true, +"options": [ +{ +"name": "daily", +"value": "daily" +}, +{ +"name": "weekly", +"value": "weekly" +}, +{ +"name": "surprise", +"value": "surprise" +} +], +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Interval", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Start Day", +"type": "options", +"display": true, +"options": [ +{ +"name": "Mon", +"value": "Mon" +}, +{ +"name": "Tue", +"value": "Tue" +}, +{ +"name": "Wed", +"value": "Wed" +}, +{ +"name": "Thu", +"value": "Thu" +}, +{ +"name": "Fri", +"value": "Fri" +}, +{ +"name": "Sat", +"value": "Sat" +}, +{ +"name": "Sun", +"value": "Sun" +} +], +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Start Day", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Topic", +"type": "string", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Topic", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Created", +"type": "string", +"display": true, +"removed": true, +"readOnly": true, +"required": false, +"displayName": "Created", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Last Modified", +"type": "string", +"display": true, +"removed": true, +"readOnly": true, +"required": false, +"displayName": "Last Modified", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Last Sent", +"type": "dateTime", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Last Sent", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [ +"id" +] +}, +"options": {}, +"operation": "update" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "88f864d6-13fb-4f09-b22d-030d016678e1", +"name": "Search surprise", +"type": "n8n-nodes-base.airtable", +"position": [ +440, +1840 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appL3dptT6ZTSzY9v", +"cachedResultUrl": "https://airtable.com/appL3dptT6ZTSzY9v", +"cachedResultName": "Scheduled Emails" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblzR9vSuFUzlQNMI", +"cachedResultUrl": "https://airtable.com/appL3dptT6ZTSzY9v/tblzR9vSuFUzlQNMI", +"cachedResultName": "Table 1" +}, +"options": {}, +"operation": "search", +"filterByFormula": "=AND(\n {Status} = 'active', \n {Interval} = 'surprise'\n)" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "28238d9a-7bc0-4a22-bb4e-a7a2827e4da3", +"name": "Should Send = True", +"type": "n8n-nodes-base.filter", +"position": [ +800, +1840 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "9aaf9ae2-8f96-443a-8294-c04270296b22", +"operator": { +"type": "boolean", +"operation": "true", +"singleValue": true +}, +"leftValue": "={{ $json.should_send }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "3a46dd3d-48a6-40ca-8823-0516aa9f73a4", +"name": "Should Send?", +"type": "n8n-nodes-base.code", +"position": [ +620, +1840 +], +"parameters": { +"mode": "runOnceForEachItem", +"jsCode": "const luckyPick = Math.floor(Math.random() * 10) + 1;\n$input.item.json.should_send = luckyPick == 8;\nreturn $input.item;" +}, +"typeVersion": 2 +}, +{ +"id": "3611da19-920b-48e6-84a4-f7be0b3a78fc", +"name": "Create Subscriber", +"type": "n8n-nodes-base.airtable", +"position": [ +440, +820 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appL3dptT6ZTSzY9v", +"cachedResultUrl": "https://airtable.com/appL3dptT6ZTSzY9v", +"cachedResultName": "Scheduled Emails" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblzR9vSuFUzlQNMI", +"cachedResultUrl": "https://airtable.com/appL3dptT6ZTSzY9v/tblzR9vSuFUzlQNMI", +"cachedResultName": "Table 1" +}, +"columns": { +"value": { +"Email": "={{ $json.email }}", +"Topic": "={{ $json.topic }}", +"Status": "active", +"Interval": "={{ $json.frequency }}", +"Start Day": "={{ $json.submittedAt.toDateTime().format('EEE') }}" +}, +"schema": [ +{ +"id": "Name", +"type": "string", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Name", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Email", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Email", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Status", +"type": "options", +"display": true, +"options": [ +{ +"name": "inactive", +"value": "inactive" +}, +{ +"name": "active", +"value": "active" +} +], +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Status", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Interval", +"type": "options", +"display": true, +"options": [ +{ +"name": "daily", +"value": "daily" +}, +{ +"name": "weekly", +"value": "weekly" +}, +{ +"name": "surprise", +"value": "surprise" +} +], +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Interval", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Start Day", +"type": "options", +"display": true, +"options": [ +{ +"name": "Mon", +"value": "Mon" +}, +{ +"name": "Tue", +"value": "Tue" +}, +{ +"name": "Wed", +"value": "Wed" +}, +{ +"name": "Thu", +"value": "Thu" +}, +{ +"name": "Fri", +"value": "Fri" +}, +{ +"name": "Sat", +"value": "Sat" +}, +{ +"name": "Sun", +"value": "Sun" +} +], +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Start Day", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Topic", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Topic", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Created", +"type": "string", +"display": true, +"removed": true, +"readOnly": true, +"required": false, +"displayName": "Created", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Last Modified", +"type": "string", +"display": true, +"removed": true, +"readOnly": true, +"required": false, +"displayName": "Last Modified", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Last Sent", +"type": "dateTime", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Last Sent", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [ +"Email" +] +}, +"options": {}, +"operation": "upsert" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "2213a81f-53a9-4142-9586-e87b88710eec", +"name": "Update Subscriber", +"type": "n8n-nodes-base.airtable", +"position": [ +440, +1160 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appL3dptT6ZTSzY9v", +"cachedResultUrl": "https://airtable.com/appL3dptT6ZTSzY9v", +"cachedResultName": "Scheduled Emails" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblzR9vSuFUzlQNMI", +"cachedResultUrl": "https://airtable.com/appL3dptT6ZTSzY9v/tblzR9vSuFUzlQNMI", +"cachedResultName": "Table 1" +}, +"columns": { +"value": { +"id": "={{ $json.ID }}", +"Status": "inactive" +}, +"schema": [ +{ +"id": "id", +"type": "string", +"display": true, +"removed": false, +"readOnly": true, +"required": false, +"displayName": "id", +"defaultMatch": true +}, +{ +"id": "Name", +"type": "string", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Name", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Email", +"type": "string", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Email", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Status", +"type": "options", +"display": true, +"options": [ +{ +"name": "inactive", +"value": "inactive" +}, +{ +"name": "active", +"value": "active" +} +], +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Status", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Interval", +"type": "options", +"display": true, +"options": [ +{ +"name": "daily", +"value": "daily" +}, +{ +"name": "weekly", +"value": "weekly" +} +], +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Interval", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Start Day", +"type": "options", +"display": true, +"options": [ +{ +"name": "Mon", +"value": "Mon" +}, +{ +"name": "Tue", +"value": "Tue" +}, +{ +"name": "Wed", +"value": "Wed" +}, +{ +"name": "Thu", +"value": "Thu" +}, +{ +"name": "Fri", +"value": "Fri" +}, +{ +"name": "Sat", +"value": "Sat" +}, +{ +"name": "Sun", +"value": "Sun" +} +], +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Start Day", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Topic", +"type": "string", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Topic", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Created", +"type": "string", +"display": true, +"removed": true, +"readOnly": true, +"required": false, +"displayName": "Created", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Last Modified", +"type": "string", +"display": true, +"removed": true, +"readOnly": true, +"required": false, +"displayName": "Last Modified", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [ +"id" +] +}, +"options": {}, +"operation": "update" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "c94ec18b-e0cf-4859-8b89-23abdd63739c", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +900, +1280 +], +"parameters": { +"color": 7, +"width": 335, +"height": 173, +"content": "### 4. Using Subworkflows to run executions concurrently\nThis configuration is desired when sequential execution is slow and unnecessary. Also if one email fails, it doesn't fail the execution for everyone else." +}, +"typeVersion": 1 +}, +{ +"id": "c14cab28-13eb-4d91-8578-8187a95a8909", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +180, +700 +], +"parameters": { +"color": 7, +"width": 380, +"height": 80, +"content": "### 1. Subscribe flow\nUse a form to allow users to subscribe to the service." +}, +"typeVersion": 1 +}, +{ +"id": "0e44ada0-f8a7-440e-aded-33b446190a08", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +180, +1020 +], +"parameters": { +"color": 7, +"width": 355, +"height": 115, +"content": "### 2. Unsubscribe flow\n* Uses Form's pre-fill field feature to identify user\n* Doesn't use \"email\" as identifier so you can't unsubscribe others" +}, +"typeVersion": 1 +}, +{ +"id": "e67bdffe-ccfc-4818-990d-b2a5ab613035", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +180, +1340 +], +"parameters": { +"color": 7, +"width": 347, +"height": 114, +"content": "### 3. Scheduled Trigger\n* Runs every day at 9am\n* Handles all 3 frequency types\n* Send emails concurrently" +}, +"typeVersion": 1 +}, +{ +"id": "ce7d5310-7170-46d3-b8d8-3f97407f9dfd", +"name": "Subscribe Form", +"type": "n8n-nodes-base.formTrigger", +"position": [ +180, +820 +], +"webhookId": "c6abe3e3-ba87-4124-a227-84e253581b58", +"parameters": { +"options": { +"path": "free-factoids-subscribe", +"appendAttribution": false, +"respondWithOptions": { +"values": { +"formSubmittedText": "Thanks! Your factoid is on its way!" +} +} +}, +"formTitle": "Learn something every day!", +"formFields": { +"values": [ +{ +"fieldType": "textarea", +"fieldLabel": "topic", +"placeholder": "What topic(s) would you like to learn about?", +"requiredField": true +}, +{ +"fieldType": "email", +"fieldLabel": "email", +"placeholder": "eg. jim@example.com", +"requiredField": true +}, +{ +"fieldType": "dropdown", +"fieldLabel": "frequency", +"fieldOptions": { +"values": [ +{ +"option": "daily" +}, +{ +"option": "weekly" +}, +{ +"option": "surprise me" +} +] +}, +"requiredField": true +} +] +}, +"formDescription": "Get a fact a day (or week) about any subject sent to your inbox." +}, +"typeVersion": 2.2 +}, +{ +"id": "a5d50886-7d6b-4bf8-b376-b23c12a60608", +"name": "Execution Data", +"type": "n8n-nodes-base.executionData", +"position": [ +1560, +1480 +], +"parameters": { +"dataToSave": { +"values": [ +{ +"key": "email", +"value": "={{ $json.email }}" +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "69b40d8d-7734-47f1-89fe-9ea0378424b7", +"name": "Window Buffer Memory", +"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow", +"position": [ +1860, +1680 +], +"parameters": { +"sessionKey": "=scheduled_send_{{ $json.email }}", +"sessionIdType": "customKey" +}, +"typeVersion": 1.3 +}, +{ +"id": "f83cff18-f41f-4a63-9d43-7e3947aae386", +"name": "Wikipedia", +"type": "@n8n/n8n-nodes-langchain.toolWikipedia", +"position": [ +2020, +1680 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "77457037-e3ab-42f1-948b-b994d42f2f6e", +"name": "Content Generation Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +1780, +1460 +], +"parameters": { +"text": "=Generate an new factoid on the following topic: \"{{ $json.topic.replace('\"','') }}\"\nEnsure it is unique and not one generated previously.", +"options": {}, +"promptType": "define" +}, +"typeVersion": 1.7 +}, +{ +"id": "cdfdd870-48b6-4c7d-a7d1-a22d70423e37", +"name": "Groq Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatGroq", +"position": [ +1720, +1680 +], +"parameters": { +"model": "llama-3.3-70b-versatile", +"options": {} +}, +"credentials": { +"groqApi": { +"id": "02xZ4o87lUMUFmbT", +"name": "Groq account" +} +}, +"typeVersion": 1 +}, +{ +"id": "87df322d-a544-476f-b2ff-83feb619fe7f", +"name": "Generate Image", +"type": "@n8n/n8n-nodes-langchain.openAi", +"position": [ +2120, +1460 +], +"parameters": { +"prompt": "=Generate a child-friendly illustration which compliments the following paragraph:\n{{ $json.output }}", +"options": {}, +"resource": "image" +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1.7 +}, +{ +"id": "5c8d9e72-4015-44da-b5d5-829864d33672", +"name": "Resize Image", +"type": "n8n-nodes-base.editImage", +"position": [ +2280, +1460 +], +"parameters": { +"width": 480, +"height": 360, +"options": {}, +"operation": "resize" +}, +"typeVersion": 1 +}, +{ +"id": "a9939fad-98b3-4894-aae0-c11fa40d09da", +"name": "Send Message", +"type": "n8n-nodes-base.gmail", +"position": [ +2680, +1480 +], +"webhookId": "dd8bd6df-2013-4f8d-a2cc-cd9b3913e3d2", +"parameters": { +"sendTo": "={{ $json.to }}", +"message": "=\n\n\n \n \n {{ $json.subject }}\n\n\n {{ $json.message }}\n

\nUnsubscribe\n

\n\n\n", +"options": { +"attachmentsUi": { +"attachmentsBinary": [ +{} +] +}, +"appendAttribution": false +}, +"subject": "={{ $json.subject }}" +}, +"credentials": { +"gmailOAuth2": { +"id": "Sf5Gfl9NiFTNXFWb", +"name": "Gmail account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "10b6ad35-fc1c-47a2-b234-5de3557d1164", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1320, +1660 +], +"parameters": { +"color": 7, +"width": 335, +"height": 113, +"content": "### 5. Use Execution Data to Filter Logs\nIf you've registered for community+ or are on n8n cloud, best practice is to use execution node to allow filtering of execution logs." +}, +"typeVersion": 1 +}, +{ +"id": "e3563fae-ff35-457b-9fb1-784eda637518", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1780, +1280 +], +"parameters": { +"color": 7, +"width": 340, +"height": 140, +"content": "### 6. Use AI to Generate Factoid and Image\nUse an AI agent to automate the generation of factoids as requested by the user. This is a simple example but we recommend a adding a unique touch to stand out from the crowd!" +}, +"typeVersion": 1 +}, +{ +"id": "d1016c5d-c855-44c5-8ad3-a534bedaa8cf", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2500, +1040 +], +"parameters": { +"color": 7, +"width": 460, +"height": 400, +"content": "### 7. Send Email to User\nFinally, send a message to the user with both text and image.\nLog the event in the Airtable for later analysis if required.\n\n![Screenshot of email result](https://res.cloudinary.com/daglih2g8/image/upload/f_auto,q_auto/v1/n8n-workflows/dbpctdhohj3vlewy6oyc)" +}, +"typeVersion": 1 +}, +{ +"id": "773075fa-e5a2-4d4f-8527-eb07c7038b00", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-420, +680 +], +"parameters": { +"width": 480, +"height": 900, +"content": "## Try It Out!\n\n### This n8n templates demonstrates how to build a simple subscriber service entirely in n8n using n8n forms as a frontend, n8n generally as the backend and Airtable as the storage layer.\n\nThis template in particular shows a fully automated service to send automated messages containing facts about a topic the user requested for.\n\n### How it works\n* An n8n form is setup up to allow users to subscribe with a desired topic and interval of which to recieve messages via n8n forms which is then added to the Airtable.\n* A scheduled trigger is executed every morning and searches for subscribers to send messages for based on their desired intervals.\n* Once found, Subscribers are sent to a subworkflow which performs the text content generation via an AI agent and also uses a vision model to generate an image.\n* Both are attached to an email which is sent to the subscriber. This email also includes an unsubscribe link.\n* The unsubscribe flow works similarly via n8n form interface which when submitted disables further scheduled emails to the user.\n\n## How to use\n* Make a copy of sample Airtable here: https://airtable.com/appL3dptT6ZTSzY9v/shrLukHafy5bwDRfD\n* Make sure the workflow is \"activated\" and the forms are available and reachable by your audience.\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 +} +], +"pinData": {}, +"connections": { +"Wikipedia": { +"ai_tool": [ +[ +{ +"node": "Content Generation Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Create Event": { +"main": [ +[ +{ +"node": "Execute Workflow", +"type": "main", +"index": 0 +} +] +] +}, +"Resize Image": { +"main": [ +[ +{ +"node": "Set Email Vars", +"type": "main", +"index": 0 +} +] +] +}, +"Search daily": { +"main": [ +[ +{ +"node": "Create Event", +"type": "main", +"index": 0 +} +] +] +}, +"Send Message": { +"main": [ +[ +{ +"node": "Log Last Sent", +"type": "main", +"index": 0 +} +] +] +}, +"Should Send?": { +"main": [ +[ +{ +"node": "Should Send = True", +"type": "main", +"index": 0 +} +] +] +}, +"Search weekly": { +"main": [ +[ +{ +"node": "Create Event", +"type": "main", +"index": 0 +} +] +] +}, +"Execution Data": { +"main": [ +[ +{ +"node": "Content Generation Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Generate Image": { +"main": [ +[ +{ +"node": "Resize Image", +"type": "main", +"index": 0 +} +] +] +}, +"Set Email Vars": { +"main": [ +[ +{ +"node": "Send Message", +"type": "main", +"index": 0 +} +] +] +}, +"Subscribe Form": { +"main": [ +[ +{ +"node": "Create Subscriber", +"type": "main", +"index": 0 +} +] +] +}, +"Groq Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Content Generation Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Search surprise": { +"main": [ +[ +{ +"node": "Should Send?", +"type": "main", +"index": 0 +} +] +] +}, +"Schedule Trigger": { +"main": [ +[ +{ +"node": "Search surprise", +"type": "main", +"index": 0 +}, +{ +"node": "Search daily", +"type": "main", +"index": 0 +}, +{ +"node": "Search weekly", +"type": "main", +"index": 0 +} +] +] +}, +"Unsubscribe Form": { +"main": [ +[ +{ +"node": "Update Subscriber", +"type": "main", +"index": 0 +} +] +] +}, +"Create Subscriber": { +"main": [ +[ +{ +"node": "confirmation email1", +"type": "main", +"index": 0 +} +] +] +}, +"Should Send = True": { +"main": [ +[ +{ +"node": "Create Event", +"type": "main", +"index": 0 +} +] +] +}, +"Window Buffer Memory": { +"ai_memory": [ +[ +{ +"node": "Content Generation Agent", +"type": "ai_memory", +"index": 0 +} +] +] +}, +"Content Generation Agent": { +"main": [ +[ +{ +"node": "Generate Image", +"type": "main", +"index": 0 +} +] +] +}, +"Execute Workflow Trigger": { +"main": [ +[ +{ +"node": "Execution Data", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Email Subscription Service with n8n Forms, Airtable and AI.txt b/Email Subscription Service with n8n Forms, Airtable and AI.txt new file mode 100644 index 0000000..c268937 --- /dev/null +++ b/Email Subscription Service with n8n Forms, Airtable and AI.txt @@ -0,0 +1,1536 @@ +{ +"nodes": [ +{ +"id": "4dd52c72-9a9b-4db4-8de5-5b12b1e5c4be", +"name": "Schedule Trigger", +"type": "n8n-nodes-base.scheduleTrigger", +"position": [ +180, +1480 +], +"parameters": { +"rule": { +"interval": [ +{ +"triggerAtHour": 9 +} +] +} +}, +"typeVersion": 1.2 +}, +{ +"id": "9226181c-b84c-4ea1-a5b4-eedb6c62037b", +"name": "Search daily", +"type": "n8n-nodes-base.airtable", +"position": [ +440, +1480 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appL3dptT6ZTSzY9v", +"cachedResultUrl": "https://airtable.com/appL3dptT6ZTSzY9v", +"cachedResultName": "Scheduled Emails" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblzR9vSuFUzlQNMI", +"cachedResultUrl": "https://airtable.com/appL3dptT6ZTSzY9v/tblzR9vSuFUzlQNMI", +"cachedResultName": "Table 1" +}, +"options": {}, +"operation": "search", +"filterByFormula": "AND({Status} = 'active', {Interval} = 'daily')" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "1a3b6224-2f66-41c6-8b3d-be286cf16370", +"name": "Search weekly", +"type": "n8n-nodes-base.airtable", +"position": [ +440, +1660 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appL3dptT6ZTSzY9v", +"cachedResultUrl": "https://airtable.com/appL3dptT6ZTSzY9v", +"cachedResultName": "Scheduled Emails" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblzR9vSuFUzlQNMI", +"cachedResultUrl": "https://airtable.com/appL3dptT6ZTSzY9v/tblzR9vSuFUzlQNMI", +"cachedResultName": "Table 1" +}, +"options": {}, +"operation": "search", +"filterByFormula": "=AND(\n {Status} = 'active', \n {Interval} = 'weekly', \n {Last Sent} <= DATEADD(TODAY(), -7, 'days')\n)" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "1ea47e14-0a28-4780-95c7-31e24eb724d5", +"name": "confirmation email1", +"type": "n8n-nodes-base.gmail", +"position": [ +620, +820 +], +"webhookId": "dd8bd6df-2013-4f8d-a2cc-cd9b3913e3d2", +"parameters": { +"sendTo": "={{ $('Subscribe Form').item.json.email }}", +"message": "=This is to confirm your request to subscribe to \"Learn something every day!\" - a free service to send you facts about your favourite topics.\n\nTopic: {{ $('Subscribe Form').item.json.topic }}\nSchedule: {{ $('Subscribe Form').item.json.frequency }}", +"options": { +"appendAttribution": false +}, +"subject": "Learn something every day confirmation" +}, +"credentials": { +"gmailOAuth2": { +"id": "Sf5Gfl9NiFTNXFWb", +"name": "Gmail account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "d95262af-1b52-4f9c-8346-183b4eee8544", +"name": "Execute Workflow", +"type": "n8n-nodes-base.executeWorkflow", +"position": [ +1140, +1480 +], +"parameters": { +"mode": "each", +"options": { +"waitForSubWorkflow": false +}, +"workflowId": { +"__rl": true, +"mode": "id", +"value": "={{ $workflow.id }}" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "075292af-7a66-4275-ac2d-3c392189a10c", +"name": "Create Event", +"type": "n8n-nodes-base.set", +"position": [ +980, +1480 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "b28a0142-a028-471a-8180-9883e930feea", +"name": "email", +"type": "string", +"value": "={{ $json.Email }}" +}, +{ +"id": "970f5495-05df-42b6-a422-b2ac27f8eb95", +"name": "topic", +"type": "string", +"value": "={{ $json.Topic }}" +}, +{ +"id": "e871c431-948f-4b80-aa17-1e4266674663", +"name": "interval", +"type": "string", +"value": "={{ $json.Interval }}" +}, +{ +"id": "9b72597d-1446-4ef3-86e5-0a071c69155b", +"name": "id", +"type": "string", +"value": "={{ $json.id }}" +}, +{ +"id": "b17039c2-14a2-4811-9528-88ae963e44f7", +"name": "created_at", +"type": "string", +"value": "={{ $json.Created }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "28776aaf-6bd9-4f9f-bcf0-3d4401a74219", +"name": "Execute Workflow Trigger", +"type": "n8n-nodes-base.executeWorkflowTrigger", +"position": [ +1360, +1480 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "0eb62e75-228b-452b-80ab-f9ef3ad33204", +"name": "Unsubscribe Form", +"type": "n8n-nodes-base.formTrigger", +"position": [ +180, +1160 +], +"webhookId": "e64db96d-5e61-40d5-88fb-761621a829ab", +"parameters": { +"options": { +"path": "free-factoids-unsubscribe" +}, +"formTitle": "Unsubscribe from Learn Something Every Day", +"formFields": { +"values": [ +{ +"fieldLabel": "ID", +"requiredField": true +}, +{ +"fieldType": "dropdown", +"fieldLabel": "Reason For Unsubscribe", +"multiselect": true, +"fieldOptions": { +"values": [ +{ +"option": "Emails not relevant" +}, +{ +"option": "Too many Emails" +}, +{ +"option": "I did not sign up to this service" +} +] +} +} +] +}, +"formDescription": "We're sorry to see you go! Please take a moment to help us improve the service." +}, +"typeVersion": 2.2 +}, +{ +"id": "f889efe9-dc3c-428b-ad8e-4f7d17f23e75", +"name": "Set Email Vars", +"type": "n8n-nodes-base.set", +"position": [ +2500, +1480 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "62a684fb-16f9-4326-8eeb-777d604b305a", +"name": "to", +"type": "string", +"value": "={{ $('Execute Workflow Trigger').first().json.email }},jim@height.io" +}, +{ +"id": "4270849e-c805-4580-9088-e8d1c3ef2fb4", +"name": "subject", +"type": "string", +"value": "=Your {{ $('Execute Workflow Trigger').first().json.interval }} factoid" +}, +{ +"id": "81d0e897-2496-4a3c-b16c-9319338f899f", +"name": "message", +"type": "string", +"value": "=

\nYou asked about \"{{ $('Execution Data').first().json.topic.replace('\"','') }}\"\n

\n

\n{{ $('Content Generation Agent').first().json.output }}\n

" +}, +{ +"id": "ee05de7b-5342-4deb-8118-edaf235d92cc", +"name": "unsubscribe_link", +"type": "string", +"value": "=https:///form/inspiration-unsubscribe?ID={{ $('Execute Workflow Trigger').first().json.id }}" +} +] +}, +"includeOtherFields": true +}, +"typeVersion": 3.4 +}, +{ +"id": "84741e6d-f5be-440d-8633-4eb30ccce170", +"name": "Log Last Sent", +"type": "n8n-nodes-base.airtable", +"position": [ +2860, +1480 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appL3dptT6ZTSzY9v", +"cachedResultUrl": "https://airtable.com/appL3dptT6ZTSzY9v", +"cachedResultName": "Scheduled Emails" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblzR9vSuFUzlQNMI", +"cachedResultUrl": "https://airtable.com/appL3dptT6ZTSzY9v/tblzR9vSuFUzlQNMI", +"cachedResultName": "Table 1" +}, +"columns": { +"value": { +"id": "={{ $('Execute Workflow Trigger').first().json.id }}", +"Last Sent": "2024-11-29T13:34:11" +}, +"schema": [ +{ +"id": "id", +"type": "string", +"display": true, +"removed": false, +"readOnly": true, +"required": false, +"displayName": "id", +"defaultMatch": true +}, +{ +"id": "Name", +"type": "string", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Name", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Email", +"type": "string", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Email", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Status", +"type": "options", +"display": true, +"options": [ +{ +"name": "inactive", +"value": "inactive" +}, +{ +"name": "active", +"value": "active" +} +], +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Status", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Interval", +"type": "options", +"display": true, +"options": [ +{ +"name": "daily", +"value": "daily" +}, +{ +"name": "weekly", +"value": "weekly" +}, +{ +"name": "surprise", +"value": "surprise" +} +], +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Interval", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Start Day", +"type": "options", +"display": true, +"options": [ +{ +"name": "Mon", +"value": "Mon" +}, +{ +"name": "Tue", +"value": "Tue" +}, +{ +"name": "Wed", +"value": "Wed" +}, +{ +"name": "Thu", +"value": "Thu" +}, +{ +"name": "Fri", +"value": "Fri" +}, +{ +"name": "Sat", +"value": "Sat" +}, +{ +"name": "Sun", +"value": "Sun" +} +], +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Start Day", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Topic", +"type": "string", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Topic", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Created", +"type": "string", +"display": true, +"removed": true, +"readOnly": true, +"required": false, +"displayName": "Created", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Last Modified", +"type": "string", +"display": true, +"removed": true, +"readOnly": true, +"required": false, +"displayName": "Last Modified", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Last Sent", +"type": "dateTime", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Last Sent", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [ +"id" +] +}, +"options": {}, +"operation": "update" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "88f864d6-13fb-4f09-b22d-030d016678e1", +"name": "Search surprise", +"type": "n8n-nodes-base.airtable", +"position": [ +440, +1840 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appL3dptT6ZTSzY9v", +"cachedResultUrl": "https://airtable.com/appL3dptT6ZTSzY9v", +"cachedResultName": "Scheduled Emails" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblzR9vSuFUzlQNMI", +"cachedResultUrl": "https://airtable.com/appL3dptT6ZTSzY9v/tblzR9vSuFUzlQNMI", +"cachedResultName": "Table 1" +}, +"options": {}, +"operation": "search", +"filterByFormula": "=AND(\n {Status} = 'active', \n {Interval} = 'surprise'\n)" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "28238d9a-7bc0-4a22-bb4e-a7a2827e4da3", +"name": "Should Send = True", +"type": "n8n-nodes-base.filter", +"position": [ +800, +1840 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "9aaf9ae2-8f96-443a-8294-c04270296b22", +"operator": { +"type": "boolean", +"operation": "true", +"singleValue": true +}, +"leftValue": "={{ $json.should_send }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "3a46dd3d-48a6-40ca-8823-0516aa9f73a4", +"name": "Should Send?", +"type": "n8n-nodes-base.code", +"position": [ +620, +1840 +], +"parameters": { +"mode": "runOnceForEachItem", +"jsCode": "const luckyPick = Math.floor(Math.random() * 10) + 1;\n$input.item.json.should_send = luckyPick == 8;\nreturn $input.item;" +}, +"typeVersion": 2 +}, +{ +"id": "3611da19-920b-48e6-84a4-f7be0b3a78fc", +"name": "Create Subscriber", +"type": "n8n-nodes-base.airtable", +"position": [ +440, +820 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appL3dptT6ZTSzY9v", +"cachedResultUrl": "https://airtable.com/appL3dptT6ZTSzY9v", +"cachedResultName": "Scheduled Emails" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblzR9vSuFUzlQNMI", +"cachedResultUrl": "https://airtable.com/appL3dptT6ZTSzY9v/tblzR9vSuFUzlQNMI", +"cachedResultName": "Table 1" +}, +"columns": { +"value": { +"Email": "={{ $json.email }}", +"Topic": "={{ $json.topic }}", +"Status": "active", +"Interval": "={{ $json.frequency }}", +"Start Day": "={{ $json.submittedAt.toDateTime().format('EEE') }}" +}, +"schema": [ +{ +"id": "Name", +"type": "string", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Name", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Email", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Email", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Status", +"type": "options", +"display": true, +"options": [ +{ +"name": "inactive", +"value": "inactive" +}, +{ +"name": "active", +"value": "active" +} +], +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Status", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Interval", +"type": "options", +"display": true, +"options": [ +{ +"name": "daily", +"value": "daily" +}, +{ +"name": "weekly", +"value": "weekly" +}, +{ +"name": "surprise", +"value": "surprise" +} +], +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Interval", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Start Day", +"type": "options", +"display": true, +"options": [ +{ +"name": "Mon", +"value": "Mon" +}, +{ +"name": "Tue", +"value": "Tue" +}, +{ +"name": "Wed", +"value": "Wed" +}, +{ +"name": "Thu", +"value": "Thu" +}, +{ +"name": "Fri", +"value": "Fri" +}, +{ +"name": "Sat", +"value": "Sat" +}, +{ +"name": "Sun", +"value": "Sun" +} +], +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Start Day", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Topic", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Topic", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Created", +"type": "string", +"display": true, +"removed": true, +"readOnly": true, +"required": false, +"displayName": "Created", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Last Modified", +"type": "string", +"display": true, +"removed": true, +"readOnly": true, +"required": false, +"displayName": "Last Modified", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Last Sent", +"type": "dateTime", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Last Sent", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [ +"Email" +] +}, +"options": {}, +"operation": "upsert" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "2213a81f-53a9-4142-9586-e87b88710eec", +"name": "Update Subscriber", +"type": "n8n-nodes-base.airtable", +"position": [ +440, +1160 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appL3dptT6ZTSzY9v", +"cachedResultUrl": "https://airtable.com/appL3dptT6ZTSzY9v", +"cachedResultName": "Scheduled Emails" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblzR9vSuFUzlQNMI", +"cachedResultUrl": "https://airtable.com/appL3dptT6ZTSzY9v/tblzR9vSuFUzlQNMI", +"cachedResultName": "Table 1" +}, +"columns": { +"value": { +"id": "={{ $json.ID }}", +"Status": "inactive" +}, +"schema": [ +{ +"id": "id", +"type": "string", +"display": true, +"removed": false, +"readOnly": true, +"required": false, +"displayName": "id", +"defaultMatch": true +}, +{ +"id": "Name", +"type": "string", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Name", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Email", +"type": "string", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Email", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Status", +"type": "options", +"display": true, +"options": [ +{ +"name": "inactive", +"value": "inactive" +}, +{ +"name": "active", +"value": "active" +} +], +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Status", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Interval", +"type": "options", +"display": true, +"options": [ +{ +"name": "daily", +"value": "daily" +}, +{ +"name": "weekly", +"value": "weekly" +} +], +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Interval", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Start Day", +"type": "options", +"display": true, +"options": [ +{ +"name": "Mon", +"value": "Mon" +}, +{ +"name": "Tue", +"value": "Tue" +}, +{ +"name": "Wed", +"value": "Wed" +}, +{ +"name": "Thu", +"value": "Thu" +}, +{ +"name": "Fri", +"value": "Fri" +}, +{ +"name": "Sat", +"value": "Sat" +}, +{ +"name": "Sun", +"value": "Sun" +} +], +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Start Day", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Topic", +"type": "string", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Topic", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Created", +"type": "string", +"display": true, +"removed": true, +"readOnly": true, +"required": false, +"displayName": "Created", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Last Modified", +"type": "string", +"display": true, +"removed": true, +"readOnly": true, +"required": false, +"displayName": "Last Modified", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [ +"id" +] +}, +"options": {}, +"operation": "update" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "c94ec18b-e0cf-4859-8b89-23abdd63739c", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +900, +1280 +], +"parameters": { +"color": 7, +"width": 335, +"height": 173, +"content": "### 4. Using Subworkflows to run executions concurrently\nThis configuration is desired when sequential execution is slow and unnecessary. Also if one email fails, it doesn't fail the execution for everyone else." +}, +"typeVersion": 1 +}, +{ +"id": "c14cab28-13eb-4d91-8578-8187a95a8909", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +180, +700 +], +"parameters": { +"color": 7, +"width": 380, +"height": 80, +"content": "### 1. Subscribe flow\nUse a form to allow users to subscribe to the service." +}, +"typeVersion": 1 +}, +{ +"id": "0e44ada0-f8a7-440e-aded-33b446190a08", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +180, +1020 +], +"parameters": { +"color": 7, +"width": 355, +"height": 115, +"content": "### 2. Unsubscribe flow\n* Uses Form's pre-fill field feature to identify user\n* Doesn't use \"email\" as identifier so you can't unsubscribe others" +}, +"typeVersion": 1 +}, +{ +"id": "e67bdffe-ccfc-4818-990d-b2a5ab613035", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +180, +1340 +], +"parameters": { +"color": 7, +"width": 347, +"height": 114, +"content": "### 3. Scheduled Trigger\n* Runs every day at 9am\n* Handles all 3 frequency types\n* Send emails concurrently" +}, +"typeVersion": 1 +}, +{ +"id": "ce7d5310-7170-46d3-b8d8-3f97407f9dfd", +"name": "Subscribe Form", +"type": "n8n-nodes-base.formTrigger", +"position": [ +180, +820 +], +"webhookId": "c6abe3e3-ba87-4124-a227-84e253581b58", +"parameters": { +"options": { +"path": "free-factoids-subscribe", +"appendAttribution": false, +"respondWithOptions": { +"values": { +"formSubmittedText": "Thanks! Your factoid is on its way!" +} +} +}, +"formTitle": "Learn something every day!", +"formFields": { +"values": [ +{ +"fieldType": "textarea", +"fieldLabel": "topic", +"placeholder": "What topic(s) would you like to learn about?", +"requiredField": true +}, +{ +"fieldType": "email", +"fieldLabel": "email", +"placeholder": "eg. jim@example.com", +"requiredField": true +}, +{ +"fieldType": "dropdown", +"fieldLabel": "frequency", +"fieldOptions": { +"values": [ +{ +"option": "daily" +}, +{ +"option": "weekly" +}, +{ +"option": "surprise me" +} +] +}, +"requiredField": true +} +] +}, +"formDescription": "Get a fact a day (or week) about any subject sent to your inbox." +}, +"typeVersion": 2.2 +}, +{ +"id": "a5d50886-7d6b-4bf8-b376-b23c12a60608", +"name": "Execution Data", +"type": "n8n-nodes-base.executionData", +"position": [ +1560, +1480 +], +"parameters": { +"dataToSave": { +"values": [ +{ +"key": "email", +"value": "={{ $json.email }}" +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "69b40d8d-7734-47f1-89fe-9ea0378424b7", +"name": "Window Buffer Memory", +"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow", +"position": [ +1860, +1680 +], +"parameters": { +"sessionKey": "=scheduled_send_{{ $json.email }}", +"sessionIdType": "customKey" +}, +"typeVersion": 1.3 +}, +{ +"id": "f83cff18-f41f-4a63-9d43-7e3947aae386", +"name": "Wikipedia", +"type": "@n8n/n8n-nodes-langchain.toolWikipedia", +"position": [ +2020, +1680 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "77457037-e3ab-42f1-948b-b994d42f2f6e", +"name": "Content Generation Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +1780, +1460 +], +"parameters": { +"text": "=Generate an new factoid on the following topic: \"{{ $json.topic.replace('\"','') }}\"\nEnsure it is unique and not one generated previously.", +"options": {}, +"promptType": "define" +}, +"typeVersion": 1.7 +}, +{ +"id": "cdfdd870-48b6-4c7d-a7d1-a22d70423e37", +"name": "Groq Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatGroq", +"position": [ +1720, +1680 +], +"parameters": { +"model": "llama-3.3-70b-versatile", +"options": {} +}, +"credentials": { +"groqApi": { +"id": "02xZ4o87lUMUFmbT", +"name": "Groq account" +} +}, +"typeVersion": 1 +}, +{ +"id": "87df322d-a544-476f-b2ff-83feb619fe7f", +"name": "Generate Image", +"type": "@n8n/n8n-nodes-langchain.openAi", +"position": [ +2120, +1460 +], +"parameters": { +"prompt": "=Generate a child-friendly illustration which compliments the following paragraph:\n{{ $json.output }}", +"options": {}, +"resource": "image" +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1.7 +}, +{ +"id": "5c8d9e72-4015-44da-b5d5-829864d33672", +"name": "Resize Image", +"type": "n8n-nodes-base.editImage", +"position": [ +2280, +1460 +], +"parameters": { +"width": 480, +"height": 360, +"options": {}, +"operation": "resize" +}, +"typeVersion": 1 +}, +{ +"id": "a9939fad-98b3-4894-aae0-c11fa40d09da", +"name": "Send Message", +"type": "n8n-nodes-base.gmail", +"position": [ +2680, +1480 +], +"webhookId": "dd8bd6df-2013-4f8d-a2cc-cd9b3913e3d2", +"parameters": { +"sendTo": "={{ $json.to }}", +"message": "=\n\n\n \n \n {{ $json.subject }}\n\n\n {{ $json.message }}\n

\nUnsubscribe\n

\n\n\n", +"options": { +"attachmentsUi": { +"attachmentsBinary": [ +{} +] +}, +"appendAttribution": false +}, +"subject": "={{ $json.subject }}" +}, +"credentials": { +"gmailOAuth2": { +"id": "Sf5Gfl9NiFTNXFWb", +"name": "Gmail account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "10b6ad35-fc1c-47a2-b234-5de3557d1164", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1320, +1660 +], +"parameters": { +"color": 7, +"width": 335, +"height": 113, +"content": "### 5. Use Execution Data to Filter Logs\nIf you've registered for community+ or are on n8n cloud, best practice is to use execution node to allow filtering of execution logs." +}, +"typeVersion": 1 +}, +{ +"id": "e3563fae-ff35-457b-9fb1-784eda637518", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1780, +1280 +], +"parameters": { +"color": 7, +"width": 340, +"height": 140, +"content": "### 6. Use AI to Generate Factoid and Image\nUse an AI agent to automate the generation of factoids as requested by the user. This is a simple example but we recommend a adding a unique touch to stand out from the crowd!" +}, +"typeVersion": 1 +}, +{ +"id": "d1016c5d-c855-44c5-8ad3-a534bedaa8cf", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2500, +1040 +], +"parameters": { +"color": 7, +"width": 460, +"height": 400, +"content": "### 7. Send Email to User\nFinally, send a message to the user with both text and image.\nLog the event in the Airtable for later analysis if required.\n\n![Screenshot of email result](https://res.cloudinary.com/daglih2g8/image/upload/f_auto,q_auto/v1/n8n-workflows/dbpctdhohj3vlewy6oyc)" +}, +"typeVersion": 1 +}, +{ +"id": "773075fa-e5a2-4d4f-8527-eb07c7038b00", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-420, +680 +], +"parameters": { +"width": 480, +"height": 900, +"content": "## Try It Out!\n\n### This n8n templates demonstrates how to build a simple subscriber service entirely in n8n using n8n forms as a frontend, n8n generally as the backend and Airtable as the storage layer.\n\nThis template in particular shows a fully automated service to send automated messages containing facts about a topic the user requested for.\n\n### How it works\n* An n8n form is setup up to allow users to subscribe with a desired topic and interval of which to recieve messages via n8n forms which is then added to the Airtable.\n* A scheduled trigger is executed every morning and searches for subscribers to send messages for based on their desired intervals.\n* Once found, Subscribers are sent to a subworkflow which performs the text content generation via an AI agent and also uses a vision model to generate an image.\n* Both are attached to an email which is sent to the subscriber. This email also includes an unsubscribe link.\n* The unsubscribe flow works similarly via n8n form interface which when submitted disables further scheduled emails to the user.\n\n## How to use\n* Make a copy of sample Airtable here: https://airtable.com/appL3dptT6ZTSzY9v/shrLukHafy5bwDRfD\n* Make sure the workflow is \"activated\" and the forms are available and reachable by your audience.\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 +} +], +"pinData": {}, +"connections": { +"Wikipedia": { +"ai_tool": [ +[ +{ +"node": "Content Generation Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Create Event": { +"main": [ +[ +{ +"node": "Execute Workflow", +"type": "main", +"index": 0 +} +] +] +}, +"Resize Image": { +"main": [ +[ +{ +"node": "Set Email Vars", +"type": "main", +"index": 0 +} +] +] +}, +"Search daily": { +"main": [ +[ +{ +"node": "Create Event", +"type": "main", +"index": 0 +} +] +] +}, +"Send Message": { +"main": [ +[ +{ +"node": "Log Last Sent", +"type": "main", +"index": 0 +} +] +] +}, +"Should Send?": { +"main": [ +[ +{ +"node": "Should Send = True", +"type": "main", +"index": 0 +} +] +] +}, +"Search weekly": { +"main": [ +[ +{ +"node": "Create Event", +"type": "main", +"index": 0 +} +] +] +}, +"Execution Data": { +"main": [ +[ +{ +"node": "Content Generation Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Generate Image": { +"main": [ +[ +{ +"node": "Resize Image", +"type": "main", +"index": 0 +} +] +] +}, +"Set Email Vars": { +"main": [ +[ +{ +"node": "Send Message", +"type": "main", +"index": 0 +} +] +] +}, +"Subscribe Form": { +"main": [ +[ +{ +"node": "Create Subscriber", +"type": "main", +"index": 0 +} +] +] +}, +"Groq Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Content Generation Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Search surprise": { +"main": [ +[ +{ +"node": "Should Send?", +"type": "main", +"index": 0 +} +] +] +}, +"Schedule Trigger": { +"main": [ +[ +{ +"node": "Search surprise", +"type": "main", +"index": 0 +}, +{ +"node": "Search daily", +"type": "main", +"index": 0 +}, +{ +"node": "Search weekly", +"type": "main", +"index": 0 +} +] +] +}, +"Unsubscribe Form": { +"main": [ +[ +{ +"node": "Update Subscriber", +"type": "main", +"index": 0 +} +] +] +}, +"Create Subscriber": { +"main": [ +[ +{ +"node": "confirmation email1", +"type": "main", +"index": 0 +} +] +] +}, +"Should Send = True": { +"main": [ +[ +{ +"node": "Create Event", +"type": "main", +"index": 0 +} +] +] +}, +"Window Buffer Memory": { +"ai_memory": [ +[ +{ +"node": "Content Generation Agent", +"type": "ai_memory", +"index": 0 +} +] +] +}, +"Content Generation Agent": { +"main": [ +[ +{ +"node": "Generate Image", +"type": "main", +"index": 0 +} +] +] +}, +"Execute Workflow Trigger": { +"main": [ +[ +{ +"node": "Execution Data", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Email Summary Agent.txt b/Email Summary Agent.txt new file mode 100644 index 0000000..cd13716 --- /dev/null +++ b/Email Summary Agent.txt @@ -0,0 +1,311 @@ +{ +"id": "M8oLW9Qd59zNJzg2", +"meta": { +"instanceId": "1abe0e4c2be794795d12bf72aa530a426a6f87aabad209ed6619bcaf0f666fb0", +"templateCredsSetupCompleted": true +}, +"name": "Email Summary Agent", +"tags": [ +{ +"id": "G1v7CnFpOHsReVhM", +"name": "Product", +"createdAt": "2025-01-13T17:04:34.969Z", +"updatedAt": "2025-01-13T17:04:34.969Z" +}, +{ +"id": "RagrXIh5iBDseqvj", +"name": "AI", +"createdAt": "2025-01-09T09:18:12.756Z", +"updatedAt": "2025-01-09T09:18:12.756Z" +}, +{ +"id": "Yg2lfYteJZAoIeaC", +"name": "Building blocks", +"createdAt": "2025-01-13T17:05:49.788Z", +"updatedAt": "2025-01-13T17:05:49.788Z" +}, +{ +"id": "ZuS1C3NpE8uBlFq4", +"name": "Finance", +"createdAt": "2025-01-13T17:05:03.996Z", +"updatedAt": "2025-01-13T17:05:03.996Z" +}, +{ +"id": "aqlZb2qfWiaT4Xr5", +"name": "IT Ops", +"createdAt": "2025-01-03T12:20:11.917Z", +"updatedAt": "2025-01-03T12:20:11.917Z" +}, +{ +"id": "fX8hRnEv4D8sLSzF", +"name": "OpenAI", +"createdAt": "2025-01-09T09:18:12.757Z", +"updatedAt": "2025-01-09T09:18:12.757Z" +}, +{ +"id": "j1qBXzFADkR3sHSa", +"name": "Marketing", +"createdAt": "2025-01-13T17:03:54.468Z", +"updatedAt": "2025-01-13T17:03:54.468Z" +}, +{ +"id": "x3OVvOuZkLx1hYpW", +"name": "Support", +"createdAt": "2025-01-13T17:05:40.900Z", +"updatedAt": "2025-01-13T17:05:40.900Z" +}, +{ +"id": "xBOhq1kP3lza5ajE", +"name": "HR", +"createdAt": "2025-01-13T17:04:57.045Z", +"updatedAt": "2025-01-13T17:04:57.045Z" +}, +{ +"id": "yy04JQqCaXepPdSa", +"name": "Project Management", +"createdAt": "2024-10-30T18:27:57.309Z", +"updatedAt": "2024-10-30T18:27:57.309Z" +}, +{ +"id": "zJaZorWWcGpTp35U", +"name": "DevOps", +"createdAt": "2025-01-03T12:19:34.273Z", +"updatedAt": "2025-01-03T12:19:34.273Z" +} +], +"nodes": [ +{ +"id": "94c09c05-539b-452e-83b7-0a029bbe6b7f", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-120, +-140 +], +"parameters": { +"width": 248.47086922498647, +"height": 314.47468983163634, +"content": "- Starts the workflow every day at 7 AM.\n- Adjust the time if you want the workflow to run at a different hour." +}, +"typeVersion": 1 +}, +{ +"id": "5e5cbc87-5c01-438b-a1c0-e8468d3ee20b", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +160, +-137.04548301590512 +], +"parameters": { +"width": 213.36643278764896, +"height": 313.40934714314244, +"content": "Fetches all emails received in the past 24 hours from the email address" +}, +"typeVersion": 1 +}, +{ +"id": "9a82f5e9-7d0b-430f-9dbb-d8ae0b129dad", +"name": "Daily 7AM Trigger", +"type": "n8n-nodes-base.scheduleTrigger", +"position": [ +-40, +0 +], +"parameters": { +"rule": { +"interval": [ +{ +"triggerAtHour": 7 +} +] +} +}, +"typeVersion": 1.2 +}, +{ +"id": "dd3e4b10-187b-45ce-b999-f0143e5af134", +"name": "Fetch Emails - Past 24 Hours", +"type": "n8n-nodes-base.gmail", +"position": [ +220, +0 +], +"webhookId": "20f1d11d-8a69-43f3-9323-33eaf1b3b600", +"parameters": { +"filters": { +"q": "={{ \n (() => {\n const yesterday = new Date();\n yesterday.setDate(yesterday.getDate() - 1);\n return `isb.quantana@quantana.in after:${yesterday.getFullYear()}/${(yesterday.getMonth() + 1).toString().padStart(2, '0')}/${yesterday.getDate().toString().padStart(2, '0')}`;\n })()\n}}" +}, +"operation": "getAll", +"returnAll": true +}, +"credentials": { +"gmailOAuth2": { +"id": "YFARhQXJAjbwXjSO", +"name": "Vishal Gmail" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "4a8fdfd9-93d7-43a2-92b0-88d845f217bf", +"name": "Organize Email Data - Morning", +"type": "n8n-nodes-base.aggregate", +"position": [ +460, +0 +], +"parameters": { +"include": "specifiedFields", +"options": {}, +"aggregate": "aggregateAllItemData", +"fieldsToInclude": "id, From, To, CC, snippet" +}, +"typeVersion": 1 +}, +{ +"id": "9e2426e8-57ba-4708-b66f-b58bd19eabff", +"name": "Summarize Emails with OpenAI - Morning", +"type": "@n8n/n8n-nodes-langchain.openAi", +"position": [ +680, +0 +], +"parameters": { +"modelId": { +"__rl": true, +"mode": "list", +"value": "gpt-4o-mini", +"cachedResultName": "GPT-4O-MINI" +}, +"options": {}, +"messages": { +"values": [ +{ +"content": "=Go through this email summary and identify all key details mentioned, any specific issues to look at, and action items.\nUse this format to output\n{\n \"summary_of_emails\": [\n \"Point 1\",\n \"Point 2\",\n \"Point 3\"\n ],\n \"actions\": [\n {\n \"name\": \"Name 1\",\n \"action\": \"Action 1\"\n },\n {\n \"name\": \"Name 1\",\n \"action\": \"Action 2\"\n },\n {\n \"name\": \"Name 2\",\n \"action\": \"Action 3\"\n }\n ]\n}\n\nInput Data:\n\n {{ $json.data.toJsonString() }}\n\n" +} +] +}, +"jsonOutput": true +}, +"credentials": { +"openAiApi": { +"id": "ksU2WMcMqe2lPgRw", +"name": "OpenAi account" +} +}, +"typeVersion": 1.7 +}, +{ +"id": "4aa68ee8-d38f-418a-9f20-6cc76850c638", +"name": "Send Summary - Morning", +"type": "n8n-nodes-base.gmail", +"position": [ +1040, +0 +], +"webhookId": "83f2aeb9-7b6c-4336-b5ed-8acfcd259850", +"parameters": { +"sendTo": "team-email@example.com", +"message": "=\n\n\n \n \n Email Summary - isbonline@quantana.in\n \n\n\n
\n
\n

Email Summary

\n
\n
\n
\n

Summary of Emails:

\n
    \n {{ $json.message.content.summary_of_emails.map(email => `
  • ${email}
  • `).join('') }}\n
\n
\n
\n

Actions:

\n
    \n {{ $json.message.content.actions.map(action => `\n
  • \n ${action.name}:\n ${action.action}\n
  • \n `).join('') }}\n
\n
\n
\n
\n

Generated by Quantana ESAgent
A Quantana AI Labs Initiative\n

\n
\n\n", +"options": { +"ccList": "cc-list@example.com", +"appendAttribution": false, +"replyToSenderOnly": false +}, +"subject": "=ESAgent - {{ new Date(new Date().setDate(new Date().getDate() - 1)).toLocaleDateString('en-GB', { day: '2-digit', month: 'short', year: 'numeric' }) }}-00:00 to {{ new Date(new Date().setDate(new Date().getDate())).toLocaleDateString('en-GB', { day: '2-digit', month: 'short', year: 'numeric' }) }}-07:00AM" +}, +"credentials": { +"gmailOAuth2": { +"id": "YFARhQXJAjbwXjSO", +"name": "Vishal Gmail" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "c7667667-9533-40cb-9c09-914a11560600", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +400, +-132.6641804468672 +], +"parameters": { +"width": 226.7095107678671, +"height": 305.83657700487913, +"content": "Organizes the fetched email data, extracting fields like sender, receiver, CC, and a preview snippet." +}, +"typeVersion": 1 +}, +{ +"id": "43955af4-3a18-44d7-8c8d-cf8051b18bdd", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +980, +-180 +], +"parameters": { +"width": 232.8435827211592, +"height": 359.7308639651144, +"content": "- Sends the summarized email report to recipients with a styled HTML layout.\n- Update the \"sendTo\" and \"ccList\" fields with the email addresses of your recipients.\n\n" +}, +"typeVersion": 1 +} +], +"active": false, +"pinData": {}, +"settings": { +"timezone": "Asia/Kolkata", +"callerPolicy": "workflowsFromSameOwner", +"executionOrder": "v1" +}, +"versionId": "b18912ed-6c1f-4912-b75a-1553f7620917", +"connections": { +"Daily 7AM Trigger": { +"main": [ +[ +{ +"node": "Fetch Emails - Past 24 Hours", +"type": "main", +"index": 0 +} +] +] +}, +"Fetch Emails - Past 24 Hours": { +"main": [ +[ +{ +"node": "Organize Email Data - Morning", +"type": "main", +"index": 0 +} +] +] +}, +"Organize Email Data - Morning": { +"main": [ +[ +{ +"node": "Summarize Emails with OpenAI - Morning", +"type": "main", +"index": 0 +} +] +] +}, +"Summarize Emails with OpenAI - Morning": { +"main": [ +[ +{ +"node": "Send Summary - Morning", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Enhance Customer Chat by Buffering Messages with Twilio and Redis.txt b/Enhance Customer Chat by Buffering Messages with Twilio and Redis.txt new file mode 100644 index 0000000..2523856 --- /dev/null +++ b/Enhance Customer Chat by Buffering Messages with Twilio and Redis.txt @@ -0,0 +1,457 @@ +{ +"meta": { +"instanceId": "26ba763460b97c249b82942b23b6384876dfeb9327513332e743c5f6219c2b8e" +}, +"nodes": [ +{ +"id": "d61d8ff3-532a-4b0d-a5a7-e02d2e79ddce", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +2660, +480 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "b6d5c1cf-b4a1-4901-b001-0c375747ee63", +"name": "No Operation, do nothing", +"type": "n8n-nodes-base.noOp", +"position": [ +1660, +520 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "f4e08e32-bb96-4b5d-852e-26ad6fec3c8c", +"name": "Add to Messages Stack", +"type": "n8n-nodes-base.redis", +"position": [ +1340, +200 +], +"parameters": { +"list": "=chat-buffer:{{ $json.From }}", +"tail": true, +"operation": "push", +"messageData": "={{ $json.Body }}" +}, +"credentials": { +"redis": { +"id": "zU4DA70qSDrZM1El", +"name": "Redis account" +} +}, +"typeVersion": 1 +}, +{ +"id": "181ae99e-ebe7-4e99-b5a5-999acc249621", +"name": "Should Continue?", +"type": "n8n-nodes-base.if", +"position": [ +1660, +360 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "ec39573f-f92a-4fe4-a832-0a137de8e7d0", +"operator": { +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $('Get Latest Message Stack').item.json.messages.last() }}", +"rightValue": "={{ $('Twilio Trigger').item.json.Body }}" +} +] +} +}, +"typeVersion": 2 +}, +{ +"id": "640c63ca-2798-48a9-8484-b834c1a36301", +"name": "Window Buffer Memory", +"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow", +"position": [ +2780, +480 +], +"parameters": { +"sessionKey": "=chat-debouncer:{{ $('Twilio Trigger').item.json.From }}", +"sessionIdType": "customKey" +}, +"typeVersion": 1.2 +}, +{ +"id": "123c35c5-f7b2-4b4d-b220-0e5273e25115", +"name": "Twilio Trigger", +"type": "n8n-nodes-base.twilioTrigger", +"position": [ +940, +360 +], +"webhookId": "0ca3da0e-e4e1-4e94-8380-06207bf9b429", +"parameters": { +"updates": [ +"com.twilio.messaging.inbound-message.received" +] +}, +"credentials": { +"twilioApi": { +"id": "TJv4H4lXxPCLZT50", +"name": "Twilio account" +} +}, +"typeVersion": 1 +}, +{ +"id": "f4e86455-7f4d-4401-8f61-a859be1433a9", +"name": "Get Latest Message Stack", +"type": "n8n-nodes-base.redis", +"position": [ +1500, +360 +], +"parameters": { +"key": "=chat-buffer:{{ $json.From }}", +"keyType": "list", +"options": {}, +"operation": "get", +"propertyName": "messages" +}, +"credentials": { +"redis": { +"id": "zU4DA70qSDrZM1El", +"name": "Redis account" +} +}, +"typeVersion": 1, +"alwaysOutputData": false +}, +{ +"id": "02f8e7f5-12b4-4a5a-9ce9-5f0558e447aa", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1232.162872321277, +-50.203627749982275 +], +"parameters": { +"color": 7, +"width": 632.8309394802918, +"height": 766.7069233634998, +"content": "## Step 2. Buffer Incoming Messages\n[Learn more about using Redis](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.redis)\n\n* New messages are captured into a list.\n* After X seconds, we get a fresh copy of this list\n* If the last message on the list is the same as the incoming message, then we know no new follow-on messages were sent within the last 5 seconds. Hence the user should be waiting and it is safe to reply.\n* But if the reverse is true, then we will abort the execution here." +}, +"typeVersion": 1 +}, +{ +"id": "311c0d69-a735-4435-91b6-e80bf7d4c012", +"name": "Send Reply", +"type": "n8n-nodes-base.twilio", +"position": [ +3000, +320 +], +"parameters": { +"to": "={{ $('Twilio Trigger').item.json.From }}", +"from": "={{ $('Twilio Trigger').item.json.To }}", +"message": "={{ $json.output }}", +"options": {} +}, +"credentials": { +"twilioApi": { +"id": "TJv4H4lXxPCLZT50", +"name": "Twilio account" +} +}, +"typeVersion": 1 +}, +{ +"id": "c0e0cd08-66e3-4ca3-9441-8436c0d9e664", +"name": "Wait 5 seconds", +"type": "n8n-nodes-base.wait", +"position": [ +1340, +360 +], +"webhookId": "d486979c-8074-4ecb-958e-fcb24455086b", +"parameters": {}, +"typeVersion": 1.1 +}, +{ +"id": "c7959fa2-69a5-46b4-8e67-1ef824860f4e", +"name": "Get Chat History", +"type": "@n8n/n8n-nodes-langchain.memoryManager", +"position": [ +2000, +280 +], +"parameters": { +"options": { +"groupMessages": true +} +}, +"typeVersion": 1.1 +}, +{ +"id": "55933c54-5546-4770-8b36-a31496163528", +"name": "Window Buffer Memory1", +"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow", +"position": [ +2000, +420 +], +"parameters": { +"sessionKey": "=chat-debouncer:{{ $('Twilio Trigger').item.json.From }}", +"sessionIdType": "customKey" +}, +"typeVersion": 1.2 +}, +{ +"id": "459c0181-d239-4eec-88b6-c9603868d518", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +774.3250485705519, +198.07493876489747 +], +"parameters": { +"color": 7, +"width": 431.1629802181097, +"height": 357.49804533541777, +"content": "## Step 1. Listen for Twilio Messages\n[Read more about Twilio Trigger](https://docs.n8n.io/integrations/builtin/trigger-nodes/n8n-nodes-base.twiliotrigger)\n\nIn this example, we'll use the sender's phone number as the session ID. This will be important in retrieving chat history." +}, +"typeVersion": 1 +}, +{ +"id": "e06313a9-066a-4387-a36c-a6c6ff57d6f9", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1900, +80 +], +"parameters": { +"color": 7, +"width": 618.970917763344, +"height": 501.77420646931444, +"content": "## Step 3. Get Messages Since Last Reply\n[Read more about using Chat Memory](https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.memorymanager)\n\nOnce conditions are met and we allow the agent to reply, we'll need to find the bot's last reply and work out the buffer of user messages since then. We can do this by looking using chat memory and comparing this to the latest message in our redis messages stack." +}, +"typeVersion": 1 +}, +{ +"id": "601a71f6-c6f8-4b73-98c7-cfa11b1facaa", +"name": "Get Messages Buffer", +"type": "n8n-nodes-base.set", +"position": [ +2320, +280 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "01434acb-c224-46d2-99b0-7a81a2bb50c5", +"name": "messages", +"type": "string", +"value": "={{\n$('Get Latest Message Stack').item.json.messages\n .slice(\n $('Get Latest Message Stack').item.json.messages.lastIndexOf(\n $('Get Chat History').item.json.messages.last().human\n || $('Twilio Trigger').item.json.chatInput\n ),\n $('Get Latest Message Stack').item.json.messages.length\n )\n .join('\\n')\n}}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "9e49f2de-89e6-4152-8e9c-ed47c5fc4654", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2549, +120 +], +"parameters": { +"color": 7, +"width": 670.2274698011594, +"height": 522.5993538768389, +"content": "## Step 4. Send Single Agent Reply For Many Messages\n[Learn more about using AI Agents](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.agent)\n\nFinally, our buffered messages are sent to the AI Agent that can formulate a single response for all. This could potentially improve the conversation experience if the chat interaction is naturally more rapid and spontaneous. A drawback however is that responses could be feel much slower - tweak the wait threshold to suit your needs!" +}, +"typeVersion": 1 +}, +{ +"id": "be13c74a-467c-4ab1-acca-44878c68dba4", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +380, +80 +], +"parameters": { +"width": 375.55385425077225, +"height": 486.69228315530853, +"content": "## Try It Out!\n### This workflow demonstrates a simple approach to stagger an AI Agent's reply if users often send in a sequence of partial messages and in short bursts.\n\n* Twilio webhook receives user's messages which are recorded in a message stack powered by Redis.\n* The execution is immediately paused for 5 seconds and then another check is done against the message stack for the latest message.\n* The purpose of this check lets use know if the user is sending more messages or if they are waiting for a reply.\n* The execution is aborted if the latest message on the stack differs from the incoming message and continues if they are the same.\n* For the latter, the agent receives buffered messages and is able to respond to all in a single reply." +}, +"typeVersion": 1 +}, +{ +"id": "334d38e1-ec16-46f2-a57d-bf531adb8d3d", +"name": "AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +2660, +320 +], +"parameters": { +"text": "={{ $json.messages }}", +"agent": "conversationalAgent", +"options": {}, +"promptType": "define" +}, +"typeVersion": 1.6 +} +], +"pinData": {}, +"connections": { +"AI Agent": { +"main": [ +[ +{ +"node": "Send Reply", +"type": "main", +"index": 0 +} +] +] +}, +"Twilio Trigger": { +"main": [ +[ +{ +"node": "Add to Messages Stack", +"type": "main", +"index": 0 +}, +{ +"node": "Wait 5 seconds", +"type": "main", +"index": 0 +} +] +] +}, +"Wait 5 seconds": { +"main": [ +[ +{ +"node": "Get Latest Message Stack", +"type": "main", +"index": 0 +} +] +] +}, +"Get Chat History": { +"main": [ +[ +{ +"node": "Get Messages Buffer", +"type": "main", +"index": 0 +} +] +] +}, +"Should Continue?": { +"main": [ +[ +{ +"node": "Get Chat History", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "No Operation, do nothing", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Get Messages Buffer": { +"main": [ +[ +{ +"node": "AI Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Window Buffer Memory": { +"ai_memory": [ +[ +{ +"node": "AI Agent", +"type": "ai_memory", +"index": 0 +} +] +] +}, +"Window Buffer Memory1": { +"ai_memory": [ +[ +{ +"node": "Get Chat History", +"type": "ai_memory", +"index": 0 +} +] +] +}, +"Get Latest Message Stack": { +"main": [ +[ +{ +"node": "Should Continue?", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Enhance Security Operations with the Qualys Slack Shortcut Bot! (1).txt b/Enhance Security Operations with the Qualys Slack Shortcut Bot! (1).txt new file mode 100644 index 0000000..d8c2b86 --- /dev/null +++ b/Enhance Security Operations with the Qualys Slack Shortcut Bot! (1).txt @@ -0,0 +1,697 @@ +{ +"meta": { +"instanceId": "03e9d14e9196363fe7191ce21dc0bb17387a6e755dcc9acc4f5904752919dca8" +}, +"nodes": [ +{ +"id": "adfda9cb-1d77-4c54-b3ea-e7bf438a48af", +"name": "Parse Webhook", +"type": "n8n-nodes-base.set", +"position": [ +760, +640 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "e63f9299-a19d-4ba1-93b0-59f458769fb2", +"name": "response", +"type": "object", +"value": "={{ $json.body.payload }}" +} +] +} +}, +"typeVersion": 3.3 +}, +{ +"id": "b3e0e490-18e0-44b5-a960-0fdbf8422515", +"name": "Qualys Create Report", +"type": "n8n-nodes-base.executeWorkflow", +"position": [ +1720, +1740 +], +"parameters": { +"options": {}, +"workflowId": "icSLX102kSS9zNdK" +}, +"typeVersion": 1 +}, +{ +"id": "80ae074b-bda5-4638-b46f-246a1b9530ae", +"name": "Required Report Variables", +"type": "n8n-nodes-base.set", +"position": [ +1520, +1740 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "47cd1502-3039-4661-a6b1-e20a74056550", +"name": "report_title", +"type": "string", +"value": "={{ $json.response.view.state.values.report_title.report_title_input.value }}" +}, +{ +"id": "6a8a0cbf-bf3e-4702-956e-a35966d8b9c5", +"name": "base_url", +"type": "string", +"value": "https://qualysapi.qg3.apps.qualys.com" +}, +{ +"id": "9a15f4db-f006-4ad8-a2c0-4002dd3e2655", +"name": "output_format", +"type": "string", +"value": "={{ $json.response.view.state.values.output_format.output_format_select.selected_option.value }}" +}, +{ +"id": "13978e05-7e7f-42e9-8645-d28803db8cc9", +"name": "template_name", +"type": "string", +"value": "={{ $json.response.view.state.values.report_template.report_template_select.selected_option.text.text }}" +} +] +} +}, +"typeVersion": 3.3 +}, +{ +"id": "b596da86-02c7-4d8e-a267-88933f47ae0c", +"name": "Qualys Start Vulnerability Scan", +"type": "n8n-nodes-base.executeWorkflow", +"position": [ +1720, +1540 +], +"parameters": { +"options": {}, +"workflowId": "pYPh5FlGZgb36xZO" +}, +"typeVersion": 1 +}, +{ +"id": "61e39516-6558-46ce-a300-b4cbade7a6f6", +"name": "Scan Report Task Modal", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1620, +720 +], +"parameters": { +"url": "https://slack.com/api/views.open", +"method": "POST", +"options": {}, +"jsonBody": "= {\n \"trigger_id\": \"{{ $('Parse Webhook').item.json['response']['trigger_id'] }}\",\n \"external_id\": \"Scan Report Generator\",\n \"view\": {\n\t\"title\": {\n\t\t\"type\": \"plain_text\",\n\t\t\"text\": \"Scan Report Generator\",\n\t\t\"emoji\": true\n\t},\n\t\"submit\": {\n\t\t\"type\": \"plain_text\",\n\t\t\"text\": \"Generate Report\",\n\t\t\"emoji\": true\n\t},\n\t\"type\": \"modal\",\n\t\"close\": {\n\t\t\"type\": \"plain_text\",\n\t\t\"text\": \"Cancel\",\n\t\t\"emoji\": true\n\t},\n\t\"blocks\": [\n\t\t{\n\t\t\t\"type\": \"image\",\n\t\t\t\"image_url\": \"https://upload.wikimedia.org/wikipedia/commons/thumb/2/26/Logo-Qualys.svg/300px-Logo-Qualys.svg.png\",\n\t\t\t\"alt_text\": \"Qualys Logo\"\n\t\t},\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"text\": {\n\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\"text\": \"Select a template and generate a detailed scan report based on the results of your previous scans.\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"input\",\n\t\t\t\"block_id\": \"report_template\",\n\t\t\t\"element\": {\n\t\t\t\t\"type\": \"external_select\",\n\t\t\t\t\"placeholder\": {\n\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\"text\": \"Select a report template\",\n\t\t\t\t\t\"emoji\": true\n\t\t\t\t},\n\t\t\t\t\"action_id\": \"report_template_select\"\n\t\t\t},\n\t\t\t\"label\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Report Template\",\n\t\t\t\t\"emoji\": true\n\t\t\t},\n\t\t\t\"hint\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Choose a report template from your Qualys account to structure the output.\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"input\",\n\t\t\t\"block_id\": \"report_title\",\n\t\t\t\"element\": {\n\t\t\t\t\"type\": \"plain_text_input\",\n\t\t\t\t\"action_id\": \"report_title_input\",\n\t\t\t\t\"placeholder\": {\n\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\"text\": \"Enter a custom title for the report\"\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"label\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Report Title\",\n\t\t\t\t\"emoji\": true\n\t\t\t},\n\t\t\t\"hint\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Provide a descriptive title for your report. This title will be used in the report header.\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"input\",\n\t\t\t\"block_id\": \"output_format\",\n\t\t\t\"element\": {\n\t\t\t\t\"type\": \"static_select\",\n\t\t\t\t\"placeholder\": {\n\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\"text\": \"Select output format\",\n\t\t\t\t\t\"emoji\": true\n\t\t\t\t},\n\t\t\t\t\"options\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"text\": {\n\t\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\t\"text\": \"PDF\",\n\t\t\t\t\t\t\t\"emoji\": true\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"value\": \"pdf\"\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"text\": {\n\t\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\t\"text\": \"HTML\",\n\t\t\t\t\t\t\t\"emoji\": true\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"value\": \"html\"\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"text\": {\n\t\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\t\"text\": \"CSV\",\n\t\t\t\t\t\t\t\"emoji\": true\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"value\": \"csv\"\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"action_id\": \"output_format_select\"\n\t\t\t},\n\t\t\t\"label\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Output Format\",\n\t\t\t\t\"emoji\": true\n\t\t\t},\n\t\t\t\"hint\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Choose the format in which you want the report to be generated.\"\n\t\t\t}\n\t\t}\n\t]\n}\n}", +"sendBody": true, +"jsonQuery": "{\n \"Content-type\": \"application/json\"\n}", +"sendQuery": true, +"specifyBody": "json", +"specifyQuery": "json", +"authentication": "predefinedCredentialType", +"nodeCredentialType": "slackApi" +}, +"credentials": { +"slackApi": { +"id": "DZJDes1ZtGpqClNk", +"name": "Qualys Slack App" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "29cf716c-9cd6-4bd9-a0f9-c75baca86cc1", +"name": "Vuln Scan Modal", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1620, +560 +], +"parameters": { +"url": "https://slack.com/api/views.open", +"method": "POST", +"options": {}, +"jsonBody": "= {\n \"trigger_id\": \"{{ $('Parse Webhook').item.json['response']['trigger_id'] }}\",\n \"external_id\": \"Scan Report Generator\",\n \"view\": {\n\t\"title\": {\n\t\t\"type\": \"plain_text\",\n\t\t\"text\": \"Vulnerability Scan\",\n\t\t\"emoji\": true\n\t},\n\t\"submit\": {\n\t\t\"type\": \"plain_text\",\n\t\t\"text\": \"Execute Scan\",\n\t\t\"emoji\": true\n\t},\n\t\"type\": \"modal\",\n\t\"close\": {\n\t\t\"type\": \"plain_text\",\n\t\t\"text\": \"Cancel\",\n\t\t\"emoji\": true\n\t},\n\t\"blocks\": [\n\t\t{\n\t\t\t\"type\": \"image\",\n\t\t\t\"image_url\": \"https://upload.wikimedia.org/wikipedia/commons/thumb/2/26/Logo-Qualys.svg/300px-Logo-Qualys.svg.png\",\n\t\t\t\"alt_text\": \"Qualys Logo\"\n\t\t},\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"text\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Initiate a network-wide scan to detect and assess security vulnerabilities.\",\n\t\t\t\t\"emoji\": true\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"input\",\n\t\t\t\"block_id\": \"option_title\",\n\t\t\t\"element\": {\n\t\t\t\t\"type\": \"plain_text_input\",\n\t\t\t\t\"action_id\": \"text_input-action\",\n\t\t\t\t\"initial_value\": \"Initial Options\"\n\t\t\t},\n\t\t\t\"label\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Option Title\",\n\t\t\t\t\"emoji\": true\n\t\t\t},\n\t\t\t\"hint\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Specify the title of the option profile to use for the scan.\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"input\",\n\t\t\t\"block_id\": \"scan_title\",\n\t\t\t\"element\": {\n\t\t\t\t\"type\": \"plain_text_input\",\n\t\t\t\t\"action_id\": \"text_input-action\",\n\t\t\t\t\"placeholder\": {\n\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\"text\": \"Enter your scan title\"\n\t\t\t\t},\n\t\t\t\t\"initial_value\": \"n8n Scan 1\"\n\t\t\t},\n\t\t\t\"label\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Scan Title\",\n\t\t\t\t\"emoji\": true\n\t\t\t},\n\t\t\t\"hint\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Provide a descriptive title for the scan. Up to 2000 characters.\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"input\",\n\t\t\t\"block_id\": \"asset_groups\",\n\t\t\t\"element\": {\n\t\t\t\t\"type\": \"plain_text_input\",\n\t\t\t\t\"action_id\": \"text_input-action\",\n\t\t\t\t\"placeholder\": {\n\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\"text\": \"Enter asset groups\"\n\t\t\t\t},\n\t\t\t\t\"initial_value\": \"Group1\"\n\t\t\t},\n\t\t\t\"label\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Asset Groups\",\n\t\t\t\t\"emoji\": true\n\t\t\t},\n\t\t\t\"hint\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Specify asset group titles for targeting. Multiple titles must be comma-separated.\"\n\t\t\t}\n\t\t}\n\t]\n}\n}", +"sendBody": true, +"jsonQuery": "{\n \"Content-type\": \"application/json\"\n}", +"sendQuery": true, +"specifyBody": "json", +"specifyQuery": "json", +"authentication": "predefinedCredentialType", +"nodeCredentialType": "slackApi" +}, +"credentials": { +"slackApi": { +"id": "DZJDes1ZtGpqClNk", +"name": "Qualys Slack App" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "a771704d-4191-4e80-b62f-81b41b047a87", +"name": "Route Message", +"type": "n8n-nodes-base.switch", +"position": [ +940, +640 +], +"parameters": { +"rules": { +"values": [ +{ +"outputKey": "Vuln Scan Modal", +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"operator": { +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.response.callback_id }}", +"rightValue": "trigger-qualys-vmscan" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "Scan Report Modal", +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "02868fd8-2577-4c6d-af5e-a1963cb2f786", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.response.callback_id }}", +"rightValue": "qualys-scan-report" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "Process Submission", +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "c320c8b8-947b-433a-be82-d2aa96594808", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.response.type }}", +"rightValue": "view_submission" +} +] +}, +"renameOutput": true +} +] +}, +"options": { +"fallbackOutput": "none" +} +}, +"typeVersion": 3 +}, +{ +"id": "c8346d57-762a-4bbd-8d2b-f13097cb063d", +"name": "Required Scan Variables", +"type": "n8n-nodes-base.set", +"position": [ +1520, +1540 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "096ff32e-356e-4a85-aad2-01001d69dd46", +"name": "platformurl", +"type": "string", +"value": "https://qualysapi.qg3.apps.qualys.com" +}, +{ +"id": "070178a6-73b0-458b-8657-20ab4ff0485c", +"name": "option_title", +"type": "string", +"value": "={{ $json.response.view.state.values.option_title['text_input-action'].value }}" +}, +{ +"id": "3605424b-5bfc-44f0-b6e4-e0d6b1130b8e", +"name": "scan_title", +"type": "string", +"value": "={{ $json.response.view.state.values.scan_title['text_input-action'].value }}" +}, +{ +"id": "2320d966-b834-46fb-b674-be97cc08682e", +"name": "asset_groups", +"type": "string", +"value": "={{ $json.response.view.state.values.asset_groups['text_input-action'].value }}" +} +] +} +}, +"typeVersion": 3.3 +}, +{ +"id": "55589da9-50ce-4d55-a5ff-d62abdf65fa4", +"name": "Route Submission", +"type": "n8n-nodes-base.switch", +"position": [ +1240, +1140 +], +"parameters": { +"rules": { +"values": [ +{ +"outputKey": "Vuln Scan", +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"operator": { +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.response.view.title.text }}", +"rightValue": "Vulnerability Scan" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "Scan Report", +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "02868fd8-2577-4c6d-af5e-a1963cb2f786", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.response.view.title.text }}", +"rightValue": "Scan Report Generator" +} +] +}, +"renameOutput": true +} +] +}, +"options": { +"fallbackOutput": "none" +} +}, +"typeVersion": 3 +}, +{ +"id": "d0fc264d-0c48-4aa6-aeab-ed605d96f35a", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +428.3467548314237, +270.6382978723399 +], +"parameters": { +"color": 7, +"width": 466.8168310000617, +"height": 567.6433222116042, +"content": "![Imgur](https://uploads.n8n.io/templates/slack.png)\n## Events Webhook Trigger\nThe first node receives all messages from Slack API via Subscription Events API. You can find more information about setting up the subscription events API by [clicking here](https://api.slack.com/apis/connections/events-api). \n\nThe second node extracts the payload from slack into an object that n8n can understand. " +}, +"typeVersion": 1 +}, +{ +"id": "acb3fbdc-1fcb-4763-8529-ea2842607569", +"name": "Sticky Note15", +"type": "n8n-nodes-base.stickyNote", +"position": [ +900, +-32.762682645579616 +], +"parameters": { +"color": 7, +"width": 566.0553219408072, +"height": 1390.6748140207737, +"content": "![n8n](https://uploads.n8n.io/templates/n8n.png)\n## Efficient Slack Interaction Handling with n8n\n\nThis section of the workflow is designed to efficiently manage and route messages and submissions from Slack based on specific triggers and conditions. When a Slack interaction occurs—such as a user triggering a vulnerability scan or generating a report through a modal—the workflow intelligently routes the message to the appropriate action:\n\n- **Dynamic Routing**: Uses conditions to determine the nature of the Slack interaction, whether it's a direct command to initiate a scan or a request to generate a report.\n- **Modal Management**: Differentiates actions based on modal titles and `callback_id`s, ensuring that each type of submission is processed according to its context.\n- **Streamlined Responses**: After routing, the workflow promptly handles the necessary responses or actions, including closing modal popups and responding to Slack with appropriate confirmation or data.\n\n**Purpose**: This mechanism ensures that all interactions within Slack are handled quickly and accurately, automating responses and actions in real-time to enhance user experience and workflow efficiency." +}, +"typeVersion": 1 +}, +{ +"id": "85f370e8-70d2-466e-8f44-45eaf04a0d95", +"name": "Sticky Note11", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1473.6255461332685, +56.17183602125283 +], +"parameters": { +"color": 7, +"width": 396.6025898621133, +"height": 881.1659905894905, +"content": "![Imgur](https://uploads.n8n.io/templates/slack.png)\n## Display Modal Popup\nThis section pops open a modal window that is later used to send data into TheHive. \n\nModals can be customized to perform all sorts of actions. And they are natively mobile! You can see a screenshot of the Slack Modals on the right. \n\nLearn more about them by [clicking here](https://api.slack.com/surfaces/modals)" +}, +"typeVersion": 1 +}, +{ +"id": "cae79c1c-47f8-41c0-b1d0-e284359b52a8", +"name": "Sticky Note12", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1480, +960 +], +"parameters": { +"color": 7, +"width": 390.82613196003143, +"height": 950.1640646001949, +"content": "![Imgur](https://i.imgur.com/abGF8EO.png)\n## Modal Submission Payload\nThe data input into the Slack Modal makes its way into these set nodes that then pass that data into the Qualys Sub workflows that handle the heavy lifting. \n\n### Two Trigger Options\n- **Trigger a Vulnerability Scan** in the Slack UI which then sends a slack message to a channel of your choice summarizing and linking to the scan in slack\n- **Trigger report creation** in the Slack UI from the previously generated Vulnerability scan and upload a PDF copy of the report directly in a slack channel of your choice" +}, +"typeVersion": 1 +}, +{ +"id": "1017df8b-ff32-47aa-a4c2-a026e6597fa9", +"name": "Close Modal Popup", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +1000, +1140 +], +"parameters": { +"options": { +"responseCode": 204 +}, +"respondWith": "noData" +}, +"typeVersion": 1.1 +}, +{ +"id": "6b058f2a-2c0c-4326-aa42-08d840e306f7", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-260, +280 +], +"parameters": { +"width": 675.1724774900403, +"height": 972.8853473866498, +"content": "![n8n](https://uploads.n8n.io/templates/n8n.png)\n## Enhance Security Operations with the Qualys Slack Shortcut Bot!\n\nOur **Qualys Slack Shortcut Bot** is strategically designed to facilitate immediate security operations directly from Slack. This powerful tool allows users to initiate vulnerability scans and generate detailed reports through simple Slack interactions, streamlining the process of managing security assessments.\n\n**Workflow Highlights:**\n- **Interactive Modals**: Utilizes Slack modals to gather user inputs for scan configurations and report generation, providing a user-friendly interface for complex operations.\n- **Dynamic Workflow Execution**: Integrates seamlessly with Qualys to execute vulnerability scans and create reports based on user-specified parameters.\n- **Real-Time Feedback**: Offers instant feedback within Slack, updating users about the status of their requests and delivering reports directly through Slack channels.\n\n\n**Operational Flow:**\n- **Parse Webhook Data**: Captures and parses incoming data from Slack to understand user commands accurately.\n- **Execute Actions**: Depending on the user's selection, the workflow triggers other sub-workflows like 'Qualys Start Vulnerability Scan' or 'Qualys Create Report' for detailed processing.\n- **Respond to Slack**: Ensures that every interaction is acknowledged, maintaining a smooth user experience by managing modal popups and sending appropriate responses.\n\n\n**Setup Instructions:**\n- Verify that Slack and Qualys API integrations are correctly configured for seamless interaction.\n- Customize the modal interfaces to align with your organization's operational protocols and security policies.\n- Test the workflow to ensure that it responds accurately to Slack commands and that the integration with Qualys is functioning as expected.\n\n\n**Need Assistance?**\n- Explore our [Documentation](https://docs.qualys.com) or get help from the [n8n Community](https://community.n8n.io) for more detailed guidance on setup and customization.\n\nDeploy this bot within your Slack environment to significantly enhance the efficiency and responsiveness of your security operations, enabling proactive management of vulnerabilities and streamlined reporting." +}, +"typeVersion": 1 +}, +{ +"id": "63b537e8-50c9-479d-96a4-54e621689a23", +"name": "Webhook", +"type": "n8n-nodes-base.webhook", +"position": [ +520, +640 +], +"webhookId": "4f86c00d-ceb4-4890-84c5-850f8e5dec05", +"parameters": { +"path": "4f86c00d-ceb4-4890-84c5-850f8e5dec05", +"options": {}, +"httpMethod": "POST", +"responseMode": "responseNode" +}, +"typeVersion": 2 +}, +{ +"id": "13500444-f2ff-4b77-8f41-8ac52d067ec7", +"name": "Respond to Slack Webhook - Vulnerability", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +1280, +560 +], +"parameters": { +"options": {}, +"respondWith": "noData" +}, +"typeVersion": 1.1 +}, +{ +"id": "e64cedf0-948c-43c8-a62c-d0ec2916f3b6", +"name": "Respond to Slack Webhook - Report", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +1280, +720 +], +"parameters": { +"options": { +"responseCode": 200 +}, +"respondWith": "noData" +}, +"typeVersion": 1.1 +}, +{ +"id": "d2e53f7b-090a-4330-949d-d66ac0e5849c", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1494.8207799250774, +1400 +], +"parameters": { +"color": 5, +"width": 361.46312518523973, +"height": 113.6416448104651, +"content": "### 🙋 Remember to update your Slack Channels\nDon't forget to update the Slack Channels in the Slack nodes in these two subworkflows. \n" +}, +"typeVersion": 1 +}, +{ +"id": "2731f910-288f-497a-a71d-d840a63b2930", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1480, +400 +], +"parameters": { +"color": 5, +"width": 376.26546828439086, +"height": 113.6416448104651, +"content": "### 🙋 Don't forget your slack credentials!\nThankfully n8n makes it easy, as long as you've added credentials to a normal slack node, these http nodes are a snap to change via the drop down. " +}, +"typeVersion": 1 +}, +{ +"id": "72105959-ee9b-4ce6-a7f8-0f5f112c14d2", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1880, +500 +], +"parameters": { +"color": 5, +"width": 532.5097590794944, +"height": 671.013686767174, +"content": "![Imgur](https://uploads.n8n.io/templates/qualysscanreport.png)" +}, +"typeVersion": 1 +}, +{ +"id": "49b8ce63-cefd-483a-b802-03e3500d807b", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1880, +-200 +], +"parameters": { +"color": 5, +"width": 535.8333316661616, +"height": 658.907292269235, +"content": "![Imgur](https://uploads.n8n.io/templates/qualysmodalscan.png)" +}, +"typeVersion": 1 +}, +{ +"id": "3ec8c799-d5a5-4134-891a-59adb3e68e23", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +280, +-158.042446016207 +], +"parameters": { +"color": 5, +"width": 596.6847639718076, +"height": 422.00743613240917, +"content": "![Imgur](https://uploads.n8n.io/templates/qualysscanshortcut.png)\n### 🤖 Triggering this workflow is as easy as typing a backslash in Slack" +}, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"Webhook": { +"main": [ +[ +{ +"node": "Parse Webhook", +"type": "main", +"index": 0 +} +] +] +}, +"Parse Webhook": { +"main": [ +[ +{ +"node": "Route Message", +"type": "main", +"index": 0 +} +] +] +}, +"Route Message": { +"main": [ +[ +{ +"node": "Respond to Slack Webhook - Vulnerability", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Respond to Slack Webhook - Report", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Close Modal Popup", +"type": "main", +"index": 0 +} +] +] +}, +"Route Submission": { +"main": [ +[ +{ +"node": "Required Scan Variables", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Required Report Variables", +"type": "main", +"index": 0 +} +] +] +}, +"Close Modal Popup": { +"main": [ +[ +{ +"node": "Route Submission", +"type": "main", +"index": 0 +} +] +] +}, +"Required Scan Variables": { +"main": [ +[ +{ +"node": "Qualys Start Vulnerability Scan", +"type": "main", +"index": 0 +} +] +] +}, +"Required Report Variables": { +"main": [ +[ +{ +"node": "Qualys Create Report", +"type": "main", +"index": 0 +} +] +] +}, +"Respond to Slack Webhook - Report": { +"main": [ +[ +{ +"node": "Scan Report Task Modal", +"type": "main", +"index": 0 +} +] +] +}, +"Respond to Slack Webhook - Vulnerability": { +"main": [ +[ +{ +"node": "Vuln Scan Modal", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Enhance Security Operations with the Qualys Slack Shortcut Bot!.txt b/Enhance Security Operations with the Qualys Slack Shortcut Bot!.txt new file mode 100644 index 0000000..d8c2b86 --- /dev/null +++ b/Enhance Security Operations with the Qualys Slack Shortcut Bot!.txt @@ -0,0 +1,697 @@ +{ +"meta": { +"instanceId": "03e9d14e9196363fe7191ce21dc0bb17387a6e755dcc9acc4f5904752919dca8" +}, +"nodes": [ +{ +"id": "adfda9cb-1d77-4c54-b3ea-e7bf438a48af", +"name": "Parse Webhook", +"type": "n8n-nodes-base.set", +"position": [ +760, +640 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "e63f9299-a19d-4ba1-93b0-59f458769fb2", +"name": "response", +"type": "object", +"value": "={{ $json.body.payload }}" +} +] +} +}, +"typeVersion": 3.3 +}, +{ +"id": "b3e0e490-18e0-44b5-a960-0fdbf8422515", +"name": "Qualys Create Report", +"type": "n8n-nodes-base.executeWorkflow", +"position": [ +1720, +1740 +], +"parameters": { +"options": {}, +"workflowId": "icSLX102kSS9zNdK" +}, +"typeVersion": 1 +}, +{ +"id": "80ae074b-bda5-4638-b46f-246a1b9530ae", +"name": "Required Report Variables", +"type": "n8n-nodes-base.set", +"position": [ +1520, +1740 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "47cd1502-3039-4661-a6b1-e20a74056550", +"name": "report_title", +"type": "string", +"value": "={{ $json.response.view.state.values.report_title.report_title_input.value }}" +}, +{ +"id": "6a8a0cbf-bf3e-4702-956e-a35966d8b9c5", +"name": "base_url", +"type": "string", +"value": "https://qualysapi.qg3.apps.qualys.com" +}, +{ +"id": "9a15f4db-f006-4ad8-a2c0-4002dd3e2655", +"name": "output_format", +"type": "string", +"value": "={{ $json.response.view.state.values.output_format.output_format_select.selected_option.value }}" +}, +{ +"id": "13978e05-7e7f-42e9-8645-d28803db8cc9", +"name": "template_name", +"type": "string", +"value": "={{ $json.response.view.state.values.report_template.report_template_select.selected_option.text.text }}" +} +] +} +}, +"typeVersion": 3.3 +}, +{ +"id": "b596da86-02c7-4d8e-a267-88933f47ae0c", +"name": "Qualys Start Vulnerability Scan", +"type": "n8n-nodes-base.executeWorkflow", +"position": [ +1720, +1540 +], +"parameters": { +"options": {}, +"workflowId": "pYPh5FlGZgb36xZO" +}, +"typeVersion": 1 +}, +{ +"id": "61e39516-6558-46ce-a300-b4cbade7a6f6", +"name": "Scan Report Task Modal", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1620, +720 +], +"parameters": { +"url": "https://slack.com/api/views.open", +"method": "POST", +"options": {}, +"jsonBody": "= {\n \"trigger_id\": \"{{ $('Parse Webhook').item.json['response']['trigger_id'] }}\",\n \"external_id\": \"Scan Report Generator\",\n \"view\": {\n\t\"title\": {\n\t\t\"type\": \"plain_text\",\n\t\t\"text\": \"Scan Report Generator\",\n\t\t\"emoji\": true\n\t},\n\t\"submit\": {\n\t\t\"type\": \"plain_text\",\n\t\t\"text\": \"Generate Report\",\n\t\t\"emoji\": true\n\t},\n\t\"type\": \"modal\",\n\t\"close\": {\n\t\t\"type\": \"plain_text\",\n\t\t\"text\": \"Cancel\",\n\t\t\"emoji\": true\n\t},\n\t\"blocks\": [\n\t\t{\n\t\t\t\"type\": \"image\",\n\t\t\t\"image_url\": \"https://upload.wikimedia.org/wikipedia/commons/thumb/2/26/Logo-Qualys.svg/300px-Logo-Qualys.svg.png\",\n\t\t\t\"alt_text\": \"Qualys Logo\"\n\t\t},\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"text\": {\n\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\"text\": \"Select a template and generate a detailed scan report based on the results of your previous scans.\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"input\",\n\t\t\t\"block_id\": \"report_template\",\n\t\t\t\"element\": {\n\t\t\t\t\"type\": \"external_select\",\n\t\t\t\t\"placeholder\": {\n\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\"text\": \"Select a report template\",\n\t\t\t\t\t\"emoji\": true\n\t\t\t\t},\n\t\t\t\t\"action_id\": \"report_template_select\"\n\t\t\t},\n\t\t\t\"label\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Report Template\",\n\t\t\t\t\"emoji\": true\n\t\t\t},\n\t\t\t\"hint\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Choose a report template from your Qualys account to structure the output.\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"input\",\n\t\t\t\"block_id\": \"report_title\",\n\t\t\t\"element\": {\n\t\t\t\t\"type\": \"plain_text_input\",\n\t\t\t\t\"action_id\": \"report_title_input\",\n\t\t\t\t\"placeholder\": {\n\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\"text\": \"Enter a custom title for the report\"\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"label\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Report Title\",\n\t\t\t\t\"emoji\": true\n\t\t\t},\n\t\t\t\"hint\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Provide a descriptive title for your report. This title will be used in the report header.\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"input\",\n\t\t\t\"block_id\": \"output_format\",\n\t\t\t\"element\": {\n\t\t\t\t\"type\": \"static_select\",\n\t\t\t\t\"placeholder\": {\n\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\"text\": \"Select output format\",\n\t\t\t\t\t\"emoji\": true\n\t\t\t\t},\n\t\t\t\t\"options\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"text\": {\n\t\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\t\"text\": \"PDF\",\n\t\t\t\t\t\t\t\"emoji\": true\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"value\": \"pdf\"\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"text\": {\n\t\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\t\"text\": \"HTML\",\n\t\t\t\t\t\t\t\"emoji\": true\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"value\": \"html\"\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"text\": {\n\t\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\t\"text\": \"CSV\",\n\t\t\t\t\t\t\t\"emoji\": true\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"value\": \"csv\"\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"action_id\": \"output_format_select\"\n\t\t\t},\n\t\t\t\"label\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Output Format\",\n\t\t\t\t\"emoji\": true\n\t\t\t},\n\t\t\t\"hint\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Choose the format in which you want the report to be generated.\"\n\t\t\t}\n\t\t}\n\t]\n}\n}", +"sendBody": true, +"jsonQuery": "{\n \"Content-type\": \"application/json\"\n}", +"sendQuery": true, +"specifyBody": "json", +"specifyQuery": "json", +"authentication": "predefinedCredentialType", +"nodeCredentialType": "slackApi" +}, +"credentials": { +"slackApi": { +"id": "DZJDes1ZtGpqClNk", +"name": "Qualys Slack App" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "29cf716c-9cd6-4bd9-a0f9-c75baca86cc1", +"name": "Vuln Scan Modal", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1620, +560 +], +"parameters": { +"url": "https://slack.com/api/views.open", +"method": "POST", +"options": {}, +"jsonBody": "= {\n \"trigger_id\": \"{{ $('Parse Webhook').item.json['response']['trigger_id'] }}\",\n \"external_id\": \"Scan Report Generator\",\n \"view\": {\n\t\"title\": {\n\t\t\"type\": \"plain_text\",\n\t\t\"text\": \"Vulnerability Scan\",\n\t\t\"emoji\": true\n\t},\n\t\"submit\": {\n\t\t\"type\": \"plain_text\",\n\t\t\"text\": \"Execute Scan\",\n\t\t\"emoji\": true\n\t},\n\t\"type\": \"modal\",\n\t\"close\": {\n\t\t\"type\": \"plain_text\",\n\t\t\"text\": \"Cancel\",\n\t\t\"emoji\": true\n\t},\n\t\"blocks\": [\n\t\t{\n\t\t\t\"type\": \"image\",\n\t\t\t\"image_url\": \"https://upload.wikimedia.org/wikipedia/commons/thumb/2/26/Logo-Qualys.svg/300px-Logo-Qualys.svg.png\",\n\t\t\t\"alt_text\": \"Qualys Logo\"\n\t\t},\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"text\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Initiate a network-wide scan to detect and assess security vulnerabilities.\",\n\t\t\t\t\"emoji\": true\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"input\",\n\t\t\t\"block_id\": \"option_title\",\n\t\t\t\"element\": {\n\t\t\t\t\"type\": \"plain_text_input\",\n\t\t\t\t\"action_id\": \"text_input-action\",\n\t\t\t\t\"initial_value\": \"Initial Options\"\n\t\t\t},\n\t\t\t\"label\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Option Title\",\n\t\t\t\t\"emoji\": true\n\t\t\t},\n\t\t\t\"hint\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Specify the title of the option profile to use for the scan.\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"input\",\n\t\t\t\"block_id\": \"scan_title\",\n\t\t\t\"element\": {\n\t\t\t\t\"type\": \"plain_text_input\",\n\t\t\t\t\"action_id\": \"text_input-action\",\n\t\t\t\t\"placeholder\": {\n\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\"text\": \"Enter your scan title\"\n\t\t\t\t},\n\t\t\t\t\"initial_value\": \"n8n Scan 1\"\n\t\t\t},\n\t\t\t\"label\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Scan Title\",\n\t\t\t\t\"emoji\": true\n\t\t\t},\n\t\t\t\"hint\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Provide a descriptive title for the scan. Up to 2000 characters.\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"input\",\n\t\t\t\"block_id\": \"asset_groups\",\n\t\t\t\"element\": {\n\t\t\t\t\"type\": \"plain_text_input\",\n\t\t\t\t\"action_id\": \"text_input-action\",\n\t\t\t\t\"placeholder\": {\n\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\"text\": \"Enter asset groups\"\n\t\t\t\t},\n\t\t\t\t\"initial_value\": \"Group1\"\n\t\t\t},\n\t\t\t\"label\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Asset Groups\",\n\t\t\t\t\"emoji\": true\n\t\t\t},\n\t\t\t\"hint\": {\n\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\"text\": \"Specify asset group titles for targeting. Multiple titles must be comma-separated.\"\n\t\t\t}\n\t\t}\n\t]\n}\n}", +"sendBody": true, +"jsonQuery": "{\n \"Content-type\": \"application/json\"\n}", +"sendQuery": true, +"specifyBody": "json", +"specifyQuery": "json", +"authentication": "predefinedCredentialType", +"nodeCredentialType": "slackApi" +}, +"credentials": { +"slackApi": { +"id": "DZJDes1ZtGpqClNk", +"name": "Qualys Slack App" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "a771704d-4191-4e80-b62f-81b41b047a87", +"name": "Route Message", +"type": "n8n-nodes-base.switch", +"position": [ +940, +640 +], +"parameters": { +"rules": { +"values": [ +{ +"outputKey": "Vuln Scan Modal", +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"operator": { +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.response.callback_id }}", +"rightValue": "trigger-qualys-vmscan" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "Scan Report Modal", +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "02868fd8-2577-4c6d-af5e-a1963cb2f786", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.response.callback_id }}", +"rightValue": "qualys-scan-report" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "Process Submission", +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "c320c8b8-947b-433a-be82-d2aa96594808", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.response.type }}", +"rightValue": "view_submission" +} +] +}, +"renameOutput": true +} +] +}, +"options": { +"fallbackOutput": "none" +} +}, +"typeVersion": 3 +}, +{ +"id": "c8346d57-762a-4bbd-8d2b-f13097cb063d", +"name": "Required Scan Variables", +"type": "n8n-nodes-base.set", +"position": [ +1520, +1540 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "096ff32e-356e-4a85-aad2-01001d69dd46", +"name": "platformurl", +"type": "string", +"value": "https://qualysapi.qg3.apps.qualys.com" +}, +{ +"id": "070178a6-73b0-458b-8657-20ab4ff0485c", +"name": "option_title", +"type": "string", +"value": "={{ $json.response.view.state.values.option_title['text_input-action'].value }}" +}, +{ +"id": "3605424b-5bfc-44f0-b6e4-e0d6b1130b8e", +"name": "scan_title", +"type": "string", +"value": "={{ $json.response.view.state.values.scan_title['text_input-action'].value }}" +}, +{ +"id": "2320d966-b834-46fb-b674-be97cc08682e", +"name": "asset_groups", +"type": "string", +"value": "={{ $json.response.view.state.values.asset_groups['text_input-action'].value }}" +} +] +} +}, +"typeVersion": 3.3 +}, +{ +"id": "55589da9-50ce-4d55-a5ff-d62abdf65fa4", +"name": "Route Submission", +"type": "n8n-nodes-base.switch", +"position": [ +1240, +1140 +], +"parameters": { +"rules": { +"values": [ +{ +"outputKey": "Vuln Scan", +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"operator": { +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.response.view.title.text }}", +"rightValue": "Vulnerability Scan" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "Scan Report", +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "02868fd8-2577-4c6d-af5e-a1963cb2f786", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.response.view.title.text }}", +"rightValue": "Scan Report Generator" +} +] +}, +"renameOutput": true +} +] +}, +"options": { +"fallbackOutput": "none" +} +}, +"typeVersion": 3 +}, +{ +"id": "d0fc264d-0c48-4aa6-aeab-ed605d96f35a", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +428.3467548314237, +270.6382978723399 +], +"parameters": { +"color": 7, +"width": 466.8168310000617, +"height": 567.6433222116042, +"content": "![Imgur](https://uploads.n8n.io/templates/slack.png)\n## Events Webhook Trigger\nThe first node receives all messages from Slack API via Subscription Events API. You can find more information about setting up the subscription events API by [clicking here](https://api.slack.com/apis/connections/events-api). \n\nThe second node extracts the payload from slack into an object that n8n can understand. " +}, +"typeVersion": 1 +}, +{ +"id": "acb3fbdc-1fcb-4763-8529-ea2842607569", +"name": "Sticky Note15", +"type": "n8n-nodes-base.stickyNote", +"position": [ +900, +-32.762682645579616 +], +"parameters": { +"color": 7, +"width": 566.0553219408072, +"height": 1390.6748140207737, +"content": "![n8n](https://uploads.n8n.io/templates/n8n.png)\n## Efficient Slack Interaction Handling with n8n\n\nThis section of the workflow is designed to efficiently manage and route messages and submissions from Slack based on specific triggers and conditions. When a Slack interaction occurs—such as a user triggering a vulnerability scan or generating a report through a modal—the workflow intelligently routes the message to the appropriate action:\n\n- **Dynamic Routing**: Uses conditions to determine the nature of the Slack interaction, whether it's a direct command to initiate a scan or a request to generate a report.\n- **Modal Management**: Differentiates actions based on modal titles and `callback_id`s, ensuring that each type of submission is processed according to its context.\n- **Streamlined Responses**: After routing, the workflow promptly handles the necessary responses or actions, including closing modal popups and responding to Slack with appropriate confirmation or data.\n\n**Purpose**: This mechanism ensures that all interactions within Slack are handled quickly and accurately, automating responses and actions in real-time to enhance user experience and workflow efficiency." +}, +"typeVersion": 1 +}, +{ +"id": "85f370e8-70d2-466e-8f44-45eaf04a0d95", +"name": "Sticky Note11", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1473.6255461332685, +56.17183602125283 +], +"parameters": { +"color": 7, +"width": 396.6025898621133, +"height": 881.1659905894905, +"content": "![Imgur](https://uploads.n8n.io/templates/slack.png)\n## Display Modal Popup\nThis section pops open a modal window that is later used to send data into TheHive. \n\nModals can be customized to perform all sorts of actions. And they are natively mobile! You can see a screenshot of the Slack Modals on the right. \n\nLearn more about them by [clicking here](https://api.slack.com/surfaces/modals)" +}, +"typeVersion": 1 +}, +{ +"id": "cae79c1c-47f8-41c0-b1d0-e284359b52a8", +"name": "Sticky Note12", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1480, +960 +], +"parameters": { +"color": 7, +"width": 390.82613196003143, +"height": 950.1640646001949, +"content": "![Imgur](https://i.imgur.com/abGF8EO.png)\n## Modal Submission Payload\nThe data input into the Slack Modal makes its way into these set nodes that then pass that data into the Qualys Sub workflows that handle the heavy lifting. \n\n### Two Trigger Options\n- **Trigger a Vulnerability Scan** in the Slack UI which then sends a slack message to a channel of your choice summarizing and linking to the scan in slack\n- **Trigger report creation** in the Slack UI from the previously generated Vulnerability scan and upload a PDF copy of the report directly in a slack channel of your choice" +}, +"typeVersion": 1 +}, +{ +"id": "1017df8b-ff32-47aa-a4c2-a026e6597fa9", +"name": "Close Modal Popup", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +1000, +1140 +], +"parameters": { +"options": { +"responseCode": 204 +}, +"respondWith": "noData" +}, +"typeVersion": 1.1 +}, +{ +"id": "6b058f2a-2c0c-4326-aa42-08d840e306f7", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-260, +280 +], +"parameters": { +"width": 675.1724774900403, +"height": 972.8853473866498, +"content": "![n8n](https://uploads.n8n.io/templates/n8n.png)\n## Enhance Security Operations with the Qualys Slack Shortcut Bot!\n\nOur **Qualys Slack Shortcut Bot** is strategically designed to facilitate immediate security operations directly from Slack. This powerful tool allows users to initiate vulnerability scans and generate detailed reports through simple Slack interactions, streamlining the process of managing security assessments.\n\n**Workflow Highlights:**\n- **Interactive Modals**: Utilizes Slack modals to gather user inputs for scan configurations and report generation, providing a user-friendly interface for complex operations.\n- **Dynamic Workflow Execution**: Integrates seamlessly with Qualys to execute vulnerability scans and create reports based on user-specified parameters.\n- **Real-Time Feedback**: Offers instant feedback within Slack, updating users about the status of their requests and delivering reports directly through Slack channels.\n\n\n**Operational Flow:**\n- **Parse Webhook Data**: Captures and parses incoming data from Slack to understand user commands accurately.\n- **Execute Actions**: Depending on the user's selection, the workflow triggers other sub-workflows like 'Qualys Start Vulnerability Scan' or 'Qualys Create Report' for detailed processing.\n- **Respond to Slack**: Ensures that every interaction is acknowledged, maintaining a smooth user experience by managing modal popups and sending appropriate responses.\n\n\n**Setup Instructions:**\n- Verify that Slack and Qualys API integrations are correctly configured for seamless interaction.\n- Customize the modal interfaces to align with your organization's operational protocols and security policies.\n- Test the workflow to ensure that it responds accurately to Slack commands and that the integration with Qualys is functioning as expected.\n\n\n**Need Assistance?**\n- Explore our [Documentation](https://docs.qualys.com) or get help from the [n8n Community](https://community.n8n.io) for more detailed guidance on setup and customization.\n\nDeploy this bot within your Slack environment to significantly enhance the efficiency and responsiveness of your security operations, enabling proactive management of vulnerabilities and streamlined reporting." +}, +"typeVersion": 1 +}, +{ +"id": "63b537e8-50c9-479d-96a4-54e621689a23", +"name": "Webhook", +"type": "n8n-nodes-base.webhook", +"position": [ +520, +640 +], +"webhookId": "4f86c00d-ceb4-4890-84c5-850f8e5dec05", +"parameters": { +"path": "4f86c00d-ceb4-4890-84c5-850f8e5dec05", +"options": {}, +"httpMethod": "POST", +"responseMode": "responseNode" +}, +"typeVersion": 2 +}, +{ +"id": "13500444-f2ff-4b77-8f41-8ac52d067ec7", +"name": "Respond to Slack Webhook - Vulnerability", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +1280, +560 +], +"parameters": { +"options": {}, +"respondWith": "noData" +}, +"typeVersion": 1.1 +}, +{ +"id": "e64cedf0-948c-43c8-a62c-d0ec2916f3b6", +"name": "Respond to Slack Webhook - Report", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +1280, +720 +], +"parameters": { +"options": { +"responseCode": 200 +}, +"respondWith": "noData" +}, +"typeVersion": 1.1 +}, +{ +"id": "d2e53f7b-090a-4330-949d-d66ac0e5849c", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1494.8207799250774, +1400 +], +"parameters": { +"color": 5, +"width": 361.46312518523973, +"height": 113.6416448104651, +"content": "### 🙋 Remember to update your Slack Channels\nDon't forget to update the Slack Channels in the Slack nodes in these two subworkflows. \n" +}, +"typeVersion": 1 +}, +{ +"id": "2731f910-288f-497a-a71d-d840a63b2930", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1480, +400 +], +"parameters": { +"color": 5, +"width": 376.26546828439086, +"height": 113.6416448104651, +"content": "### 🙋 Don't forget your slack credentials!\nThankfully n8n makes it easy, as long as you've added credentials to a normal slack node, these http nodes are a snap to change via the drop down. " +}, +"typeVersion": 1 +}, +{ +"id": "72105959-ee9b-4ce6-a7f8-0f5f112c14d2", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1880, +500 +], +"parameters": { +"color": 5, +"width": 532.5097590794944, +"height": 671.013686767174, +"content": "![Imgur](https://uploads.n8n.io/templates/qualysscanreport.png)" +}, +"typeVersion": 1 +}, +{ +"id": "49b8ce63-cefd-483a-b802-03e3500d807b", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1880, +-200 +], +"parameters": { +"color": 5, +"width": 535.8333316661616, +"height": 658.907292269235, +"content": "![Imgur](https://uploads.n8n.io/templates/qualysmodalscan.png)" +}, +"typeVersion": 1 +}, +{ +"id": "3ec8c799-d5a5-4134-891a-59adb3e68e23", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +280, +-158.042446016207 +], +"parameters": { +"color": 5, +"width": 596.6847639718076, +"height": 422.00743613240917, +"content": "![Imgur](https://uploads.n8n.io/templates/qualysscanshortcut.png)\n### 🤖 Triggering this workflow is as easy as typing a backslash in Slack" +}, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"Webhook": { +"main": [ +[ +{ +"node": "Parse Webhook", +"type": "main", +"index": 0 +} +] +] +}, +"Parse Webhook": { +"main": [ +[ +{ +"node": "Route Message", +"type": "main", +"index": 0 +} +] +] +}, +"Route Message": { +"main": [ +[ +{ +"node": "Respond to Slack Webhook - Vulnerability", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Respond to Slack Webhook - Report", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Close Modal Popup", +"type": "main", +"index": 0 +} +] +] +}, +"Route Submission": { +"main": [ +[ +{ +"node": "Required Scan Variables", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Required Report Variables", +"type": "main", +"index": 0 +} +] +] +}, +"Close Modal Popup": { +"main": [ +[ +{ +"node": "Route Submission", +"type": "main", +"index": 0 +} +] +] +}, +"Required Scan Variables": { +"main": [ +[ +{ +"node": "Qualys Start Vulnerability Scan", +"type": "main", +"index": 0 +} +] +] +}, +"Required Report Variables": { +"main": [ +[ +{ +"node": "Qualys Create Report", +"type": "main", +"index": 0 +} +] +] +}, +"Respond to Slack Webhook - Report": { +"main": [ +[ +{ +"node": "Scan Report Task Modal", +"type": "main", +"index": 0 +} +] +] +}, +"Respond to Slack Webhook - Vulnerability": { +"main": [ +[ +{ +"node": "Vuln Scan Modal", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Enrich FAQ sections on your website pages at scale with AI.txt b/Enrich FAQ sections on your website pages at scale with AI.txt new file mode 100644 index 0000000..0031598 --- /dev/null +++ b/Enrich FAQ sections on your website pages at scale with AI.txt @@ -0,0 +1,1161 @@ +{ +"meta": { +"instanceId": "ff412ab2a6cd55af5dedbbab9b8e43f0f3a0cb16fb794fa8d3837f957b771ad2" +}, +"nodes": [ +{ +"id": "9c3c06eb-8b48-4229-9b16-7fe7c4f886c3", +"name": "When clicking ‘Test workflow’", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +78.44447107090468, +520 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "2a8d8297-18de-4e1f-b44b-93842f7c1709", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +1678.4444710709047, +2020 +], +"parameters": { +"model": "gpt-4o-mini", +"options": {} +}, +"typeVersion": 1 +}, +{ +"id": "a6c24857-ad3b-4561-b40b-8520064e861b", +"name": "Format QA Pair1", +"type": "n8n-nodes-base.set", +"position": [ +2018.4444710709047, +1880 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "2c1bd408-29f0-487b-9a33-7513d5bbfe23", +"name": "question", +"type": "string", +"value": "={{ $('Needs AI Completion?1').item.json.question }}" +}, +{ +"id": "02ffc3b7-3d77-4dfe-ba3f-2052f5cc9e83", +"name": "answer", +"type": "string", +"value": "={{\n[\n $('Needs AI Completion?1').item.json.answer,\n $json.text\n ? $json.text[0].toLowerCase() + $json.text.substring(1, $json.text.length)\n : '',\n $('Needs AI Completion?1').item.json.append || '',\n].join(' ').trim()\n}}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "2b4712cb-371c-45bc-a024-363ae951b0ac", +"name": "For Each Question...1", +"type": "n8n-nodes-base.splitInBatches", +"position": [ +1238.4444710709047, +1400 +], +"parameters": { +"options": {} +}, +"typeVersion": 3 +}, +{ +"id": "8f7cefc1-9fc0-474b-a81e-bf573068258b", +"name": "Question to List1", +"type": "n8n-nodes-base.splitOut", +"position": [ +1038.4444710709047, +1400 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "data" +}, +"typeVersion": 1 +}, +{ +"id": "9aeb5858-d6d4-4541-8a0d-851740d948ae", +"name": "Questions to Object...1", +"type": "n8n-nodes-base.aggregate", +"position": [ +1978.4444710709047, +1380 +], +"parameters": { +"options": {}, +"aggregate": "aggregateAllItemData" +}, +"typeVersion": 1 +}, +{ +"id": "2c1d56c5-20f2-4691-ab89-87edf9902a5f", +"name": "Format DisplayName + Questions1", +"type": "n8n-nodes-base.set", +"position": [ +2198.444471070905, +1380 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "66318f17-a3bd-4bcf-b326-50208b503143", +"name": "name", +"type": "string", +"value": "={{ $('Execute Workflow Trigger').first().json.data.displayName || $('Execute Workflow Trigger').first().json.data['Category name'] }}" +}, +{ +"id": "a83abac5-ddc6-4316-a916-7eab338f97cf", +"name": "questions", +"type": "array", +"value": "={{ $json.data }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "5147d5ef-f56d-49b0-9be8-0af7ccb8cdae", +"name": "Create From Text", +"type": "n8n-nodes-base.googleDrive", +"position": [ +2380, +1380 +], +"parameters": { +"name": "={{ $json.name + '-' + $now.format('yyyyMMdd') }}", +"content": "={{ JSON.stringify($json, null, 4) }}", +"driveId": { +"__rl": true, +"mode": "list", +"value": "" +}, +"options": {}, +"folderId": { +"__rl": true, +"mode": "id", +"value": "={{ $('Execute Workflow Trigger').first().json.outdir }}" +}, +"operation": "createFromText" +}, +"typeVersion": 3 +}, +{ +"id": "9abc3871-8103-4659-9afa-93142dabec01", +"name": "Define Sheets", +"type": "n8n-nodes-base.set", +"position": [ +518.4444710709047, +520 +], +"parameters": { +"mode": "raw", +"options": {}, +"jsonOutput": "{\n \"data\": [\n \"Single Integration Native\",\n \"Single Integration Cred-only\",\n \"Single Integration Non-native\",\n \"Categories\"\n ]\n}\n" +}, +"typeVersion": 3.4 +}, +{ +"id": "417b1c53-ec19-4f59-9580-b6080d3bc103", +"name": "Sheets To List...", +"type": "n8n-nodes-base.splitOut", +"position": [ +698.4444710709047, +520 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "data" +}, +"typeVersion": 1 +}, +{ +"id": "d8495ac2-7f45-4dd5-8eb5-d95c9e572dd3", +"name": "Get Services", +"type": "n8n-nodes-base.googleSheets", +"position": [ +1098.4444710709047, +660 +], +"parameters": { +"options": { +"returnAllMatches": "returnAllMatches" +}, +"filtersUI": { +"values": [ +{ +"lookupColumn": "=status" +} +] +}, +"sheetName": { +"__rl": true, +"mode": "name", +"value": "={{ $json.data }}" +}, +"documentId": { +"__rl": true, +"mode": "list", +"value": "" +} +}, +"typeVersion": 4.3, +"alwaysOutputData": true +}, +{ +"id": "e5b7ebe7-0e0f-4f61-8a14-afc51eb37270", +"name": "Single Integration Cred-only", +"type": "n8n-nodes-base.set", +"position": [ +778.4444710709047, +1400 +], +"parameters": { +"mode": "raw", +"options": {}, +"jsonOutput": "={\n \"data\": [\n {\n \"question\": \"How can I set up {{ $json.data.displayName }} integration in n8n?\",\n \"answer\": \"To use {{ $json.data.displayName }} integration in n8n, start by adding the HTTP Request node to your workflow canvas and authenticate it using a predefined credential type. This allows you to perform custom operations, without additional authentication setup. Once connected, you can make custom API calls to {{ $json.data.displayName }} to query the data you need using the URLs you provide, for example:\",\n \"ai_example\": \"Assume useris advanced in n8n integration and sending HTTP requests, focus instead on examples operations and/or use-cases such as creating records, updating records, or retrieving data.\",\n \"ai_completion\": {{ true }}\n },\n {\n \"question\": \"Do I need any special permissions or API keys to integrate {{ $json.data.displayName }} with n8n?\",\n \"answer\": \"Yes, you need an API key with the necessary permissions to integrate {{ $json.data.displayName }} with n8n. You will typically need to use the {{ $json.data.displayName }} API docs to construct your request via the HTTP Request node. Ensure the API key has the appropriate access rights for the data and actions you want to automate within your workflows.\",\n \"ai_completion\": {{ false }}\n },\n {\n \"question\": \"Can I combine {{ $json.data.displayName }} with other apps in n8n workflows?\",\n \"answer\": \"Definitely! n8n enables you to create workflows that combine {{ $json.data.displayName }} with other apps and services. For instance,\",\n \"ai_completion\": {{ true }}\n },\n {\n \"question\": \"What are some common use cases for {{ $json.data.displayName }} integrations with n8n?\",\n \"answer\": \"Common use cases for {{ $json.data.displayName }} automation include\",\n \"append\": \"With n8n, you can customize these workflows to fit your specific needs and extend them by adding other 400+ integrations or incorporating advanced AI logic.\",\n \"ai_completion\": {{ true }}\n },\n {\n \"question\": \"How does n8n’s pricing model benefit me when integrating {{ $json.data.displayName }}?\",\n \"answer\": \"n8n’s pricing model is designed to be both affordable and scalable, which is particularly beneficial when integrating with {{ $json.data.displayName }}. Unlike other platforms that charge per operation or task, n8n charges only for full workflow executions. This means you can create complex workflows with {{ $json.data.displayName }}, involving thousands of tasks or steps, without worrying about escalating costs. For example, if your {{ $json.data.displayName }} workflows perform around 100k tasks, you could be paying $500+/month on other platforms, but with n8n's pro plan, you start at around $50. This approach allows you to scale your {{ $json.data.displayName }} integrations efficiently while maintaining predictable costs.\",\n \"ai_completion\": {{ false }}\n }\n ]\n}" +}, +"typeVersion": 3.4 +}, +{ +"id": "e2cc607b-8502-4beb-ace5-8670af845134", +"name": "Single Integration Native", +"type": "n8n-nodes-base.set", +"position": [ +778.4444710709047, +1240 +], +"parameters": { +"mode": "raw", +"options": {}, +"jsonOutput": "={\n \"data\": [\n {\n \"question\": \"How can I set up {{ $json.data.displayName }} integration in n8n?\",\n \"answer\": \"To use {{ $json.data.displayName }} integration in n8n, start by adding the {{ $json.data.displayName }} node to your workflow. You'll need to authenticate your {{ $json.data.displayName }} account using supported authentication methods. Once connected, you can choose from the list of supported actions or make custom API calls via the HTTP Request node, for example:\",\n \"ai_completion\": {{ true }}\n },\n {\n \"question\": \"Do I need any special permissions or API keys to integrate {{ $json.data.displayName }} with n8n?\",\n \"answer\": \"Yes, you will typically need an API key, token, or similar credentials to add {{ $json.data.displayName }} integration to n8n. These can usually be found in your account settings for the service. Ensure that your credentials have the necessary permissions to access and manage the data or actions you want to automate within your workflows.\",\n \"ai_completion\": {{ false }}\n },\n {\n \"question\": \"Can I combine {{ $json.data.displayName }} with other apps in n8n workflows?\",\n \"answer\": \"Definitely! n8n enables you to create workflows that combine {{ $json.data.displayName }} with other apps and services. For instance,\",\n \"ai_completion\": {{ true }}\n },\n {\n \"question\": \"What are some common use cases for {{ $json.data.displayName }} integrations with n8n?\",\n \"answer\": \"Common use cases for {{ $json.data.displayName }} automation include\",\n \"append\": \"With n8n, you can customize these workflows to fit your specific needs and extend them by adding other 400+ integrations or incorporating advanced AI logic.\",\n \"ai_completion\": {{ true }}\n },\n {\n \"question\": \"How does n8n’s pricing model benefit me when integrating {{ $json.data.displayName }}?\",\n \"answer\": \"n8n’s pricing model is designed to be both affordable and scalable, which is particularly beneficial when integrating with {{ $json.data.displayName }}. Unlike other platforms that charge per operation or task, n8n charges only for full workflow executions. This means you can create complex workflows with {{ $json.data.displayName }}, involving thousands of tasks or steps, without worrying about escalating costs. For example, if your {{ $json.data.displayName }} workflows perform around 100k tasks, you could be paying $500+/month on other platforms, but with n8n's pro plan, you start at around $50. This approach allows you to scale your {{ $json.data.displayName }} integrations efficiently while maintaining predictable costs.\",\n \"ai_completion\": {{ false }}\n }\n ]\n}" +}, +"typeVersion": 3.4 +}, +{ +"id": "ce1905c2-f41a-4dea-bd03-a9ae1e893326", +"name": "Categories", +"type": "n8n-nodes-base.set", +"position": [ +778.4444710709047, +1760 +], +"parameters": { +"mode": "raw", +"options": {}, +"jsonOutput": "={{\n{\n \"data\": [\n {\n \"question\": `What types of ${$json.data['Category name']} tools can I integrate with n8n?`,\n \"answer\": `n8n offers integrations with a wide range of ${$json.data['Category name']} tools, including`,\n \"append\": `These integrations allow you to streamline your ${$json.data['Category name']} workflows, automate repetitive tasks, and improve collaboration across your team.`,\n \"ai_completion\": true\n },\n {\n \"question\": `Are there any specific requirements or limitations for using ${$json.data['Category name']} integrations?`,\n \"answer\": `Yes, each ${$json.data['Category name']} integration may have specific requirements. For example,`,\n \"append\": `n8n offers a significant number of pre-built ${$json.data['Category name']} integrations (called nodes). If n8n doesn't support the integration you need, use the HTTP Request node or custom code to connect to the service's API. Be sure to review the integration documentation for any app-specific prerequisites. Additionally, consider any API rate limits or usage constraints that might affect your workflows.`,\n \"ai_completion\": true\n },\n {\n \"question\": `What are some popular use cases for ${$json.data['Category name']} integrations in n8n?`,\n \"answer\": `${$json.data['Category name']} integrations with n8n offer a variety of practical use cases. For example:`,\n \"ai_completion\": true,\n \"ai_completion_format\": \"list\"\n },\n {\n \"question\": `How does n8n’s pricing model benefit ${$json.data['Category name']} workflows?`,\n \"answer\": `n8n's pricing model, which charges only for full workflow executions rather than individual tasks or steps, is particularly advantageous for ${$json.data['Category name']} workflows. This means you can build complex, multi-step workflows involving various ${$json.data['Category name']} tools without worrying about cost increases due to the number of operations. For example, if your ${$json.data['Category name']} workflows perform around 100k tasks, you could be paying $500+/month on other platforms, but with n8n's pro plan, you start at around $50. This approach allows you to scale your ${$json.data['Category name']} integrations efficiently while maintaining predictable costs.`,\n \"ai_completion\": false\n },\n {\n \"question\": `How can I leverage n8n's AI capabilities in my ${$json.data['Category name']} workflows?`,\n \"answer\": `n8n offers powerful AI capabilities that can enhance your ${$json.data['Category name']} workflows. For example, you can integrate AI tools like OpenAI with n8n to`,\n \"append\": `To add AI capabilities, navigate to the AI category in n8n's integrations directory and set up the integration with your chosen AI service. This combination of AI and ${$json.data['Category name']} integrations can significantly boost your development efficiency and innovation.`,\n \"ai_completion\": true\n }\n ]\n}\n}}" +}, +"typeVersion": 3.4 +}, +{ +"id": "344c93e6-3ed9-4dd0-8a38-c2f853ef3cc1", +"name": "For Each Sheet...", +"type": "n8n-nodes-base.splitInBatches", +"position": [ +918.4444710709047, +520 +], +"parameters": { +"options": {} +}, +"typeVersion": 3 +}, +{ +"id": "e5776c79-51e4-4469-8cf7-dff009ee0ffd", +"name": "Execute Workflow Trigger", +"type": "n8n-nodes-base.executeWorkflowTrigger", +"position": [ +298.4444710709047, +1400 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "76aca3a6-c3ff-41fa-9fdf-30839df85669", +"name": "Execute Workflow", +"type": "n8n-nodes-base.executeWorkflow", +"position": [ +1898.4444710709047, +660 +], +"parameters": { +"mode": "each", +"options": {}, +"workflowId": "={{ $workflow.id }}" +}, +"typeVersion": 1, +"alwaysOutputData": true +}, +{ +"id": "663b1ce2-ccb5-43d1-8871-c5fa7412151c", +"name": "Prepare Job", +"type": "n8n-nodes-base.set", +"position": [ +1278.4444710709047, +660 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "2755153b-d38c-4aba-be8f-f72c3bf91cf2", +"name": "sheet", +"type": "string", +"value": "={{ $('For Each Sheet...').item.json.data }}" +}, +{ +"id": "eed4a03a-451b-4b74-b591-ce970d84f990", +"name": "data", +"type": "object", +"value": "={{ $json }}" +}, +{ +"id": "ee73316c-0316-4389-aa13-4bb145637262", +"name": "outdir", +"type": "string", +"value": "={{\n{\n \"Single Integration Native\": \"Insert the corresponding Google Drive folder ID here\",\n \"Single Integration Cred-only\": \"Insert the corresponding Google Drive folder ID here\",\n \"Single Integration Non-native\": \"Insert the corresponding Google Drive folder ID here\",\n \"Categories\": \"Insert the corresponding Google Drive folder ID here\",\n}[$('For Each Sheet...').item.json.data]\n}}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "087249d0-d001-49c3-8695-e0e3f02b66e2", +"name": "For Each Service...", +"type": "n8n-nodes-base.splitInBatches", +"position": [ +1498.4444710709047, +520 +], +"parameters": { +"options": { +"reset": false +} +}, +"typeVersion": 3 +}, +{ +"id": "edd9e2c7-9477-4145-bb1f-1424ccb2080f", +"name": "Update Row Status", +"type": "n8n-nodes-base.googleSheets", +"position": [ +2558.444471070905, +1380 +], +"parameters": { +"columns": { +"value": { +"status": "done", +"row_number": "={{ $('Execute Workflow Trigger').first().json.data.row_number }}" +}, +"schema": [ +{ +"id": "displayName", +"type": "string", +"display": true, +"required": false, +"displayName": "displayName", +"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": false, +"readOnly": true, +"required": false, +"displayName": "row_number", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [ +"row_number" +] +}, +"options": {}, +"operation": "update", +"sheetName": { +"__rl": true, +"mode": "name", +"value": "={{ $('Execute Workflow Trigger').first().json.sheet }}" +}, +"documentId": { +"__rl": true, +"mode": "list", +"value": "" +} +}, +"typeVersion": 4.4 +}, +{ +"id": "454ccacd-104c-4cad-b52e-72447a49fb04", +"name": "Single Integration Non-native", +"type": "n8n-nodes-base.set", +"position": [ +778.4444710709047, +1580 +], +"parameters": { +"mode": "raw", +"options": {}, +"jsonOutput": "={{\n{\n \"data\": [\n {\n \"question\": `How can I set up ${$json.data.displayName} integration in n8n?`,\n \"answer\": `To use ${$json.data.displayName} integration in n8n, start by adding the HTTP Request node to your workflow canvas and authenticate it using a generic authentication method. Once connected, you can make custom API calls to ${$json.data.displayName} to query the data you need using the URLs you provide, for example:`,\n \"ai_example\": \"Assume useris advanced in n8n integration and sending HTTP requests, focus instead on examples operations and/or use-cases such as creating records, updating records, or retrieving data.\",\n \"ai_completion\": true\n },\n{\n \"question\": `Do I need any special permissions or API keys to integrate ${$json.data.displayName} with n8n?`,\n \"answer\": `Yes, with generic authentication, you'll typically need to provide endpoint URLs, headers, parameters, and any other authentication details specific to **${$json.data.displayName}**: - Find the **${$json.data.displayName}** API documentation and see if the API supports HTTP requests; - Most APIs require some form of authentication and you can configure this in the HTTP Request mode (Basic Auth, Custom Auth, Digest Auth, Header Auth, OAuth1 API, OAuth2 API, Query Auth).`,\n \"ai_completion\": false\n },\n{\n \"question\": `Can I combine ${$json.data.displayName} with other apps in n8n workflows?`,\n \"answer\": `Definitely! n8n enables you to create workflows that combine ${$json.data.displayName} with other apps and services. For instance,`,\n \"ai_completion\": true\n },\n {\n \"question\": `What are some common use cases for ${$json.data.displayName} integrations with n8n?`,\n \"answer\": `Common use cases for ${$json.data.displayName} automation include`,\n \"append\": `With n8n, you can customize these workflows to fit your specific needs and extend them by adding other 400+ integrations or incorporating advanced AI logic.`,\n \"ai_completion\": true\n },\n {\n \"question\": `How does n8n’s pricing model benefit me when integrating ${$json.data.displayName}?`,\n \"answer\": `n8n's pricing model is designed to be both affordable and scalable, which is particularly beneficial when integrating with ${ $json.data.displayName}. Unlike other platforms that charge per operation or task, n8n charges only for full workflow executions. This means you can create complex workflows with ${ $json.data.displayName}, involving thousands of tasks or steps, without worrying about escalating costs. For example, if your ${ $json.data.displayName} workflows perform around 100k tasks, you could be paying $500+/month on other platforms, but with n8n's pro plan, you start at around $50. This approach allows you to scale your ${ $json.data.displayName} integrations efficiently while maintaining predictable costs.`,\n \"ai_completion\": false\n }\n ]\n}\n}}" +}, +"typeVersion": 3.4 +}, +{ +"id": "660fda59-4222-489a-a19a-b3ae0ed7c66f", +"name": "If has Data", +"type": "n8n-nodes-base.if", +"position": [ +1678.4444710709047, +640 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "aea0bac0-4d4a-4359-8df0-1309c3126376", +"operator": { +"type": "object", +"operation": "notEmpty", +"singleValue": true +}, +"leftValue": "={{ $json.data }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2 +}, +{ +"id": "911aece8-1137-48d4-85f6-ee15ebfdc299", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1238.4444710709047, +620 +], +"parameters": { +"width": 193.4545454545455, +"height": 317.09090909090907, +"content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n### 🚨 Set Destination Folders Here" +}, +"typeVersion": 1 +}, +{ +"id": "44d206a7-049c-4721-8934-2308a4b67821", +"name": "Needs AI Completion?1", +"type": "n8n-nodes-base.switch", +"position": [ +1458.4444710709047, +1780 +], +"parameters": { +"rules": { +"values": [ +{ +"outputKey": "TEXT_REPLACE", +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"operator": { +"type": "boolean", +"operation": "false", +"singleValue": true +}, +"leftValue": "={{ $json.ai_completion }}", +"rightValue": "" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "AI_COMPLETE", +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "f3fcd8ea-6cfa-4658-86c3-3ace9b81d3f2", +"operator": { +"type": "boolean", +"operation": "true", +"singleValue": true +}, +"leftValue": "={{ $json.ai_completion }}", +"rightValue": "" +} +] +}, +"renameOutput": true +} +] +}, +"options": {} +}, +"typeVersion": 3 +}, +{ +"id": "14999c7a-2497-46db-b3b5-ede6a9c89dcb", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-20, +320 +], +"parameters": { +"color": 7, +"width": 322.9750655002858, +"height": 374.7055783044638, +"content": "## Trigger event\nThis could be changed to whatever trigger event you need: an app event, a schedule, a webhook call, another workflow or an AI chat. Sometimes, the HTTP Request node might already serve as your starting point." +}, +"typeVersion": 1 +}, +{ +"id": "99a4ca3b-3ad0-48a7-84d7-eb83b61e938b", +"name": "Switch", +"type": "n8n-nodes-base.switch", +"position": [ +538.4444710709047, +1400 +], +"parameters": { +"rules": { +"values": [ +{ +"outputKey": "Single - Native", +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"operator": { +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.sheet }}", +"rightValue": "Single Integration Native" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "Single - Cred Only", +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "6dcb9e09-5eb6-4527-9c22-7eb8867643f4", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.sheet }}", +"rightValue": "Single Integration Cred-only" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "Single - Non Native", +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "04ee4ccd-9efc-46a9-9521-fe50fb0c3087", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.sheet }}", +"rightValue": "Single Integration Non-native" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "Categories", +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "21579253-15c5-4cb4-869b-5760322ae5b5", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.sheet }}", +"rightValue": "Categories" +} +] +}, +"renameOutput": true +} +] +}, +"options": {} +}, +"typeVersion": 3 +}, +{ +"id": "7fe047c7-716c-4ac3-8b7c-c07949c579a4", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +459.1561069271204, +320 +], +"parameters": { +"color": 7, +"width": 1627.0681704544622, +"height": 636.4009080766225, +"content": "## Prepare data in Google Sheets\nThis part of the workflow prepares the data for reading from a Google Sheets document containing information about different services or categories. Here's an example of Google Sheet: https://docs.google.com/spreadsheets/d/1DCf-phfLWvuTwu02bumx-qykVQeFANnacTTAkRj5tZk/edit?usp=sharing" +}, +"typeVersion": 1 +}, +{ +"id": "cb3dc532-40db-437d-97ec-f522e6087b7c", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +498.4444710709047, +1080 +], +"parameters": { +"color": 7, +"width": 513.3200522929088, +"height": 840.0651105548446, +"content": "## Create your Q&A templates\nFor each service or category, this part of the workflow generates a set of standard questions and answers covering setup, permissions, integrations, use cases, and pricing benefits. You can modify here the input that you will feed to AI." +}, +"typeVersion": 1 +}, +{ +"id": "b4095a1b-91aa-4abc-8ed5-d6ca7271ee6c", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1238.4444710709047, +1640 +], +"parameters": { +"color": 7, +"width": 989.1782467385665, +"height": 523.7514972875132, +"content": "## Complete your Q&A templates with AI\n* An AI model (OpenAI's GPT) is used to enhance or complete some of the answers, making the content more comprehensive and natural-sounding.\n* The workflow formats the Q&A pairs, combining AI-generated content with predefined answers where applicable." +}, +"typeVersion": 1 +}, +{ +"id": "d944dfd9-4bfc-4fb0-8655-3269f6caa8ef", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1858.4444710709047, +1200 +], +"parameters": { +"color": 7, +"width": 907.1258470912726, +"height": 396.4865508957922, +"content": "## Generate JSON schemas and upload to Google Drive\n* The generated files are saved to specific folders in Google Drive, organized by the type of integration (native, credential-only, non-native) or category.\n* After processing each service or category, it updates the status in the original Google Sheets document to mark it as completed." +}, +"typeVersion": 1 +}, +{ +"id": "e21d2a42-021f-4f8e-889d-68a851e9e688", +"name": "Strapi", +"type": "n8n-nodes-base.strapi", +"position": [ +2978.444471070905, +1380 +], +"parameters": { +"operation": "create" +}, +"typeVersion": 1 +}, +{ +"id": "92ba57a7-a37a-4d67-9db9-7fa2fe72eec5", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2918.444471070905, +1100 +], +"parameters": { +"color": 7, +"width": 437.8755022115163, +"height": 1073.2774375197612, +"content": "## Send the JSON schemas to your CMS\nThis step is up to you to finish: you can choose either pre-built n8n nodes to connect with your CMS or use the HTTP Request node if you CMS is not supported directly in n8n." +}, +"typeVersion": 1 +}, +{ +"id": "a42de52f-292b-4b60-ba6d-ff1a672a9758", +"name": "Wordpress", +"type": "n8n-nodes-base.wordpress", +"position": [ +2978.444471070905, +1580 +], +"parameters": { +"additionalFields": {} +}, +"credentials": { +"wordpressApi": { +"id": "dk1CzqTOkihXrjym", +"name": "Wordpress account" +} +}, +"typeVersion": 1 +}, +{ +"id": "abcad9f3-9f05-40e7-8925-32c59b1a6355", +"name": "Webflow", +"type": "n8n-nodes-base.webflow", +"position": [ +2978.444471070905, +1780 +], +"parameters": { +"operation": "create" +}, +"typeVersion": 2 +}, +{ +"id": "60942673-646f-43df-8c0c-c78975ea38c4", +"name": "HTTP Request", +"type": "n8n-nodes-base.httpRequest", +"position": [ +2978.444471070905, +1980 +], +"parameters": { +"options": {} +}, +"typeVersion": 4.2 +}, +{ +"id": "d0a97b0c-1271-48e7-8587-5aae565b9d95", +"name": "AI Completion1", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +1678.4444710709047, +1880 +], +"parameters": { +"text": "=### The question\n{{ $json.question }}\n### Prefered answer format\n{{ $json.ai_completion_format ? 'markdown bullet list' : 'markdown' }}\n### User's answer\n{{ $json.answer }}\n{{\n$json.ai_example\n ? `### Guidance\\nWhen giving answer, follow this blueprint: ${$json.ai_example}`\n : ''\n}}", +"messages": { +"messageValues": [ +{ +"message": "=You are assisting with writing a FAQ for the service, {{ $('Execute Workflow Trigger').first().json.data.displayName || $('Execute Workflow Trigger').first().json.data['Category name'] }}. Complete the user's answer in regards to the given question. Ensure the answer is consistent by assuming the tone and style of the user's answer. Give your answer as succinctly as you can with no more than 3 sentences. Do not mention the user or use markdown, return plain text only as this output will be directly appended." +} +] +}, +"promptType": "define" +}, +"executeOnce": false, +"typeVersion": 1.4 +} +], +"pinData": {}, +"connections": { +"Switch": { +"main": [ +[ +{ +"node": "Single Integration Native", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Single Integration Cred-only", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Single Integration Non-native", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Categories", +"type": "main", +"index": 0 +} +] +] +}, +"Categories": { +"main": [ +[ +{ +"node": "Question to List1", +"type": "main", +"index": 0 +} +] +] +}, +"If has Data": { +"main": [ +[ +{ +"node": "Execute Workflow", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "For Each Service...", +"type": "main", +"index": 0 +} +] +] +}, +"Prepare Job": { +"main": [ +[ +{ +"node": "For Each Sheet...", +"type": "main", +"index": 0 +} +] +] +}, +"Get Services": { +"main": [ +[ +{ +"node": "Prepare Job", +"type": "main", +"index": 0 +} +] +] +}, +"Define Sheets": { +"main": [ +[ +{ +"node": "Sheets To List...", +"type": "main", +"index": 0 +} +] +] +}, +"AI Completion1": { +"main": [ +[ +{ +"node": "Format QA Pair1", +"type": "main", +"index": 0 +} +] +] +}, +"Format QA Pair1": { +"main": [ +[ +{ +"node": "For Each Question...1", +"type": "main", +"index": 0 +} +] +] +}, +"Create From Text": { +"main": [ +[ +{ +"node": "Update Row Status", +"type": "main", +"index": 0 +} +] +] +}, +"Execute Workflow": { +"main": [ +[ +{ +"node": "For Each Service...", +"type": "main", +"index": 0 +} +] +] +}, +"For Each Sheet...": { +"main": [ +[ +{ +"node": "For Each Service...", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Get Services", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "AI Completion1", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Question to List1": { +"main": [ +[ +{ +"node": "For Each Question...1", +"type": "main", +"index": 0 +} +] +] +}, +"Sheets To List...": { +"main": [ +[ +{ +"node": "For Each Sheet...", +"type": "main", +"index": 0 +} +] +] +}, +"Update Row Status": { +"main": [ +[ +{ +"node": "Strapi", +"type": "main", +"index": 0 +} +] +] +}, +"For Each Service...": { +"main": [ +null, +[ +{ +"node": "If has Data", +"type": "main", +"index": 0 +} +] +] +}, +"For Each Question...1": { +"main": [ +[ +{ +"node": "Questions to Object...1", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Needs AI Completion?1", +"type": "main", +"index": 0 +} +] +] +}, +"Needs AI Completion?1": { +"main": [ +[ +{ +"node": "Format QA Pair1", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "AI Completion1", +"type": "main", +"index": 0 +} +] +] +}, +"Questions to Object...1": { +"main": [ +[ +{ +"node": "Format DisplayName + Questions1", +"type": "main", +"index": 0 +} +] +] +}, +"Execute Workflow Trigger": { +"main": [ +[ +{ +"node": "Switch", +"type": "main", +"index": 0 +} +] +] +}, +"Single Integration Native": { +"main": [ +[ +{ +"node": "Question to List1", +"type": "main", +"index": 0 +} +] +] +}, +"Single Integration Cred-only": { +"main": [ +[ +{ +"node": "Question to List1", +"type": "main", +"index": 0 +} +] +] +}, +"Single Integration Non-native": { +"main": [ +[ +{ +"node": "Question to List1", +"type": "main", +"index": 0 +} +] +] +}, +"Format DisplayName + Questions1": { +"main": [ +[ +{ +"node": "Create From Text", +"type": "main", +"index": 0 +} +] +] +}, +"When clicking ‘Test workflow’": { +"main": [ +[ +{ +"node": "Define Sheets", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Enrich Pipedrive_s Organization Data with OpenAI GPT-4o & Notify it in Slack.txt b/Enrich Pipedrive_s Organization Data with OpenAI GPT-4o & Notify it in Slack.txt new file mode 100644 index 0000000..287fce7 --- /dev/null +++ b/Enrich Pipedrive_s Organization Data with OpenAI GPT-4o & Notify it in Slack.txt @@ -0,0 +1,266 @@ +{ +"id": "", +"meta": { +"instanceId": "", +"templateCredsSetupCompleted": true +}, +"name": "piepdrive-test", +"tags": [], +"nodes": [ +{ +"id": "b2838678-c796-4c99-a3da-a2cd1b42ea97", +"name": "Pipedrive Trigger - An Organization is created", +"type": "n8n-nodes-base.pipedriveTrigger", +"position": [ +820, +380 +], +"webhookId": "f5de09a8-6601-4ad5-8bc8-9b3f4b83e997", +"parameters": { +"action": "added", +"object": "organization" +}, +"credentials": { +"pipedriveApi": { +"id": "", +"name": "Pipedrive Connection" +} +}, +"typeVersion": 1 +}, +{ +"id": "5aa05d79-b2fa-4040-b4ca-cad83adf2798", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-20, +120 +], +"parameters": { +"width": 656.3637637842876, +"height": 1455.9537026322007, +"content": "# Enrich Pipedrive's Organization Data with GPT-4o When an Organization is Created in Pipedrive\n\nThis workflow **enriches a Pipedrive organization's data by adding a note to the organization object in Pipedrive**. It assumes there is a custom \"website\" field in your Pipedrive setup, as data will be scraped from this website to generate a note using OpenAI.\n\n## ⚠️ Disclaimer\n**These workflows use a scraping API. Before using it, ensure you comply with the regulations regarding web scraping in your country or state**.\n\n## Important Notes\n- The OpenAI model used is GPT-4o, chosen for its large input token context capacity. However, it is also **the most expensive option**, you should take cost into consideration.\n\n- The system prompt in the OpenAI Node generates output with relevant information, but feel free to improve or **modify it according to your needs**.\n\n## **How It Works**\n\n### Node 1: `Pipedrive Trigger - An Organization is Created`\nThis is the trigger of the workflow. When **an organization object is created in Pipedrive**, this node is triggered and retrieves the data. Make sure you have a \"website\" custom field (the name of the field in the n8n node will appear as a random ID and not with the Pipedrive custom field name).\n\n### Node 2: `ScrapingBee - Get Organization's Website's Homepage Content`\nThis node **scrapes the content** from the URL of the website associated with the **Pipedrive Organization** created in Node 1. The workflow uses the [ScrapingBee](https://www.scrapingbee.com/) API, but you can use any preferred API or simply the HTTP request node in n8n.\n\n### Node 3: `OpenAI - Message GPT-4o with Scraped Data`\nThis node sends HTML-scraped data from the previous node to the **OpenAI GPT-4 model**. The system prompt instructs the model to **extract company data**, such as products or services offered and competitors (if known by the model), and format it as HTML for optimal use in a Pipedrive Note.\n\n### Node 4: `Pipedrive - Create a Note with OpenAI Output`\nThis node **adds a Note to the Organization created in Pipedrive** using the OpenAI node output. The Note will include the company description, target market, selling products, and competitors (if GPT-4 was able to determine them).\n\n### Node 5 & 6: `HTML To Markdown` & `Code - Markdown to Slack Markdown`\nThese two nodes **format the HTML output to Slack Markdown**.\n\nThe Note created in Pipedrive is in HTML format, **as specified by the System Prompt of the OpenAI Node**. To send it to Slack, it needs to be converted to Markdown and then to Slack-specific Markdown.\n\n### Node 7: `Slack - Notify`\nThis node **sends a message in Slack containing the Pipedrive Organization Note** created with this workflow.\n" +}, +"typeVersion": 1 +}, +{ +"id": "47ee8bfb-2f9d-4790-a929-1533215d6746", +"name": "Pipedrive - Create a Note with OpenAI output", +"type": "n8n-nodes-base.pipedrive", +"position": [ +1640, +380 +], +"parameters": { +"content": "={{ $json.message.content }}", +"resource": "note", +"additionalFields": { +"org_id": "={{ $('Pipedrive Trigger - An Organization is created').item.json.meta.id }}" +} +}, +"credentials": { +"pipedriveApi": { +"id": "", +"name": "Pipedrive Connection" +} +}, +"typeVersion": 1 +}, +{ +"id": "7783b531-0469-4bee-868e-4b26a1bb41ba", +"name": "Code - Markdown to Slack Markdown", +"type": "n8n-nodes-base.code", +"position": [ +2080, +380 +], +"parameters": { +"jsCode": "const inputMarkdown = items[0].json.data;\n\nfunction convertMarkdownToSlackFormat(markdown) {\n let slackFormatted = markdown;\n \n // Convert headers\n slackFormatted = slackFormatted.replace(/^# (.*$)/gim, '*$1*');\n slackFormatted = slackFormatted.replace(/^## (.*$)/gim, '*$1*');\n \n // Convert unordered lists\n slackFormatted = slackFormatted.replace(/^\\* (.*$)/gim, '➡️ $1');\n \n // Convert tables\n const tableRegex = /\\n\\|.*\\|\\n\\|.*\\|\\n((\\|.*\\|\\n)+)/;\n const tableMatch = slackFormatted.match(tableRegex);\n if (tableMatch) {\n const table = tableMatch[0];\n const rows = table.split('\\n').slice(3, -1);\n const formattedRows = rows.map(row => {\n const columns = row.split('|').slice(1, -1).map(col => col.trim());\n return `*${columns[0]}*: ${columns[1]}`;\n }).join('\\n');\n slackFormatted = slackFormatted.replace(table, formattedRows);\n }\n \n return slackFormatted;\n}\n\nconst slackMarkdown = convertMarkdownToSlackFormat(inputMarkdown);\nconsole.log(slackMarkdown);\n\n// Return data\nreturn [{ slackFormattedMarkdown: slackMarkdown }];\n" +}, +"typeVersion": 2 +}, +{ +"id": "cf2b02df-07e8-4ebb-ba3d-bfd294dcfab0", +"name": "Scrapingbee - Get Organization's URL content", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1040, +380 +], +"parameters": { +"url": "https://app.scrapingbee.com/api/v1", +"options": {}, +"sendQuery": true, +"queryParameters": { +"parameters": [ +{ +"name": "api_key", +"value": "" +}, +{ +"name": "url", +"value": "={{ $json.current. }}" +}, +{ +"name": "render_js", +"value": "false" +} +] +} +}, +"typeVersion": 4.2 +}, +{ +"id": "906d44f0-7582-4742-9fd8-4c8dfba918e0", +"name": "HTML To Markdown", +"type": "n8n-nodes-base.markdown", +"position": [ +1860, +380 +], +"parameters": { +"html": "={{ $json.content }}", +"options": {} +}, +"typeVersion": 1 +}, +{ +"id": "8c1a5d64-4f38-4f9e-8878-443f750206b7", +"name": "Slack - Notify ", +"type": "n8n-nodes-base.slack", +"position": [ +2300, +380 +], +"parameters": { +"text": "=*New Organizaton {{ $('Pipedrive Trigger - An Organization is created').item.json.current.name }} created on Pipedrive* :\n\n\n {{ $json.slackFormattedMarkdown }}", +"select": "channel", +"channelId": { +"__rl": true, +"mode": "list", +"value": "", +"cachedResultName": "pipedrive-notification" +}, +"otherOptions": {}, +"authentication": "oAuth2" +}, +"credentials": { +"slackOAuth2Api": { +"id": "", +"name": "Slack Connection" +} +}, +"typeVersion": 2.2 +}, +{ +"id": "2414a5d3-1d4b-447b-b401-4b6f823a0cf9", +"name": "OpenAI - Message GPT-4o with Scraped Data", +"type": "@n8n/n8n-nodes-langchain.openAi", +"position": [ +1260, +380 +], +"parameters": { +"modelId": { +"__rl": true, +"mode": "list", +"value": "gpt-4o", +"cachedResultName": "GPT-4O" +}, +"options": {}, +"messages": { +"values": [ +{ +"content": "={{ $json.data }}" +}, +{ +"role": "system", +"content": "You're an assistant that summarizes website content for CRM entries. The user will provide HTML content from a company's website. Your task is to analyze the HTML content and create a concise summary that includes:\n\n1. A brief description of the company's services or products.\n2. Any information about the company's target market or customer base.\n3. Key points about the company's unique selling propositions or competitive advantages.\n4. Based on the provided information, suggest potential competitors if you know any.\n\nFormat your response as HTML.\n\nExample response :\n\n

Company Description

\n

Company1 specializes in services related to electric vehicles. The company focuses on providing resources and information about electric car chargers, battery life, different car brands, and the environmental impact of electric vehicles.

\n\n

Target Market

\n

The target market for Company1 includes electric vehicle owners and potential buyers who are interested in making the shift from traditional fossil fuel vehicles to electric cars. The company also targets environmentally conscious consumers who are looking for sustainable mobility solutions.

\n\n

Unique Selling Propositions

\n
    \n
  • Comprehensive information about electric vehicle charging solutions, including how to install home charging stations.
  • \n
  • Detailed articles on the advantages of electric vehicles such as ecology and reliability.
  • \n
  • Educational resources on the autonomy and battery life of different electric car models.
  • \n
  • Insights into premier electric vehicle brands.
  • \n
\n\n

Potential Competitors

\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
Competitor NameWebsite
Competitor1https://www.example1.com
Competitor2https://www.example2.com
Competitor3https://www.example3.com
Competitor4https://www.example4.com
\n" +} +] +} +}, +"credentials": { +"openAiApi": { +"id": "", +"name": "OpenAi Connection" +} +}, +"typeVersion": 1.3 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "", +"connections": { +"HTML To Markdown": { +"main": [ +[ +{ +"node": "Code - Markdown to Slack Markdown", +"type": "main", +"index": 0 +} +] +] +}, +"Code - Markdown to Slack Markdown": { +"main": [ +[ +{ +"node": "Slack - Notify ", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI - Message GPT-4o with Scraped Data": { +"main": [ +[ +{ +"node": "Pipedrive - Create a Note with OpenAI output", +"type": "main", +"index": 0 +} +] +] +}, +"Pipedrive - Create a Note with OpenAI output": { +"main": [ +[ +{ +"node": "HTML To Markdown", +"type": "main", +"index": 0 +} +] +] +}, +"Scrapingbee - Get Organization's URL content": { +"main": [ +[ +{ +"node": "OpenAI - Message GPT-4o with Scraped Data", +"type": "main", +"index": 0 +} +] +] +}, +"Pipedrive Trigger - An Organization is created": { +"main": [ +[ +{ +"node": "Scrapingbee - Get Organization's URL content", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Enrich Property Inventory Survey with Image Recognition and AI Agent.txt b/Enrich Property Inventory Survey with Image Recognition and AI Agent.txt new file mode 100644 index 0000000..720c260 --- /dev/null +++ b/Enrich Property Inventory Survey with Image Recognition and AI Agent.txt @@ -0,0 +1,960 @@ +{ +"meta": { +"instanceId": "26ba763460b97c249b82942b23b6384876dfeb9327513332e743c5f6219c2b8e" +}, +"nodes": [ +{ +"id": "192d3e4f-6bb0-4b87-a1fa-e32c9efb49cc", +"name": "When clicking \"Test workflow\"", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +336, +34 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "32a7a772-76a6-4614-a6ab-d2b152a5811f", +"name": "OpenAI Chat Model1", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +1220, +180 +], +"parameters": { +"model": "gpt-4o", +"options": { +"temperature": 0 +} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "8c444314-ed7d-4ca0-b0fa-b6d1e964c698", +"name": "Get Applicable Rows", +"type": "n8n-nodes-base.airtable", +"position": [ +516, +34 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appbgxPBurOmQK3E7", +"cachedResultUrl": "https://airtable.com/appbgxPBurOmQK3E7", +"cachedResultName": "Building Inventory Survey Example" +}, +"table": { +"__rl": true, +"mode": "id", +"value": "tblEHkoTvKpa4Aa0Q" +}, +"options": {}, +"operation": "search", +"returnAll": false, +"filterByFormula": "AND(Image!=\"\", AI_status=FALSE())" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2 +}, +{ +"id": "f90578fa-b886-4653-8ff7-0c91884dc517", +"name": "Execute Workflow Trigger", +"type": "n8n-nodes-base.executeWorkflowTrigger", +"position": [ +1257, +733 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "8f5959eb-45bd-4185-a959-10268827e41d", +"name": "Edit Fields", +"type": "n8n-nodes-base.set", +"position": [ +1417, +733 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "7263764b-8409-4cea-8db3-3278dd7ef9d8", +"name": "=route", +"type": "string", +"value": "={{ $json.route }}" +}, +{ +"id": "55c3b207-2e98-4137-8413-f72cbff17986", +"name": "query", +"type": "string", +"value": "={{ $json.query }}" +}, +{ +"id": "6eb873de-3c3a-4135-9dc0-1d441c63647c", +"name": "", +"type": "string", +"value": "" +} +] +} +}, +"typeVersion": 3.3 +}, +{ +"id": "2c7f7274-12e9-4dd3-8ee4-679b408d5430", +"name": "Fallback Response", +"type": "n8n-nodes-base.set", +"position": [ +1580, +875 +], +"parameters": { +"mode": "raw", +"options": {}, +"jsonOutput": "{\n \"response\": {\n \"ok\": false,\n \"error\": \"The requested tool was not found or the service may be unavailable. Do not retry.\"\n }\n}\n" +}, +"typeVersion": 3.3 +}, +{ +"id": "09f36f4d-eb88-4d93-a8b3-e9ba66b46b54", +"name": "SERP Google Reverse Image API", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1860, +549 +], +"parameters": { +"url": "https://serpapi.com/search.json", +"options": {}, +"sendQuery": true, +"authentication": "predefinedCredentialType", +"queryParameters": { +"parameters": [ +{ +"name": "engine", +"value": "google_reverse_image" +}, +{ +"name": "image_url", +"value": "={{ $json.query }}" +} +] +}, +"nodeCredentialType": "serpApi" +}, +"credentials": { +"serpApi": { +"id": "aJCKjxx6U3K7ydDe", +"name": "SerpAPI account" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "8e3a0f38-8663-4f5c-837f-4b9aa21f14fb", +"name": "Reverse Image Search Response", +"type": "n8n-nodes-base.set", +"position": [ +2037, +547 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "de99a504-713f-4c78-8679-08139b2def31", +"name": "response", +"type": "string", +"value": "={{ JSON.stringify($json.image_results.map(x => ({ position: x.position, title: x.title, link: x.link, description: x.snippet }))) }}" +} +] +} +}, +"typeVersion": 3.3 +}, +{ +"id": "0cd2269a-5b1f-4f10-b180-7f9cff9b1102", +"name": "Reverse Image Search Tool", +"type": "@n8n/n8n-nodes-langchain.toolWorkflow", +"position": [ +1300, +340 +], +"parameters": { +"name": "reverse_image_search", +"fields": { +"values": [ +{ +"name": "route", +"stringValue": "serp.google_reverse_image" +} +] +}, +"workflowId": "={{ $workflow.id }}", +"description": "Call this tool to perform a reverse image search. Reverse image searches return urls where similar looking products exists. Fetch the returned urls to gather more information. This tool requires the following object request body.\n```\n{\n \"type\": \"object\",\n \"properties\": {\n \"image_url\": { \"type\": \"string\" },\n }\n}\n```\nimage_url should be an absolute URL to the image." +}, +"typeVersion": 1.1 +}, +{ +"id": "9825651e-b382-4e0a-97ef-37764cb5be9e", +"name": "Firecrawl Scrape API", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1860, +889 +], +"parameters": { +"url": "https://api.firecrawl.dev/v0/scrape", +"method": "POST", +"options": {}, +"sendBody": true, +"sendHeaders": true, +"authentication": "genericCredentialType", +"bodyParameters": { +"parameters": [ +{ +"name": "url", +"value": "={{ $json.query }}" +} +] +}, +"genericAuthType": "httpHeaderAuth", +"headerParameters": { +"parameters": [ +{ +"name": "Content-Type", +"value": "application/json" +} +] +} +}, +"credentials": { +"httpHeaderAuth": { +"id": "OUOnyTkL9vHZNorB", +"name": "Firecrawl API" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "7f61d60b-b052-4b7c-abfd-9eb8e05a45a2", +"name": "Scrape Success?", +"type": "n8n-nodes-base.if", +"position": [ +2020, +889 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "a15a164f-d0c5-478f-8b27-f3d51746c214", +"operator": { +"type": "boolean", +"operation": "true", +"singleValue": true +}, +"leftValue": "={{ $json.success }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2 +}, +{ +"id": "29c65ef4-6350-490a-b8e3-a5c869e656b2", +"name": "Firecrawl Scrape Success Response", +"type": "n8n-nodes-base.set", +"position": [ +2180, +889 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "7db5c81f-de90-40e1-8086-3f13d40451c7", +"name": "response", +"type": "string", +"value": "={{ $json.data.markdown.substring(0, 3000) }}" +} +] +} +}, +"typeVersion": 3.3 +}, +{ +"id": "229b4008-d8a8-4609-854a-fc244a4ed630", +"name": "Firecrawl scrape Error Response", +"type": "n8n-nodes-base.set", +"position": [ +2180, +1049 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "e691d86a-d366-44a2-baa6-3dba42527f6e", +"name": "response", +"type": "string", +"value": "{ error: \"Unable to scrape website due to unknown error. Do not retry.\" }" +} +] +} +}, +"typeVersion": 3.3 +}, +{ +"id": "f080069b-e849-45e0-88cf-03707d22c704", +"name": "Firecrawl Web Scaper Tool", +"type": "@n8n/n8n-nodes-langchain.toolWorkflow", +"position": [ +1440, +340 +], +"parameters": { +"name": "webpage_url_scraper_tool", +"fields": { +"values": [ +{ +"name": "route", +"stringValue": "firecrawl.scrape" +} +] +}, +"workflowId": "={{ $workflow.id }}", +"description": "Call this tool to retrieve page contents of a url.\n```\n{\n \"type\": \"object\",\n \"properties\": {\n \"url\": { \"type\": \"string\" },\n }\n}\n```\nurl should be an absolute URL." +}, +"typeVersion": 1.1 +}, +{ +"id": "4eff88bb-bd5e-4d6a-b5e1-8521632c461f", +"name": "Structured Output Parser", +"type": "@n8n/n8n-nodes-langchain.outputParserStructured", +"position": [ +1500, +180 +], +"parameters": { +"jsonSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"title\": { \"type\": \"string\" },\n \"description\": { \"type\": \"string\" },\n \"model\": { \"type\": \"string\" },\n \"material\": { \"type\": \"string\" },\n \"color\": { \"type\": \"string\" },\n \"condition\": { \"type\": \"string\" }\n }\n}" +}, +"typeVersion": 1.1 +}, +{ +"id": "328d106b-a473-4f54-82fd-55c30d813da9", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +280, +-260 +], +"parameters": { +"color": 7, +"width": 402.5984702109446, +"height": 495.4071184783251, +"content": "## 1. Use Airtable to Capture Survey Photos\n[Read more about AirTable](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.airtable)\n\nTo enable this workflow, we need a database where we can retreive the title and photo to analyse and write the generate values back to. Airtable is perfect for this since it has a robust API we can work with.\n\nFor this demo, we'll manually trigger but this can be changed for forms or other triggers." +}, +"typeVersion": 1 +}, +{ +"id": "e358775d-ff83-411d-9364-b43c87d98134", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +716.3106363781314, +-160 +], +"parameters": { +"color": 7, +"width": 359.40869874940336, +"height": 428.4787925736586, +"content": "## 2. Use AI Vision Model to Analyse the Photo.\n[Read more about OpenAI Vision](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-langchain.openai)\n\nWe'll use OpenAi vision model to create a detailed description of the product in the photo. We split this step from the agent because it uses an image model rather than the usual text-based one." +}, +"typeVersion": 1 +}, +{ +"id": "51b4a70c-9583-4e8a-8e8d-896a80ad53c3", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1111.3914848823072, +-293.9250474768817 +], +"parameters": { +"color": 7, +"width": 593.0683948010671, +"height": 803.956942672397, +"content": "## 3. Build an AI Agent who Searches the Internet\n[Read more about OpenAI Agents](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-langchain.openai)\n\nThis AI Agent has the ability to perform reverse image searches using our captured photos as well visit external webpages in order to obtain accurate product names and attributes. The Agent along with the tools might mimic what the average human user would carry out the same task.\n\n* For reverse image search, we're using SERP API service however we won't use the built-in SERP node as we need to specify custom parameters. \n* For scraping, we'll use [Firecrawl](https://www.firecrawl.dev/) as this service also helps to parse and return the page as markdown which is more efficient." +}, +"typeVersion": 1 +}, +{ +"id": "adfb519b-a5c7-432c-be32-5acfcc388b49", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1740, +-149.28190375244515 +], +"parameters": { +"color": 7, +"width": 373.3601237414979, +"height": 397.7168664109706, +"content": "## 4. Overwrite our Rows with Enriched Results\n\nAnd Viola! Our AI agent has potentially saved hours of manual data entry work for our surveyor. This technique can be used for many other usecases." +}, +"typeVersion": 1 +}, +{ +"id": "6444e217-b944-450e-892a-5822d4d390ce", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1200, +549 +], +"parameters": { +"color": 7, +"width": 554.6092633638649, +"height": 490.7010880746526, +"content": "## 5. Using the Custom Workflow Tool\n[Read more about Workflow Tools](https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolworkflow)\n\nAI Agents rely on Tools to make decisions and become exponentially more powerful the more tools they have. A common pattern to manage multiple tools is to create a routing system for tools using the API pattern." +}, +"typeVersion": 1 +}, +{ +"id": "bf2459cf-a931-4232-9504-b36b15721194", +"name": "Enrich Product Rows", +"type": "n8n-nodes-base.airtable", +"position": [ +1880, +60 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appbgxPBurOmQK3E7", +"cachedResultUrl": "https://airtable.com/appbgxPBurOmQK3E7", +"cachedResultName": "Building Inventory Survey Example" +}, +"table": { +"__rl": true, +"mode": "id", +"value": "tblEHkoTvKpa4Aa0Q" +}, +"columns": { +"value": { +"id": "={{ $('Get Applicable Rows').item.json.id }}", +"Color": "={{ $json.output.output.color }}", +"Model": "={{ $json.output.output.model }}", +"Title": "={{ $json.output.output.title }}", +"Material": "={{ $json.output.output.material }}", +"AI_status": true, +"Condition": "={{ $json.output.output.condition }}", +"Description": "={{ $json.output.output.description }}" +}, +"schema": [ +{ +"id": "id", +"type": "string", +"display": true, +"removed": false, +"readOnly": true, +"required": false, +"displayName": "id", +"defaultMatch": true +}, +{ +"id": "Title", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Title", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Image", +"type": "array", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Image", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Description", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Description", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Model", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Model", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Material", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Material", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Color", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Color", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Condition", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Condition", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "AI_status", +"type": "boolean", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "AI_status", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [ +"id" +] +}, +"options": {}, +"operation": "update" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2 +}, +{ +"id": "19d736bf-c29d-46a2-93bc-b536ff28c4b5", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-100, +-260 +], +"parameters": { +"width": 359.6648027457353, +"height": 381.0536322713287, +"content": "## Try It Out!\n### This workflow does the following:\n* Scans an Airtable spreadsheet for rows with product photo images.\n* Uses an AI vision model to attempt to identify the product.\n* Uses an AI Agent to research the product on the internet to enrich the product data.\n* Overwrites our Airtable spreadsheet with the enriched data.\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": "25f15c48-16bf-4f92-942d-c224ed88d208", +"name": "Analyse Image", +"type": "@n8n/n8n-nodes-langchain.openAi", +"position": [ +840, +80 +], +"parameters": { +"text": "=Focus on the {{ $json.Title }} in the image - we'll refer to this as the \"object\". Identify the following attributes of the object. If you cannot determine confidently, then leave blank and move to next attribute.\n* Decription of the object.\n* The model/make of the object.\n* The material(s) used in the construction of the object.\n* The color(s) of the object\n* The condition of the object. Use one of poor, good, excellent.\n", +"options": {}, +"resource": "image", +"imageUrls": "={{ $json.Image[0].thumbnails.large.url }}", +"operation": "analyze" +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1.3 +}, +{ +"id": "e6c99f71-ccc9-426e-b916-cc38864e3224", +"name": "Object Identifier Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +1260, +20 +], +"parameters": { +"text": "=system: Your role is to help an building surveyor perform a object classification and data collection task whereby the surveyor will take photos of various objects and your job is to try and identify accurately certain product attributes of the objects as detailed below.\n\nThe surveyor has given you the following:\n1) photo url ```{{ $('Get Applicable Rows').item.json.Image[0].thumbnails.large.url }}```.\n2) photo description ```{{ $json.content }}```.\n\nFor each product attribute the surveyor is unable to determine, you may:\n1) use the reverse image search tool to search the product on the internet via the provided image url.\n2) use the web scraper tool to read webpages on the internet which may be relevant to the product.\n3) If after using these tools, you are still unable to determine the required product attributes then leave the data blank.\n\nUse all the information provided and gathered, to extract the following product attributes: title, description, model, material, color and condition.", +"agent": "openAiFunctionsAgent", +"options": {}, +"promptType": "define", +"hasOutputParser": true +}, +"typeVersion": 1.5 +}, +{ +"id": "661b14bd-6511-4f20-981c-2e68a7c34ec5", +"name": "Actions Router", +"type": "n8n-nodes-base.switch", +"position": [ +1577, +733 +], +"parameters": { +"rules": { +"values": [ +{ +"outputKey": "serp.google_reverse_image", +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"operator": { +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.route }}", +"rightValue": "serp.google_reverse_image" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "firecrawl.scrape", +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "0a1f54ae-39f1-468d-ba6e-1376d13e4ee8", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.route }}", +"rightValue": "firecrawl.scrape" +} +] +}, +"renameOutput": true +} +] +}, +"options": { +"fallbackOutput": "extra" +} +}, +"typeVersion": 3 +}, +{ +"id": "c5078221-9239-4ec0-b25e-7cd880b58216", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +480, +20 +], +"parameters": { +"width": 181.2788838920522, +"height": 297.0159375852115, +"content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n🚨**Required**\n* Set Airtable Base and Table IDs here." +}, +"typeVersion": 1 +}, +{ +"id": "c58c0db4-9b99-4a77-90ae-66fa3981b684", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1840, +40 +], +"parameters": { +"width": 181.2788838920522, +"height": 297.0159375852115, +"content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n🚨**Required**\n* Set Airtable Base and Table IDs here." +}, +"typeVersion": 1 +}, +{ +"id": "e3a666d7-d7a5-43f5-8f04-7972332f8916", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1780, +440 +], +"parameters": { +"color": 7, +"width": 460.3301604548244, +"height": 298.81538450684064, +"content": "## 5.1 Google Reverse Image Tool\nThis tool uses Google's reverse image API to return websites where similar images are found." +}, +"typeVersion": 1 +}, +{ +"id": "d7407cdb-16bb-4bd9-a28e-7a72a5289354", +"name": "Sticky Note9", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1780, +769.9385328672522 +], +"parameters": { +"color": 7, +"width": 575.3216480295998, +"height": 463.34699288922565, +"content": "## 5.2 Webscraper Tool\nThis tool uses Firecrawl.dev API to crawl webpages and returns those pages in markdown format." +}, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"Edit Fields": { +"main": [ +[ +{ +"node": "Actions Router", +"type": "main", +"index": 0 +} +] +] +}, +"Analyse Image": { +"main": [ +[ +{ +"node": "Object Identifier Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Actions Router": { +"main": [ +[ +{ +"node": "SERP Google Reverse Image API", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Firecrawl Scrape API", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Fallback Response", +"type": "main", +"index": 0 +} +] +] +}, +"Scrape Success?": { +"main": [ +[ +{ +"node": "Firecrawl Scrape Success Response", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Firecrawl scrape Error Response", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model1": { +"ai_languageModel": [ +[ +{ +"node": "Object Identifier Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Get Applicable Rows": { +"main": [ +[ +{ +"node": "Analyse Image", +"type": "main", +"index": 0 +} +] +] +}, +"Firecrawl Scrape API": { +"main": [ +[ +{ +"node": "Scrape Success?", +"type": "main", +"index": 0 +} +] +] +}, +"Object Identifier Agent": { +"main": [ +[ +{ +"node": "Enrich Product Rows", +"type": "main", +"index": 0 +} +] +] +}, +"Execute Workflow Trigger": { +"main": [ +[ +{ +"node": "Edit Fields", +"type": "main", +"index": 0 +} +] +] +}, +"Structured Output Parser": { +"ai_outputParser": [ +[ +{ +"node": "Object Identifier Agent", +"type": "ai_outputParser", +"index": 0 +} +] +] +}, +"Firecrawl Web Scaper Tool": { +"ai_tool": [ +[ +{ +"node": "Object Identifier Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Reverse Image Search Tool": { +"ai_tool": [ +[ +{ +"node": "Object Identifier Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"SERP Google Reverse Image API": { +"main": [ +[ +{ +"node": "Reverse Image Search Response", +"type": "main", +"index": 0 +} +] +] +}, +"When clicking \"Test workflow\"": { +"main": [ +[ +{ +"node": "Get Applicable Rows", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Extract Information from a Logo Sheet using forms, AI, Google Sheet and Airtable.txt b/Extract Information from a Logo Sheet using forms, AI, Google Sheet and Airtable.txt new file mode 100644 index 0000000..cd27e7f --- /dev/null +++ b/Extract Information from a Logo Sheet using forms, AI, Google Sheet and Airtable.txt @@ -0,0 +1,1992 @@ +{ +"id": "dDAqkobn2pqgdl2N", +"meta": { +"instanceId": "9e331a89ae45a204c6dee51c77131d32a8c962ec20ccf002135ea60bd285dba9" +}, +"name": "AI Logo Sheet Extractor to Airtable", +"tags": [], +"nodes": [ +{ +"id": "f7ecadb8-dc5d-4e8c-96b8-52c1dbad49b6", +"name": "On form submission", +"type": "n8n-nodes-base.formTrigger", +"position": [ +-660, +-220 +], +"webhookId": "43837a27-f752-40a8-852a-d5d63d647bfd", +"parameters": { +"options": { +"path": "logo-sheet-feeder" +}, +"formTitle": "AI Logo Sheet Feeder", +"formFields": { +"values": [ +{ +"fieldType": "file", +"fieldLabel": "The Logo-Sheet as Image", +"requiredField": true +}, +{ +"fieldLabel": "Addional Prompt (e.g.: What the meaning of the graphic?) *optional but helps from time to time.", +"placeholder": "It's a graph chart comparing AI Tools" +} +] +}, +"formDescription": "Provide a Image with multiple Logos comparing or bringing multiple Tools into Context with one another." +}, +"typeVersion": 2.2 +}, +{ +"id": "b1530578-bde9-4ee3-9cdb-545a621cdb84", +"name": "Retrieve and Parser Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +-180, +-220 +], +"parameters": { +"options": { +"systemMessage": "Your task is to retrieve Information from the given Input. Extract Categories and Attributes of all given and shown Tools, Softwares or Products you've got by the user.\n\nProvide the Output Array of Tools with the following Structure as JSON:\n\n[{\n\"name\": \"Name of the Tool, Software, etc.\",\n\"attributes\": [\"Some category or attribute\", \"something else you can see from the context or image\"],\n\"similar\": [\"similar tool, product, etc. from shown context\", \"another similar software, product, tool from context\"]\n},{\n\"name\": \"Name of anotherTool, Software, etc.\",\n\"attributes\": [\"Some category, subcategory or general attribute\", \"something else you can see from the context or image\"],\n\"similar\": [\"similar tool, product, etc. from shown context\", \"another similar software, product, tool from context\"]\n}]\n\nList these structure for all the Products you see!\n\nHere a description of the JSON fields:\n\"name\": Just the Name of the Software.\n\"attribute\": Turn any information from the context or image into multiple useful Attributes for this tool. Could be a category, could be a feature, etc. Try to split this information in multiple specific Attributes or Categories.\n\"similar\": if multiple tools are shown that could compare to this one (like on the same level or in the same category), list those here\n\nTake a deep breath and think step by step.\nTry to extract every mentioned tool. There are for sure multiple listed.", +"passthroughBinaryImages": true +}, +"hasOutputParser": true +}, +"typeVersion": 1.7 +}, +{ +"id": "51642a02-51a4-4894-adf0-f364736dabc1", +"name": "JSON it", +"type": "n8n-nodes-base.set", +"position": [ +220, +-220 +], +"parameters": { +"mode": "raw", +"options": {}, +"jsonOutput": "={{ $json.output }}" +}, +"typeVersion": 3.4 +}, +{ +"id": "ec0f0575-eb33-48a9-b3fe-c4f5b71ff548", +"name": "Structured Output Parser", +"type": "@n8n/n8n-nodes-langchain.outputParserStructured", +"position": [ +40, +20 +], +"parameters": { +"jsonSchemaExample": "{\n\t\"tools\": [{\n\"name\": \"Name of the Tool, Software, etc.\",\n\"attributes\": [\"Some category or attribute\", \"something else you can see from the context or image\"],\n\"similar\": [\"similar tool, product, etc. from shown context\", \"another similar software, product, tool from context\"]\n},{\n\"name\": \"Name of anotherTool, Software, etc.\",\n\"attributes\": [\"Some category, subcategory or general attribute\", \"something else you can see from the context or image\"],\n\"similar\": [\"similar tool, product, etc. from shown context\", \"another similar software, product, tool from context\"]\n}]}" +}, +"typeVersion": 1.2 +}, +{ +"id": "6d78005e-7277-40a9-9f10-e3d8e475cbaf", +"name": "Check if Attribute exists", +"type": "n8n-nodes-base.airtable", +"position": [ +1380, +0 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appq0gcmxHAZQhswW", +"cachedResultUrl": "https://airtable.com/appq0gcmxHAZQhswW", +"cachedResultName": "AI Tools" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblX2rj8yNAZZRhwt", +"cachedResultUrl": "https://airtable.com/appq0gcmxHAZQhswW/tblX2rj8yNAZZRhwt", +"cachedResultName": "Attributes" +}, +"columns": { +"value": { +"Name": "={{$json.attributes}}" +}, +"schema": [ +{ +"id": "id", +"type": "string", +"display": true, +"removed": true, +"readOnly": true, +"required": false, +"displayName": "id", +"defaultMatch": true +}, +{ +"id": "Name", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Name", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Tools", +"type": "array", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Tools", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [ +"Name" +] +}, +"options": {}, +"operation": "upsert" +}, +"credentials": { +"airtableTokenApi": { +"id": "jMqH6HkKUYTgyHVm", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "1c468a4b-4563-4f78-ba1b-138b18ac4821", +"name": "Merge", +"type": "n8n-nodes-base.merge", +"position": [ +1620, +80 +], +"parameters": { +"mode": "combine", +"options": {}, +"combineBy": "combineByPosition" +}, +"typeVersion": 3 +}, +{ +"id": "4f597962-48e5-4367-a329-bc07d42ff86d", +"name": "Map Attribute ID", +"type": "n8n-nodes-base.set", +"position": [ +1840, +80 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "675510b1-97e7-4a71-9c9e-d3ee792d9919", +"name": "id", +"type": "string", +"value": "={{ $json.id }}" +}, +{ +"id": "87cc9086-effd-4f4e-84c1-9adec5774e94", +"name": "attribute", +"type": "string", +"value": "={{ $json.attributes }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "11679757-360c-468f-b624-a9f6853e29f4", +"name": "Loop Over Attributes", +"type": "n8n-nodes-base.splitInBatches", +"position": [ +720, +-40 +], +"parameters": { +"options": {} +}, +"typeVersion": 3 +}, +{ +"id": "835a09ae-2e51-488c-b0b3-d895696a135e", +"name": "All Attributes", +"type": "n8n-nodes-base.set", +"position": [ +940, +-60 +], +"parameters": { +"mode": "raw", +"options": {}, +"jsonOutput": "={{ $json }}" +}, +"typeVersion": 3.4 +}, +{ +"id": "b8ca6d98-ab37-4393-8a2c-561912aeff2b", +"name": "Wait for Attribute Creation", +"type": "n8n-nodes-base.merge", +"position": [ +1120, +-200 +], +"parameters": { +"mode": "chooseBranch" +}, +"typeVersion": 3 +}, +{ +"id": "9eaf87d4-910b-4a6e-9cdf-ee51ff4180cc", +"name": "Change each Attribute to the corresponding RecID", +"type": "n8n-nodes-base.code", +"position": [ +1340, +-200 +], +"parameters": { +"jsCode": "let knownAttributesOutput = $('All Attributes').all();\nlet knownAttributes = new Map();\nknownAttributesOutput.forEach((nodeOutput)=>{\nknownAttributes.set(nodeOutput.json.attribute.toString().trim(), nodeOutput.json.id);\n});\n\n\nfor (const item of $input.all()) {\n item.json.attributes.forEach((attribute, index)=>{\n item.json.attributes[index] = knownAttributes.get(attribute.toString().trim());\n });\n}\n\nreturn $input.all();" +}, +"typeVersion": 2 +}, +{ +"id": "ecfedff4-f6f9-429e-8514-cf8208e70048", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +600, +-280 +], +"parameters": { +"color": 5, +"width": 1460, +"height": 600, +"content": "## Attribute Creation and Mapping those created or existing Ids " +}, +"typeVersion": 1 +}, +{ +"id": "ad2fafed-0a42-4615-a882-01306af7caf5", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-260, +-360 +], +"parameters": { +"color": 6, +"width": 420, +"height": 540, +"content": "## Eat the provided Images, Extract the Information out of them as \"Tool -> Attributes\" list." +}, +"typeVersion": 1 +}, +{ +"id": "5eb89e50-7a2f-415c-82f2-99eb8a7ff82f", +"name": "Split Out Tools", +"type": "n8n-nodes-base.splitOut", +"position": [ +440, +-220 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "tools" +}, +"typeVersion": 1 +}, +{ +"id": "680dfb4b-dde4-4d8f-852d-c3eba82e6607", +"name": "Split Out each Attribute String", +"type": "n8n-nodes-base.splitOut", +"position": [ +1140, +100 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "attributes" +}, +"typeVersion": 1 +}, +{ +"id": "a33465e9-d469-498f-9178-7c30e15d2782", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2120, +-280 +], +"parameters": { +"color": 4, +"width": 880, +"height": 600, +"content": "## Create the Tools (if not exists)" +}, +"typeVersion": 1 +}, +{ +"id": "5b5ab9f2-d4ac-437f-ab0a-b113a8af34ab", +"name": "Generate Unique Hash for Name", +"type": "n8n-nodes-base.crypto", +"position": [ +2180, +-200 +], +"parameters": { +"value": "={{ $json.name.toLowerCase().trim() }}", +"dataPropertyName": "hash" +}, +"typeVersion": 1 +}, +{ +"id": "ea8f7e6f-9004-4271-80d3-333701cce488", +"name": "Create if not Exist", +"type": "n8n-nodes-base.airtable", +"position": [ +2400, +-100 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appq0gcmxHAZQhswW", +"cachedResultUrl": "https://airtable.com/appq0gcmxHAZQhswW", +"cachedResultName": "AI Tools" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblrikRHbX1N6P2JI", +"cachedResultUrl": "https://airtable.com/appq0gcmxHAZQhswW/tblrikRHbX1N6P2JI", +"cachedResultName": "Tools" +}, +"columns": { +"value": { +"Hash": "={{$json.hash}}", +"Name": "={{$json.name}}" +}, +"schema": [ +{ +"id": "id", +"type": "string", +"display": true, +"removed": true, +"readOnly": true, +"required": false, +"displayName": "id", +"defaultMatch": true +}, +{ +"id": "Name", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Name", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Description", +"type": "string", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Description", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Website", +"type": "string", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Website", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Category", +"type": "array", +"display": true, +"options": [], +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Category", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Attributes", +"type": "array", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Attributes", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Hash", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Hash", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [ +"Hash" +] +}, +"options": {}, +"operation": "upsert" +}, +"credentials": { +"airtableTokenApi": { +"id": "jMqH6HkKUYTgyHVm", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "85ac3cbb-4103-4184-b686-9e5b8d48f421", +"name": "Merge Old Data + RecID", +"type": "n8n-nodes-base.merge", +"position": [ +2820, +-180 +], +"parameters": { +"mode": "combine", +"options": {}, +"fieldsToMatchString": "hash" +}, +"typeVersion": 3 +}, +{ +"id": "29d6369f-f233-46f8-8bee-aa3be854bb0c", +"name": "Only what we need", +"type": "n8n-nodes-base.set", +"position": [ +2600, +-100 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "0ff954ec-1d71-429b-b2e8-dca17ff0478d", +"name": "hash", +"type": "string", +"value": "={{ $json.fields.Hash }}" +}, +{ +"id": "a7f4c2e7-fa63-45d7-ad22-ce8c3aaae4d6", +"name": "id", +"type": "string", +"value": "={{ $json.id }}" +}, +{ +"id": "081a7613-7c06-4578-8aa4-25d21952b727", +"name": "existingAttributes", +"type": "array", +"value": "={{ $json.fields.Attributes ? $json.fields.Attributes : [] }}" +}, +{ +"id": "e3ace89b-d818-4448-8328-b36cdf08da2a", +"name": "existingSimilars", +"type": "array", +"value": "={{ $json.fields.Similar ? $json.fields.Similar : [] }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "bdf9c435-3994-4c25-9520-8dfa76e625eb", +"name": "Determine Attributes we should save", +"type": "n8n-nodes-base.code", +"position": [ +3040, +-180 +], +"parameters": { +"mode": "runOnceForEachItem", +"jsCode": "let savingAttributes = $input.item.json.existingAttributes ? $input.item.json.existingAttributes : [];\n$input.item.json.attributes.forEach((attrId)=>{\nif($input.item.json.existingAttributes.indexOf(attrId) == -1) savingAttributes.push(attrId);\n});\n\n$input.item.json.savingAttributes = savingAttributes;\n\nreturn $input.item;" +}, +"typeVersion": 2 +}, +{ +"id": "88e9f499-87d3-46e2-b3ea-1833c14aaa1b", +"name": "Split Out similar", +"type": "n8n-nodes-base.splitOut", +"position": [ +3300, +20 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "similar" +}, +"typeVersion": 1 +}, +{ +"id": "733a8d0c-c6ea-4386-9fd1-075980289e9c", +"name": "Merge1", +"type": "n8n-nodes-base.merge", +"position": [ +3960, +0 +], +"parameters": { +"mode": "combine", +"options": {}, +"combineBy": "combineByPosition" +}, +"typeVersion": 3 +}, +{ +"id": "dabb7e11-b4de-44d9-a80f-3302f49194fb", +"name": "Generate Unique Hash for Similar", +"type": "n8n-nodes-base.crypto", +"position": [ +3520, +-100 +], +"parameters": { +"value": "={{ $json.similar.toLowerCase().trim() }}", +"dataPropertyName": "hash" +}, +"typeVersion": 1 +}, +{ +"id": "a1bbda24-f75c-4316-b2bd-645827d7af1f", +"name": "It Should exists", +"type": "n8n-nodes-base.airtable", +"position": [ +3740, +-100 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appq0gcmxHAZQhswW", +"cachedResultUrl": "https://airtable.com/appq0gcmxHAZQhswW", +"cachedResultName": "AI Tools" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblrikRHbX1N6P2JI", +"cachedResultUrl": "https://airtable.com/appq0gcmxHAZQhswW/tblrikRHbX1N6P2JI", +"cachedResultName": "Tools" +}, +"columns": { +"value": { +"Hash": "={{$json.hash}}", +"Name": "={{$json.similar}}" +}, +"schema": [ +{ +"id": "id", +"type": "string", +"display": true, +"removed": true, +"readOnly": true, +"required": false, +"displayName": "id", +"defaultMatch": true +}, +{ +"id": "Name", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Name", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Description", +"type": "string", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Description", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Website", +"type": "string", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Website", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Category", +"type": "array", +"display": true, +"options": [], +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Category", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Attributes", +"type": "array", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Attributes", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Hash", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Hash", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [ +"Hash" +] +}, +"options": {}, +"operation": "upsert" +}, +"credentials": { +"airtableTokenApi": { +"id": "jMqH6HkKUYTgyHVm", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "9853b85d-fcb9-4183-8fe4-6e32d318ab01", +"name": "All Similar", +"type": "n8n-nodes-base.set", +"position": [ +4180, +0 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "675510b1-97e7-4a71-9c9e-d3ee792d9919", +"name": "id", +"type": "string", +"value": "={{ $json.id }}" +}, +{ +"id": "87cc9086-effd-4f4e-84c1-9adec5774e94", +"name": "similar", +"type": "string", +"value": "={{ $json.similar }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "0e98acd2-4aa5-4df0-b36b-6ac1a8a2263b", +"name": "Merge2", +"type": "n8n-nodes-base.merge", +"position": [ +4400, +-160 +], +"parameters": { +"mode": "chooseBranch" +}, +"typeVersion": 3 +}, +{ +"id": "ed94900a-78cd-4f61-a705-30f7cb8eb9b8", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +3200, +-280 +], +"parameters": { +"color": 2, +"width": 1600, +"height": 600, +"content": "## Map Competitors" +}, +"typeVersion": 1 +}, +{ +"id": "74f0f703-ce73-457c-9137-88d613d2e480", +"name": "Change each Smiliar to the corresponding RecID", +"type": "n8n-nodes-base.code", +"position": [ +4600, +-160 +], +"parameters": { +"jsCode": "let knownSimilarsOutput = $('All Similar').all();\nlet knownSimilars = new Map();\nknownSimilarsOutput.forEach((nodeOutput)=>{\n knownSimilars.set(nodeOutput.json.similar.toString().trim(), nodeOutput.json.id);\n});\n\nfor (const item of $input.all()) {\n item.json.similar.forEach((similar, index)=>{\n item.json.similar[index] = knownSimilars.get(similar.toString().trim());\n });\n}\n\nreturn $input.all();" +}, +"typeVersion": 2 +}, +{ +"id": "c9187902-f67f-4639-906b-d6b14ace6a0e", +"name": "Determine Similar we should save", +"type": "n8n-nodes-base.code", +"position": [ +4880, +-160 +], +"parameters": { +"mode": "runOnceForEachItem", +"jsCode": "let savingSimilar = $input.item.json.existingSimilars ? $input.item.json.existingSimilars : [];\n$input.item.json.similar.forEach((simId)=>{\nif($input.item.json.existingSimilars.indexOf(simId) == -1) savingSimilar.push(simId);\n});\n\n$input.item.json.savingSimilars = savingSimilar;\n\nreturn $input.item;" +}, +"typeVersion": 2 +}, +{ +"id": "e925a388-05e2-49e4-92ad-984517f44057", +"name": "Save all this juicy data", +"type": "n8n-nodes-base.airtable", +"position": [ +5120, +-160 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appq0gcmxHAZQhswW", +"cachedResultUrl": "https://airtable.com/appq0gcmxHAZQhswW", +"cachedResultName": "AI Tools" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblrikRHbX1N6P2JI", +"cachedResultUrl": "https://airtable.com/appq0gcmxHAZQhswW/tblrikRHbX1N6P2JI", +"cachedResultName": "Tools" +}, +"columns": { +"value": { +"Hash": "={{$json.hash}}", +"Name": "={{$json.name}}", +"Similar": "={{ $json.savingSimilars }}", +"Attributes": "={{ $json.savingAttributes }}" +}, +"schema": [ +{ +"id": "id", +"type": "string", +"display": true, +"removed": true, +"readOnly": true, +"required": false, +"displayName": "id", +"defaultMatch": true +}, +{ +"id": "Name", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Name", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Description", +"type": "string", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Description", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Website", +"type": "string", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Website", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Category", +"type": "array", +"display": true, +"options": [], +"removed": true, +"readOnly": false, +"required": false, +"displayName": "Category", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Attributes", +"type": "array", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Attributes", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Hash", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Hash", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Similar", +"type": "array", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Similar", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [ +"Hash" +] +}, +"options": {}, +"operation": "upsert" +}, +"credentials": { +"airtableTokenApi": { +"id": "jMqH6HkKUYTgyHVm", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "d2532094-9c71-4fc0-8195-fb2e29169086", +"name": "Map Agent Input", +"type": "n8n-nodes-base.set", +"position": [ +-440, +-220 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "ace29464-a2a1-44a1-87f9-255fbde042cf", +"name": "chatInput", +"type": "string", +"value": "={{$json.Prompt}}" +} +] +}, +"includeOtherFields": true +}, +"typeVersion": 3.4 +}, +{ +"id": "8fa7273b-ebc8-40e4-9f11-e4b26784f60d", +"name": "gpt-4o", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +-200, +20 +], +"parameters": { +"model": "gpt-4o", +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "25", +"name": "Key 3 vom 15. Jan. 2023\t" +} +}, +"typeVersion": 1 +}, +{ +"id": "fb282ffe-4871-4560-97ce-43cc381db874", +"name": "Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1440, +-580 +], +"parameters": { +"width": 668, +"height": 786, +"content": "## Instructions\n\nThis automation enables you to just upload any Image (via Form) of a Logo Sheet, containing multiple Images of Products, most likely and bringing them in some context to one another. \n\nAfter submitting an AI-Agent eats **that Logo Sheet**, turning it into an List of \"Productname\" and \"Attributes\", also checks if Tools are kind of similar to another, given the Context of the Image.\n\nWe utilize AI Vision capabilities for that. **NOTE:** It might not be able to extract all informations. For a \"upload and forget it\" Workflow it works for me. You can even run it multiple times, to be sure. \n\nBut if you need to make sure it extracts **everything** you might need to think about an Multi-Agent Setup with Validation-Agent Steps.\n\nOnce the Agent finishes the extraction, it will traditionally and deterministicly add those Attributes to Airtable (**Creates** those, if not already existing.) and also **Upserts** the Tool Informations.\n\nIt uses MD5 **Hashes** for turning Product Names into.. something fancy really, you could also use it without that, but I wanted to have something that looks atleast like an ID. \n\n### Setup\n\n1. Set Up the Airtable like shown below.\n2. Update and set Credentials for all Airtable Nodes.\n3. Check or Adjust the Prompt of the Agent matching your use-case.\n4. Activate the Workflow. \n5. Open the Form (default: https://your-n8n.io/form/logo-sheet-feeder)\n6. Enjoy growing your Airtable.\n\n![Image](https://cloud.let-the-work-flow.com/logo-64.png) \nEnjoy the workflow! ❤️ \n[let the workf low](https://let-the-work-flow.com) — Workflow Automation & Development" +}, +"typeVersion": 1 +}, +{ +"id": "9ea45b9b-ac2a-4498-b96f-5f5de50acade", +"name": "Table: Tools", +"type": "n8n-nodes-base.noOp", +"position": [ +-1340, +340 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "6dfbc02e-36b3-4640-b9f2-940c7cd6f86e", +"name": "Table: Attributes", +"type": "n8n-nodes-base.noOp", +"position": [ +-1000, +340 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "d8ffeff8-8df7-4fc0-9f18-49a44d10eb7d", +"name": "Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1440, +240 +], +"parameters": { +"color": 7, +"width": 668, +"height": 786, +"content": "## Airtable Structure\n" +}, +"typeVersion": 1 +}, +{ +"id": "7023be89-ee1d-41e6-bcf5-ee28f1284e07", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1420, +580 +], +"parameters": { +"color": 5, +"width": 300, +"height": 320, +"content": "### Tools Table Fields\n\n**Required:**\nName (singleLineText) \nAttributes (multipleRecordLinks=Link to Attributes Table) \nHash (singleLineText) \nSimilar (multipleRecordLinks=Link to the Same Table:\"Tools\") \n\n_Description (multilineText)_ \n_Website (url)_\n_Category (multipleSelects)_" +}, +"typeVersion": 1 +}, +{ +"id": "0c999f6f-11fb-472a-aa10-0915fbcd1254", +"name": "make it a readable list", +"type": "n8n-nodes-base.html", +"disabled": true, +"position": [ +-420, +800 +], +"parameters": { +"html": "" +}, +"typeVersion": 1.2 +}, +{ +"id": "ae351db3-5c47-4e53-bf9e-e34434ad9522", +"name": "Get Schema", +"type": "n8n-nodes-base.airtable", +"disabled": true, +"position": [ +-640, +800 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appq0gcmxHAZQhswW", +"cachedResultUrl": "https://airtable.com/appq0gcmxHAZQhswW", +"cachedResultName": "AI Tools" +}, +"resource": "base", +"operation": "getSchema" +}, +"credentials": { +"airtableTokenApi": { +"id": "jMqH6HkKUYTgyHVm", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "9da286e2-2a06-4d2a-bd5b-b6c828683ff2", +"name": "Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-720, +660 +], +"parameters": { +"color": 7, +"width": 488, +"height": 366, +"content": "## Helper for Documentation (ignore or enjoy it)\n" +}, +"typeVersion": 1 +}, +{ +"id": "901a0c48-82a9-4fd3-a007-8f4b257348d3", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1080, +580 +], +"parameters": { +"color": 5, +"width": 280, +"height": 320, +"content": "### Attributes Table Fields\n\n**Required:**\nName (singleLineText)\nTools (multipleRecordLinks=Link to Tools Table) " +}, +"typeVersion": 1 +}, +{ +"id": "966243fa-a1a3-4201-9df7-6a01aa762ae8", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-160, +-460 +], +"parameters": { +"color": 3, +"width": 220, +"height": 80, +"content": "### Might want to Adjust Prompt to your \"Use-Case\" 🤖" +}, +"typeVersion": 1 +}, +{ +"id": "1a4e5b87-68a6-499e-9374-e067fae12c84", +"name": "Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-2440, +-580 +], +"parameters": { +"color": 7, +"width": 968, +"height": 646, +"content": "## Example Logo Sheet\n### For these kind of sheets the Prompt is designed per default\n\n![Image](https://cloud.let-the-work-flow.com/workflow-data/example-ai-logo-sheet.jpg) " +}, +"typeVersion": 1 +} +], +"active": true, +"pinData": { +"Retrieve and Parser Agent": [ +{ +"json": { +"output": { +"tools": [ +{ +"name": "airOps", +"similar": [ +"Cognition", +"Gradial" +], +"attributes": [ +"Agentic Application", +"AI infrastructure" +] +}, +{ +"name": "Cognition", +"similar": [ +"airOps", +"Gradial" +], +"attributes": [ +"Agentic Application", +"AI infrastructure" +] +}, +{ +"name": "Gradial", +"similar": [ +"Cognition", +"airOps" +], +"attributes": [ +"Agentic Application", +"AI infrastructure" +] +}, +{ +"name": "Cognosys", +"similar": [ +"FIXIE", +"continuia" +], +"attributes": [ +"Agentic Application", +"AI infrastructure" +] +}, +{ +"name": "FIXIE", +"similar": [ +"Cognosys", +"continuia" +], +"attributes": [ +"Agentic Application", +"AI infrastructure" +] +}, +{ +"name": "continuia", +"similar": [ +"Cognosys", +"FIXIE" +], +"attributes": [ +"Agentic Application", +"AI infrastructure" +] +}, +{ +"name": "Agentlabs", +"similar": [ +"OpenAI", +"LangChain" +], +"attributes": [ +"Presentation Tool", +"Utilizes OpenAI and LangChain" +] +}, +{ +"name": "TINY FISH", +"similar": [ +"Superagent", +"basepilot" +], +"attributes": [ +"UI Automation", +"Agent as a Service" +] +}, +{ +"name": "Superagent", +"similar": [ +"TINY FISH", +"basepilot" +], +"attributes": [ +"UI Automation", +"Agent as a Service" +] +}, +{ +"name": "basepilot", +"similar": [ +"TINY FISH", +"Superagent" +], +"attributes": [ +"UI Automation", +"Agent as a Service" +] +}, +{ +"name": "Browserbase", +"similar": [ +"browsersless", +"APIFY" +], +"attributes": [ +"Browser Infrastructure", +"Web services" +] +}, +{ +"name": "browsersless", +"similar": [ +"Browserbase", +"APIFY" +], +"attributes": [ +"Browser Infrastructure", +"Web services" +] +}, +{ +"name": "APIFY", +"similar": [ +"Browserbase", +"browsersless" +], +"attributes": [ +"Browser Infrastructure", +"Web services" +] +}, +{ +"name": "Cloudflare", +"similar": [ +"bright data", +"platform.sh" +], +"attributes": [ +"Browser Infrastructure", +"Web services" +] +}, +{ +"name": "bright data", +"similar": [ +"Cloudflare", +"platform.sh" +], +"attributes": [ +"Browser Infrastructure", +"Web services" +] +}, +{ +"name": "platform.sh", +"similar": [ +"Cloudflare", +"bright data" +], +"attributes": [ +"Browser Infrastructure", +"Web services" +] +}, +{ +"name": "ingest", +"similar": [ +"hatchet", +"Trigger.dev" +], +"attributes": [ +"Persistence Tool", +"Data management" +] +}, +{ +"name": "hatchet", +"similar": [ +"ingest", +"Trigger.dev" +], +"attributes": [ +"Persistence Tool", +"Data management" +] +}, +{ +"name": "Trigger.dev", +"similar": [ +"ingest", +"hatchet" +], +"attributes": [ +"Persistence Tool", +"Data management" +] +}, +{ +"name": "DSPy", +"similar": [ +"AutoGen", +"Scma4.ai" +], +"attributes": [ +"Orchestration Tool", +"AI Workflow Management" +] +}, +{ +"name": "AutoGen", +"similar": [ +"DSPy", +"Scma4.ai" +], +"attributes": [ +"Orchestration Tool", +"AI Workflow Management" +] +}, +{ +"name": "Scma4.ai", +"similar": [ +"DSPy", +"AutoGen" +], +"attributes": [ +"Orchestration Tool", +"AI Workflow Management" +] +}, +{ +"name": "WhyHowAI", +"similar": [ +"Graphlit", +"LangMem" +], +"attributes": [ +"Personalization Tool", +"Memory management" +] +}, +{ +"name": "Graphlit", +"similar": [ +"WhyHowAI", +"LangMem" +], +"attributes": [ +"Personalization Tool", +"Memory management" +] +}, +{ +"name": "LangMem", +"similar": [ +"WhyHowAI", +"Graphlit" +], +"attributes": [ +"Personalization Tool", +"Memory management" +] +}, +{ +"name": "Pinecone", +"similar": [ +"Chroma", +"Weaviate" +], +"attributes": [ +"Storage Tool", +"Memory management" +] +}, +{ +"name": "Chroma", +"similar": [ +"Pinecone", +"Weaviate" +], +"attributes": [ +"Storage Tool", +"Memory management" +] +}, +{ +"name": "Weaviate", +"similar": [ +"Pinecone", +"Chroma" +], +"attributes": [ +"Storage Tool", +"Memory management" +] +}, +{ +"name": "MongoDB", +"similar": [ +"WhiteLodge", +"Chroma" +], +"attributes": [ +"Context Management", +"Data storage" +] +}, +{ +"name": "LangServe", +"similar": [ +"E2B", +"Ollama" +], +"attributes": [ +"Agent Hosting", +"Deployment platform" +] +}, +{ +"name": "E2B", +"similar": [ +"LangServe", +"Ollama" +], +"attributes": [ +"Agent Hosting", +"Deployment platform" +] +}, +{ +"name": "Ollama", +"similar": [ +"LangServe", +"E2B" +], +"attributes": [ +"Agent Hosting", +"Deployment platform" +] +}, +{ +"name": "LangGraph", +"similar": [ +"Semantic Kernel", +"LlamaIndex" +], +"attributes": [ +"Framework Tool", +"Graph Management" +] +}, +{ +"name": "LlamaIndex", +"similar": [ +"LangGraph", +"Semantic Kernel" +], +"attributes": [ +"Framework Tool", +"Graph Management" +] +}, +{ +"name": "Semantic Kernel", +"similar": [ +"LangGraph", +"LlamaIndex" +], +"attributes": [ +"Framework Tool", +"Graph Management" +] +}, +{ +"name": "agentops", +"similar": [ +"context", +"LangSmith" +], +"attributes": [ +"Agent Evaluation Tool", +"Performance Assessment" +] +}, +{ +"name": "context", +"similar": [ +"agentops", +"LangSmith" +], +"attributes": [ +"Agent Evaluation Tool", +"Performance Assessment" +] +}, +{ +"name": "LangSmith", +"similar": [ +"agentops", +"context" +], +"attributes": [ +"Agent Evaluation Tool", +"Performance Assessment" +] +}, +{ +"name": "WHYLabs", +"similar": [ +"griptape", +"braintrust" +], +"attributes": [ +"Developer Tools", +"Data Management" +] +}, +{ +"name": "griptape", +"similar": [ +"WHYLabs", +"braintrust" +], +"attributes": [ +"Developer Tools", +"Data Management" +] +}, +{ +"name": "braintrust", +"similar": [ +"WHYLabs", +"griptape" +], +"attributes": [ +"Developer Tools", +"Data Management" +] +} +] +} +} +} +] +}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "cd74efad-4f0c-45ea-bc7e-3f7c5554c204", +"connections": { +"Merge": { +"main": [ +[ +{ +"node": "Map Attribute ID", +"type": "main", +"index": 0 +} +] +] +}, +"Merge1": { +"main": [ +[ +{ +"node": "All Similar", +"type": "main", +"index": 0 +} +] +] +}, +"Merge2": { +"main": [ +[ +{ +"node": "Change each Smiliar to the corresponding RecID", +"type": "main", +"index": 0 +} +] +] +}, +"gpt-4o": { +"ai_languageModel": [ +[ +{ +"node": "Retrieve and Parser Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"JSON it": { +"main": [ +[ +{ +"node": "Split Out Tools", +"type": "main", +"index": 0 +} +] +] +}, +"Get Schema": { +"main": [ +[ +{ +"node": "make it a readable list", +"type": "main", +"index": 0 +} +] +] +}, +"All Similar": { +"main": [ +[ +{ +"node": "Merge2", +"type": "main", +"index": 1 +} +] +] +}, +"Table: Tools": { +"main": [ +[ +{ +"node": "Table: Tools", +"type": "main", +"index": 0 +}, +{ +"node": "Table: Attributes", +"type": "main", +"index": 0 +} +] +] +}, +"All Attributes": { +"main": [ +[ +{ +"node": "Wait for Attribute Creation", +"type": "main", +"index": 1 +} +] +] +}, +"Map Agent Input": { +"main": [ +[ +{ +"node": "Retrieve and Parser Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Split Out Tools": { +"main": [ +[ +{ +"node": "Loop Over Attributes", +"type": "main", +"index": 0 +}, +{ +"node": "Wait for Attribute Creation", +"type": "main", +"index": 0 +} +] +] +}, +"It Should exists": { +"main": [ +[ +{ +"node": "Merge1", +"type": "main", +"index": 0 +} +] +] +}, +"Map Attribute ID": { +"main": [ +[ +{ +"node": "Loop Over Attributes", +"type": "main", +"index": 0 +} +] +] +}, +"Only what we need": { +"main": [ +[ +{ +"node": "Merge Old Data + RecID", +"type": "main", +"index": 1 +} +] +] +}, +"Split Out similar": { +"main": [ +[ +{ +"node": "Generate Unique Hash for Similar", +"type": "main", +"index": 0 +}, +{ +"node": "Merge1", +"type": "main", +"index": 1 +} +] +] +}, +"Table: Attributes": { +"main": [ +[] +] +}, +"On form submission": { +"main": [ +[ +{ +"node": "Map Agent Input", +"type": "main", +"index": 0 +} +] +] +}, +"Create if not Exist": { +"main": [ +[ +{ +"node": "Only what we need", +"type": "main", +"index": 0 +} +] +] +}, +"Loop Over Attributes": { +"main": [ +[ +{ +"node": "All Attributes", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Split Out each Attribute String", +"type": "main", +"index": 0 +} +] +] +}, +"Merge Old Data + RecID": { +"main": [ +[ +{ +"node": "Determine Attributes we should save", +"type": "main", +"index": 0 +} +] +] +}, +"Structured Output Parser": { +"ai_outputParser": [ +[ +{ +"node": "Retrieve and Parser Agent", +"type": "ai_outputParser", +"index": 0 +} +] +] +}, +"Check if Attribute exists": { +"main": [ +[ +{ +"node": "Merge", +"type": "main", +"index": 0 +} +] +] +}, +"Retrieve and Parser Agent": { +"main": [ +[ +{ +"node": "JSON it", +"type": "main", +"index": 0 +} +] +] +}, +"Wait for Attribute Creation": { +"main": [ +[ +{ +"node": "Change each Attribute to the corresponding RecID", +"type": "main", +"index": 0 +} +] +] +}, +"Generate Unique Hash for Name": { +"main": [ +[ +{ +"node": "Create if not Exist", +"type": "main", +"index": 0 +}, +{ +"node": "Merge Old Data + RecID", +"type": "main", +"index": 0 +} +] +] +}, +"Split Out each Attribute String": { +"main": [ +[ +{ +"node": "Check if Attribute exists", +"type": "main", +"index": 0 +}, +{ +"node": "Merge", +"type": "main", +"index": 1 +} +] +] +}, +"Determine Similar we should save": { +"main": [ +[ +{ +"node": "Save all this juicy data", +"type": "main", +"index": 0 +} +] +] +}, +"Generate Unique Hash for Similar": { +"main": [ +[ +{ +"node": "It Should exists", +"type": "main", +"index": 0 +} +] +] +}, +"Determine Attributes we should save": { +"main": [ +[ +{ +"node": "Split Out similar", +"type": "main", +"index": 0 +}, +{ +"node": "Merge2", +"type": "main", +"index": 0 +} +] +] +}, +"Change each Smiliar to the corresponding RecID": { +"main": [ +[ +{ +"node": "Determine Similar we should save", +"type": "main", +"index": 0 +} +] +] +}, +"Change each Attribute to the corresponding RecID": { +"main": [ +[ +{ +"node": "Generate Unique Hash for Name", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Extract and process information directly from PDF using Claude and Gemini.txt b/Extract and process information directly from PDF using Claude and Gemini.txt new file mode 100644 index 0000000..5430e37 --- /dev/null +++ b/Extract and process information directly from PDF using Claude and Gemini.txt @@ -0,0 +1,283 @@ +{ +"meta": { +"instanceId": "f4f5d195bb2162a0972f737368404b18be694648d365d6c6771d7b4909d28167" +}, +"nodes": [ +{ +"id": "b6cd232e-e82e-457b-9f03-c010b3eba148", +"name": "When clicking 'Test workflow'", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +-40, +0 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "2b734806-e3c0-4552-a491-54ca846ed3ac", +"name": "Extract from File", +"type": "n8n-nodes-base.extractFromFile", +"position": [ +620, +0 +], +"parameters": { +"options": {}, +"operation": "binaryToPropery" +}, +"typeVersion": 1 +}, +{ +"id": "2c199499-cc4f-405c-8560-765500b7acba", +"name": "Google Drive", +"type": "n8n-nodes-base.googleDrive", +"position": [ +420, +0 +], +"parameters": { +"fileId": { +"__rl": true, +"mode": "list", +"value": "18Ac2xorxirIBm9FNFDDB5aVUSPBCCg1U", +"cachedResultUrl": "https://drive.google.com/file/d/18Ac2xorxirIBm9FNFDDB5aVUSPBCCg1U/view?usp=drivesdk", +"cachedResultName": "Invoice-798FE2FA-0004.pdf" +}, +"options": {}, +"operation": "download" +}, +"credentials": { +"googleDriveOAuth2Api": { +"id": "AUEpxwlqBJghNMtb", +"name": "Google Drive account" +} +}, +"typeVersion": 3 +}, +{ +"id": "e3031c0c-f059-4f30-9684-10014a277d55", +"name": "Call Gemini 2.0 Flash with PDF Capabilities", +"type": "n8n-nodes-base.httpRequest", +"position": [ +880, +220 +], +"parameters": { +"url": "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp:generateContent", +"method": "POST", +"options": {}, +"jsonBody": "={\n \"contents\": [\n {\n \"parts\": [\n {\n \"inline_data\": {\n \"mime_type\": \"application/pdf\",\n \"data\": \"{{ $json.data }}\"\n }\n },\n {\n \"text\": \"{{ $('Define Prompt').item.json.prompt }}\"\n }\n ]\n }\n ]\n}", +"sendBody": true, +"specifyBody": "json", +"authentication": "predefinedCredentialType", +"nodeCredentialType": "googlePalmApi" +}, +"credentials": { +"anthropicApi": { +"id": "eOt6Ois0jSizRFMJ", +"name": "Anthropic Mira Account" +}, +"googlePalmApi": { +"id": "IQrjvfoUd5LUft3b", +"name": "Google Gemini(PaLM) Api account" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "135df716-32a1-47e8-9ed8-30c830b803d6", +"name": "Call Claude 3.5 Sonnet with PDF Capabilities", +"type": "n8n-nodes-base.httpRequest", +"position": [ +880, +-140 +], +"parameters": { +"url": "https://api.anthropic.com/v1/messages", +"method": "POST", +"options": {}, +"jsonBody": "={\n \"model\": \"claude-3-5-sonnet-20241022\",\n \"max_tokens\": 1024,\n \"messages\": [{\n \"role\": \"user\",\n \"content\": [{\n \"type\": \"document\",\n \"source\": {\n \"type\": \"base64\",\n \"media_type\": \"application/pdf\",\n \"data\": \"{{$json.data}}\"\n }\n },\n {\n \"type\": \"text\",\n \"text\": \"{{ $('Define Prompt').item.json.prompt }}\"\n }]\n }]\n}", +"sendBody": true, +"sendHeaders": true, +"specifyBody": "json", +"authentication": "predefinedCredentialType", +"headerParameters": { +"parameters": [ +{ +"name": "anthropic-version", +"value": "2023-06-01" +}, +{ +"name": "content-type", +"value": "application/json" +} +] +}, +"nodeCredentialType": "anthropicApi" +}, +"credentials": { +"anthropicApi": { +"id": "eOt6Ois0jSizRFMJ", +"name": "Anthropic Mira Account" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "5b8994d1-4bfd-4776-84ac-b3141aca6378", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-700, +-280 +], +"parameters": { +"color": 7, +"width": 601, +"height": 585, +"content": "## Workflow: Extract data from PDF with Claude 3.5 Sonnet or Gemini 2.0 Flash\n\n**Overview**\n- This workflow helps you compare Claude 3.5 Sonnet and Gemini 2.0 Flash when extracting data from a PDF\n- This workflow extracts and processes the data within a PDF in **one single step**, **instead of calling an OCR and then an LLM”**\n\n\n**How it works**\n- The initial 2 steps download the PDF and convert it to base64.\n- This base64 string is then sent to both Claude 3.5 Sonnet and Gemini 2.0 Flash to extract information.\n- This workflow is made to let you compare results, latency, and cost (in their dedicated dashboard).\n\n\n**How to use it**\n- Set up your Google Drive if not already done\n- Select a document on your Google Drive\n- Modify the prompt in \"Define Prompt\" to extract the information you need and transform it as wanted.\n- Get a [Claude API key](https://console.anthropic.com/settings/keys) and/or [Gemini API key](https://aistudio.google.com/app/apikey)\n- Note that you can deactivate one of the 2 API calls if you don't want to try both\n- Test the Workflow\n" +}, +"typeVersion": 1 +}, +{ +"id": "616241a9-6199-406b-88dc-0afc7d974250", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +820, +60 +], +"parameters": { +"color": 5, +"width": 320, +"height": 360, +"content": "You can output the result as JSON by adding the following:\n```\n\"generationConfig\": {\n \"responseMimeType\": \"application/json\"\n```\nor even use a structured output.\n[Check the documentation](https://ai.google.dev/gemini-api/docs/structured-output?lang=rest)" +}, +"typeVersion": 1 +}, +{ +"id": "bbac8d3d-d68f-4aa2-a41a-b06f7de2317b", +"name": "Define Prompt", +"type": "n8n-nodes-base.set", +"position": [ +180, +0 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "dba23ef5-95df-496a-8e24-c7c1544533d2", +"name": "prompt", +"type": "string", +"value": "Extract the VAT numbers for each country" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "3c2e7265-76e5-4911-a950-7e6b0c89ec5a", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +820, +-200 +], +"parameters": { +"color": 5, +"width": 320, +"height": 240, +"content": "You can force Claude to output JSON with [Prefill response format](https://docs.anthropic.com/en/docs/test-and-evaluate/strengthen-guardrails/increase-consistency#prefill-claudes-response)" +}, +"typeVersion": 1 +}, +{ +"id": "f2b46305-5200-486e-ad4d-ecc0d2a14314", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +380, +-120 +], +"parameters": { +"color": 5, +"width": 380, +"height": 280, +"content": "These 2 steps first download the PDF file, and then convert it to base64.\nThis is required by both APIs to process the file." +}, +"typeVersion": 1 +}, +{ +"id": "e5dff70f-b55a-4c23-9025-765a7cf19c4a", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +120, +-120 +], +"parameters": { +"color": 5, +"width": 220, +"height": 280, +"content": "This prompt is used in both Gemini’s and Claude’s calls to define what information should be extracted and processed." +}, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"Google Drive": { +"main": [ +[ +{ +"node": "Extract from File", +"type": "main", +"index": 0 +} +] +] +}, +"Define Prompt": { +"main": [ +[ +{ +"node": "Google Drive", +"type": "main", +"index": 0 +} +] +] +}, +"Extract from File": { +"main": [ +[ +{ +"node": "Call Claude 3.5 Sonnet with PDF Capabilities", +"type": "main", +"index": 0 +}, +{ +"node": "Call Gemini 2.0 Flash with PDF Capabilities", +"type": "main", +"index": 0 +} +] +] +}, +"When clicking 'Test workflow'": { +"main": [ +[ +{ +"node": "Define Prompt", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Extract data from resume and create PDF with Gotenberg.txt b/Extract data from resume and create PDF with Gotenberg.txt new file mode 100644 index 0000000..371bdc4 --- /dev/null +++ b/Extract data from resume and create PDF with Gotenberg.txt @@ -0,0 +1,1143 @@ +{ +"nodes": [ +{ +"id": "79849bb5-00a4-42e6-92c4-b06c7a20eb3e", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +1580, +340 +], +"parameters": { +"model": "gpt-4-turbo-preview", +"options": { +"temperature": 0, +"responseFormat": "json_object" +} +}, +"credentials": { +"openAiApi": { +"id": "jazew1WAaSRrjcHp", +"name": "OpenAI (workfloows@gmail.com)" +} +}, +"typeVersion": 1 +}, +{ +"id": "85df0106-1f78-4412-8751-b84d417c8bf9", +"name": "Convert education to HTML", +"type": "n8n-nodes-base.code", +"position": [ +2420, +180 +], +"parameters": { +"mode": "runOnceForEachItem", +"jsCode": "function convertToHTML(list) {\n let html = '';\n\n list.forEach((education, index) => {\n if (index > 0) {\n html += '

'; // Add a new line if it's not the first item\n }\n html += `Institution: ${education.institution}
\nStart year: ${education.start_year}
\nDegree: ${education.degree}`;\n });\n\n return html;\n}\n\n// Assuming payload is already defined\nconst payload = $input.item.json.education;\n\nconst htmlOutput = convertToHTML(payload);\nreturn {\n htmlOutput\n};" +}, +"typeVersion": 2 +}, +{ +"id": "da4fc45d-712f-4171-b72a-66b74b4d8e05", +"name": "Auto-fixing Output Parser", +"type": "@n8n/n8n-nodes-langchain.outputParserAutofixing", +"position": [ +1820, +340 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "225a7513-6fd4-4672-9b40-b10b00f121a7", +"name": "OpenAI Chat Model1", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +1740, +520 +], +"parameters": { +"options": { +"temperature": 0 +} +}, +"credentials": { +"openAiApi": { +"id": "jazew1WAaSRrjcHp", +"name": "OpenAI (workfloows@gmail.com)" +} +}, +"typeVersion": 1 +}, +{ +"id": "0606c99d-a080-4277-b071-1bc0c93bb2e3", +"name": "Structured Output Parser", +"type": "@n8n/n8n-nodes-langchain.outputParserStructured", +"position": [ +1960, +520 +], +"parameters": { +"jsonSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"personal_info\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": { \"type\": \"string\" },\n \"address\": { \"type\": \"string\" },\n \"email\": { \"type\": \"string\", \"format\": \"email\" },\n \"github\": { \"type\": \"string\"},\n \"linkedin\": { \"type\": \"string\" }\n }\n },\n \"employment_history\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"position\": { \"type\": \"string\" },\n \"company\": { \"type\": \"string\" },\n \"duration\": { \"type\": \"string\" },\n \"responsibilities\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n }\n }\n }\n },\n \"education\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"institution\": { \"type\": \"string\" },\n \"start_year\": { \"type\": \"integer\" },\n \"degree\": { \"type\": \"string\" }\n }\n }\n },\n \"projects\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": { \"type\": \"string\" },\n \"year\": { \"type\": \"integer\" },\n \"description\": { \"type\": \"string\" },\n \"technologies\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n }\n }\n }\n },\n \"volunteering\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"activity\": { \"type\": \"string\" },\n \"location\": { \"type\": \"string\" },\n \"date\": { \"type\": \"string\" },\n \"description\": { \"type\": \"string\" }\n }\n }\n },\n \"programming_languages\": {\n \"type\": \"object\",\n \"properties\": {\n \"languages\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n },\n \"tools\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n },\n \"methodologies\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n }\n }\n },\n \"foreign_languages\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"language\": { \"type\": \"string\" },\n \"level\": { \"type\": \"string\" }\n }\n }\n }\n }\n}\n" +}, +"typeVersion": 1 +}, +{ +"id": "027975cd-768a-4048-858d-9060f48ab622", +"name": "Convert employment history to HTML", +"type": "n8n-nodes-base.code", +"position": [ +2420, +-20 +], +"parameters": { +"mode": "runOnceForEachItem", +"jsCode": "function convertToHTML(list) {\n let html = '';\n\n list.forEach((item, index) => {\n if (index > 0) {\n html += '
'; // Add a new line if it's not the first item\n }\n html += `Position: ${item.position}\nCompany: ${item.company}\n
\nDuration: ${item.duration}\n
\nResponsibilities:\n`;\n\n item.responsibilities.forEach((responsibility, i) => {\n html += `- ${responsibility}`;\n if (i < item.responsibilities.length - 1 || index < list.length - 1) {\n html += '
'; // Add new line if it's not the last responsibility in the last item\n }\n });\n });\n\n return html;\n}\n\n// Assuming payload is already defined\nconst payload = $input.item.json.employment_history;\n\nconst htmlOutput = convertToHTML(payload);\nreturn {\n htmlOutput\n};" +}, +"typeVersion": 2 +}, +{ +"id": "823a241d-1c68-40a9-8f2c-f1bdfaab7603", +"name": "Convert projects to HTML", +"type": "n8n-nodes-base.code", +"position": [ +2420, +380 +], +"parameters": { +"mode": "runOnceForEachItem", +"jsCode": "function convertToHTML(list) {\n let html = '';\n\n list.forEach((project, index) => {\n if (index > 0) {\n html += '
'; // Add a new line if it's not the first project\n }\n html += `Name: ${project.name}
\nYear: ${project.year}
\nDescription: ${project.description}

\nTechnologies:\n
`;\n\n project.technologies.forEach((technology, i) => {\n html += `- ${technology}`;\n if (i < project.technologies.length - 1 || index < list.length - 1) {\n html += '
'; // Add new line if it's not the last technology in the last project\n }\n });\n });\n\n return html;\n}\n\n// Assuming payload is already defined\nconst payload = $input.item.json.projects;\n\nconst htmlOutput = convertToHTML(payload);\nreturn {\n htmlOutput\n};\n" +}, +"typeVersion": 2 +}, +{ +"id": "a12eb0e1-1cb9-4b83-a1ec-42dd8214f6bc", +"name": "Convert volunteering to HTML", +"type": "n8n-nodes-base.code", +"position": [ +2420, +580 +], +"parameters": { +"mode": "runOnceForEachItem", +"jsCode": "function convertToHTML(list) {\n let html = '';\n\n list.forEach((event, index) => {\n if (index > 0) {\n html += '
'; // Add a new line if it's not the first volunteering event\n }\n html += `Activity: ${event.activity}
\nLocation: ${event.location}
\nDate: ${event.date}
\nDescription: ${event.description}
`;\n });\n\n return html;\n}\n\n// Assuming payload is already defined\nconst payload = $input.item.json.volunteering;\n\nconst htmlOutput = convertToHTML(payload);\nreturn {\n htmlOutput\n};\n" +}, +"typeVersion": 2 +}, +{ +"id": "70b67b80-d22d-4eea-8c97-3d2cb2b9bbfc", +"name": "Telegram trigger", +"type": "n8n-nodes-base.telegramTrigger", +"position": [ +360, +340 +], +"webhookId": "d6829a55-a01b-44ac-bad3-2349324c8515", +"parameters": { +"updates": [ +"message" +], +"additionalFields": {} +}, +"credentials": { +"telegramApi": { +"id": "lStLV4zzcrQO9eAM", +"name": "Telegram (Resume Extractor)" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "21bead1d-0665-44d5-b623-b0403c9abd6c", +"name": "Auth", +"type": "n8n-nodes-base.if", +"position": [ +600, +340 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "7ca4b4c3-e23b-4896-a823-efc85c419467", +"operator": { +"type": "number", +"operation": "equals" +}, +"leftValue": "={{ $json.message.chat.id }}", +"rightValue": 0 +} +] +} +}, +"typeVersion": 2 +}, +{ +"id": "de76d6ec-3b0e-44e0-943d-55547aac2e46", +"name": "No operation (unauthorized)", +"type": "n8n-nodes-base.noOp", +"position": [ +860, +520 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "439f5e2c-be7d-486b-a1f1-13b09f77c2c8", +"name": "Check if start message", +"type": "n8n-nodes-base.if", +"position": [ +860, +220 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "1031f14f-9793-488d-bb6b-a021f943a399", +"operator": { +"type": "string", +"operation": "notEquals" +}, +"leftValue": "={{ $json.message.text }}", +"rightValue": "/start" +} +] +} +}, +"typeVersion": 2 +}, +{ +"id": "af5f5622-c338-40c0-af72-90e124ed7ce1", +"name": "No operation (start message)", +"type": "n8n-nodes-base.noOp", +"position": [ +1120, +360 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "2efae11a-376b-44aa-ab91-9b3dea82ede0", +"name": "Get file", +"type": "n8n-nodes-base.telegram", +"position": [ +1120, +120 +], +"parameters": { +"fileId": "={{ $json.message.document.file_id }}", +"resource": "file" +}, +"credentials": { +"telegramApi": { +"id": "lStLV4zzcrQO9eAM", +"name": "Telegram (Resume Extractor)" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "88fd1002-ad2c-445f-92d4-11b571db3788", +"name": "Extract text from PDF", +"type": "n8n-nodes-base.extractFromFile", +"position": [ +1380, +120 +], +"parameters": { +"options": {}, +"operation": "pdf" +}, +"typeVersion": 1 +}, +{ +"id": "9dfc204b-c567-418a-93a3-9b72cf534a8c", +"name": "Set parsed fileds", +"type": "n8n-nodes-base.set", +"position": [ +2040, +120 +], +"parameters": { +"options": {} +}, +"typeVersion": 3.2 +}, +{ +"id": "314c771a-5ff2-484f-823b-0eab88f43ea3", +"name": "Personal info", +"type": "n8n-nodes-base.set", +"position": [ +2420, +-380 +], +"parameters": { +"fields": { +"values": [ +{ +"name": "personal_info", +"stringValue": "=Personal info\n

\nName: {{ $json.personal_info.name }}\n
\nAddress: {{ $json.personal_info.address }}\n
\nEmail: {{ $json.personal_info.email }}\n
\nGitHub: {{ $json.personal_info.github }}\n
" +} +] +}, +"include": "none", +"options": {} +}, +"typeVersion": 3.2 +}, +{ +"id": "be6b32e8-6000-4235-a723-0e22828ead45", +"name": "Technologies", +"type": "n8n-nodes-base.set", +"position": [ +2420, +-200 +], +"parameters": { +"fields": { +"values": [ +{ +"name": "technologies", +"stringValue": "=Technologies\n

\nProgramming languages: {{ $json.programming_languages.languages.join(', ') }}\n
\nTools: {{ $json.programming_languages.tools.join(', ') }}\n
\nMethodologies: {{ $json.programming_languages.methodologies.join(', ') }}\n
" +} +] +}, +"include": "none", +"options": {} +}, +"typeVersion": 3.2 +}, +{ +"id": "ab726d61-84b8-4af7-a195-33e1add89153", +"name": "Employment history", +"type": "n8n-nodes-base.set", +"position": [ +2640, +-20 +], +"parameters": { +"fields": { +"values": [ +{ +"name": "employment_history", +"stringValue": "=Employment history\n

\n{{ $json[\"htmlOutput\"] }}" +} +] +}, +"include": "none", +"options": {} +}, +"typeVersion": 3.2 +}, +{ +"id": "692f9555-6102-4d3c-b0a1-868e27e3c343", +"name": "Education", +"type": "n8n-nodes-base.set", +"position": [ +2640, +180 +], +"parameters": { +"fields": { +"values": [ +{ +"name": "education", +"stringValue": "=Education\n

\n{{ $json[\"htmlOutput\"] }}" +} +] +}, +"include": "none", +"options": {} +}, +"typeVersion": 3.2 +}, +{ +"id": "258728f2-1f03-4786-8197-feb9f1bc4dfe", +"name": "Projects", +"type": "n8n-nodes-base.set", +"position": [ +2640, +380 +], +"parameters": { +"fields": { +"values": [ +{ +"name": "projects", +"stringValue": "=Projects\n

\n{{ $json[\"htmlOutput\"] }}" +} +] +}, +"include": "none", +"options": {} +}, +"typeVersion": 3.2 +}, +{ +"id": "3c819ce4-235a-4b12-a396-d33dca9f80da", +"name": "Volunteering", +"type": "n8n-nodes-base.set", +"position": [ +2640, +580 +], +"parameters": { +"fields": { +"values": [ +{ +"name": "volunteering", +"stringValue": "=Volunteering\n

\n{{ $json[\"htmlOutput\"] }}" +} +] +}, +"include": "none", +"options": {} +}, +"typeVersion": 3.2 +}, +{ +"id": "41bd7506-7330-4c25-8b43-aa3c836736fc", +"name": "Merge education and employment history", +"type": "n8n-nodes-base.merge", +"position": [ +2880, +100 +], +"parameters": { +"mode": "combine", +"options": {}, +"combinationMode": "multiplex" +}, +"typeVersion": 2.1 +}, +{ +"id": "d788da36-360b-4009-82ad-2f206fad8e53", +"name": "Merge projects and volunteering", +"type": "n8n-nodes-base.merge", +"position": [ +2880, +500 +], +"parameters": { +"mode": "combine", +"options": {}, +"combinationMode": "multiplex" +}, +"typeVersion": 2.1 +}, +{ +"id": "57c20e19-3d84-41c0-a415-1d55cb031da1", +"name": "Merge personal info and technologies", +"type": "n8n-nodes-base.merge", +"position": [ +3140, +-160 +], +"parameters": { +"mode": "combine", +"options": {}, +"combinationMode": "multiplex" +}, +"typeVersion": 2.1 +}, +{ +"id": "f12be010-8375-4ff7-ba8e-9c2c870f648b", +"name": "Merge all", +"type": "n8n-nodes-base.merge", +"position": [ +3400, +200 +], +"parameters": { +"mode": "combine", +"options": {}, +"combinationMode": "multiplex" +}, +"typeVersion": 2.1 +}, +{ +"id": "d6428167-2c75-42a5-a905-7590ff1d6a25", +"name": "Set final data", +"type": "n8n-nodes-base.set", +"position": [ +3620, +200 +], +"parameters": { +"fields": { +"values": [ +{ +"name": "output", +"stringValue": "={{ $json.personal_info }}\n

\n{{ $json.employment_history }}\n

\n{{ $json.education }}\n

\n{{ $json.projects }}\n

\n{{ $json.volunteering }}\n

\n{{ $json.technologies }}" +} +] +}, +"include": "none", +"options": {} +}, +"typeVersion": 3.2 +}, +{ +"id": "9ea13c62-2e09-4b37-b889-66edaef1fcf1", +"name": "Convert raw to base64", +"type": "n8n-nodes-base.code", +"position": [ +3840, +200 +], +"parameters": { +"mode": "runOnceForEachItem", +"jsCode": "const encoded = Buffer.from($json.output).toString('base64');\n\nreturn { encoded };" +}, +"typeVersion": 2 +}, +{ +"id": "c4474fa1-b1b5-432f-b30e-100201c9ec7c", +"name": "Convert to HTML", +"type": "n8n-nodes-base.convertToFile", +"position": [ +4060, +200 +], +"parameters": { +"options": { +"fileName": "index.html", +"mimeType": "text/html" +}, +"operation": "toBinary", +"sourceProperty": "encoded" +}, +"typeVersion": 1.1 +}, +{ +"id": "3c4d2010-1bdc-4f01-bb1a-bd0128017787", +"name": "Generate plain PDF doc", +"type": "n8n-nodes-base.httpRequest", +"position": [ +4340, +200 +], +"parameters": { +"url": "http://gotenberg:3000/forms/chromium/convert/html", +"method": "POST", +"options": { +"response": { +"response": { +"responseFormat": "file" +} +} +}, +"sendBody": true, +"contentType": "multipart-form-data", +"bodyParameters": { +"parameters": [ +{ +"name": "files", +"parameterType": "formBinaryData", +"inputDataFieldName": "data" +} +] +} +}, +"typeVersion": 4.1 +}, +{ +"id": "2b3cd55f-21a3-4c14-905f-82b158aa3fd0", +"name": "Send PDF to the user", +"type": "n8n-nodes-base.telegram", +"position": [ +4640, +200 +], +"parameters": { +"chatId": "={{ $('Telegram trigger').item.json[\"message\"][\"chat\"][\"id\"] }}", +"operation": "sendDocument", +"binaryData": true, +"additionalFields": { +"fileName": "={{ $('Set parsed fileds').item.json[\"personal_info\"][\"name\"].toLowerCase().replace(' ', '-') }}.pdf" +} +}, +"credentials": { +"telegramApi": { +"id": "lStLV4zzcrQO9eAM", +"name": "Telegram (Resume Extractor)" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "54fe1d2d-eb9d-4fe1-883f-1826e27ac873", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +540, +180 +], +"parameters": { +"width": 226.21234567901217, +"height": 312.917333333334, +"content": "### Add chat ID\nRemember to set your actual ID to trigger automation from Telegram." +}, +"typeVersion": 1 +}, +{ +"id": "b193a904-260b-4d45-8a66-e3cb46fc7ce4", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +800, +83.43940740740783 +], +"parameters": { +"width": 229.64938271604922, +"height": 293.54824691358016, +"content": "### Ignore start message\nWorkflow ignores initial`/start` message sent to the bot." +}, +"typeVersion": 1 +}, +{ +"id": "d5c95d8f-b699-4a8e-9460-a4f5856b5e6f", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1066, +-20 +], +"parameters": { +"width": 211.00246913580224, +"height": 302.41975308642, +"content": "### Download resume file\nBased on file ID, node performs downloading of the file uploaded by user." +}, +"typeVersion": 1 +}, +{ +"id": "2de0751d-8e11-457e-8c38-a6dcca59190c", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1320, +-20 +], +"parameters": { +"width": 217.87654320987633, +"height": 302.41975308642, +"content": "### Extract text from PDF\nNode extracts readable text form PDF." +}, +"typeVersion": 1 +}, +{ +"id": "4b9ccab8-ff6c-408f-93fe-f148034860a0", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1580, +-20 +], +"parameters": { +"width": 410.9479506172837, +"height": 302.41975308642, +"content": "### Parse resume data\nCreate structured data from text extracted from resume. Chain uses OpenAI `gpt-4-turbo-preview` model and JSON response mode. **Adjust JSON schema in output parser to your needs.**" +}, +"typeVersion": 1 +}, +{ +"id": "bfb1d382-90fa-4bff-8c38-04e53bcf5f58", +"name": "Parse resume data", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +1660, +120 +], +"parameters": { +"prompt": "={{ $json.text }}", +"messages": { +"messageValues": [ +{ +"message": "Your task is to extract all necessary data such as first name, last name, experience, known technologies etc. from the provided resume text and return in well-unified JSON format. Do not make things up." +} +] +} +}, +"typeVersion": 1.3 +}, +{ +"id": "7e8eb10a-f21c-4a9c-90b1-b71537b78356", +"name": "Merge other data", +"type": "n8n-nodes-base.merge", +"position": [ +3140, +340 +], +"parameters": { +"mode": "combine", +"options": {}, +"combinationMode": "multiplex" +}, +"typeVersion": 2.1 +}, +{ +"id": "7c4398de-7b4d-4095-b38f-eaf099d2991b", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2340, +-491.4074074074074 +], +"parameters": { +"width": 1196.8442469135782, +"height": 1260.345679012346, +"content": "### Format HTML\nFormat HTML for each resume section (employment history, projects etc.)." +}, +"typeVersion": 1 +}, +{ +"id": "9de2f504-6ff0-4b00-8e0d-436c789b4e23", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +3580, +40 +], +"parameters": { +"width": 638.6516543209876, +"height": 322.5837037037037, +"content": "### Create HTML file\nFrom formatted output create `index.html` file in order to run PDF conversion." +}, +"typeVersion": 1 +}, +{ +"id": "11abdff5-377e-490d-9136-15c24ff6a05e", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +4260, +39.83604938271645 +], +"parameters": { +"color": 3, +"width": 262.0096790123454, +"height": 322.5837037037035, +"content": "### Convert file to PDF\nForm `index.html` create PDF using [Gotenberg](https://gotenberg.dev/). If you're not familiar with this software, feel free to check out [my tutorial on YouTube](https://youtu.be/bo15xdjXf1Y?si=hFZMTfjzfSOLOLPK)." +}, +"typeVersion": 1 +}, +{ +"id": "73fb81d0-5218-4311-aaec-7fa259d8cbd3", +"name": "Sticky Note9", +"type": "n8n-nodes-base.stickyNote", +"position": [ +4560, +40 +], +"parameters": { +"width": 262.0096790123454, +"height": 322.5837037037035, +"content": "### Send PDF file to user\nDeliver converted PDF to Telegram user (based on chat ID)." +}, +"typeVersion": 1 +}, +{ +"id": "bb5fa375-4cc9-4559-a014-7b618d6c5f32", +"name": "Sticky Note10", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-280, +128 +], +"parameters": { +"width": 432.69769500990674, +"height": 364.2150828344463, +"content": "## ⚠️ Note\n\nThis is *resume extractor* workflow that I had a pleasure to present during [n8n community hangout](https://youtu.be/eZacuxrhCuo?si=KkJQrgQuvLxj-6FM&t=1701\n) on March 7, 2024.\n\n1. Remember to add your credentials and configure nodes.\n2. This node requires installed [Gotenberg](https://gotenberg.dev/) for PDF generation. If you're not familiar with this software, feel free to check out [my tutorial on YouTube](https://youtu.be/bo15xdjXf1Y?si=hFZMTfjzfSOLOLPK). If you don't want to self-host Gotenberg, you use other PDF generation provider (PDFMonkey, ApiTemplate or similar).\n3. If you like this workflow, please subscribe to [my YouTube channel](https://www.youtube.com/@workfloows) and/or [my newsletter](https://workfloows.com/).\n\n**Thank you for your support!**" +}, +"typeVersion": 1 +} +], +"connections": { +"Auth": { +"main": [ +[ +{ +"node": "Check if start message", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "No operation (unauthorized)", +"type": "main", +"index": 0 +} +] +] +}, +"Get file": { +"main": [ +[ +{ +"node": "Extract text from PDF", +"type": "main", +"index": 0 +} +] +] +}, +"Projects": { +"main": [ +[ +{ +"node": "Merge projects and volunteering", +"type": "main", +"index": 0 +} +] +] +}, +"Education": { +"main": [ +[ +{ +"node": "Merge education and employment history", +"type": "main", +"index": 1 +} +] +] +}, +"Merge all": { +"main": [ +[ +{ +"node": "Set final data", +"type": "main", +"index": 0 +} +] +] +}, +"Technologies": { +"main": [ +[ +{ +"node": "Merge personal info and technologies", +"type": "main", +"index": 1 +} +] +] +}, +"Volunteering": { +"main": [ +[ +{ +"node": "Merge projects and volunteering", +"type": "main", +"index": 1 +} +] +] +}, +"Personal info": { +"main": [ +[ +{ +"node": "Merge personal info and technologies", +"type": "main", +"index": 0 +} +] +] +}, +"Set final data": { +"main": [ +[ +{ +"node": "Convert raw to base64", +"type": "main", +"index": 0 +} +] +] +}, +"Convert to HTML": { +"main": [ +[ +{ +"node": "Generate plain PDF doc", +"type": "main", +"index": 0 +} +] +] +}, +"Merge other data": { +"main": [ +[ +{ +"node": "Merge all", +"type": "main", +"index": 1 +} +] +] +}, +"Telegram trigger": { +"main": [ +[ +{ +"node": "Auth", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Parse resume data", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Parse resume data": { +"main": [ +[ +{ +"node": "Set parsed fileds", +"type": "main", +"index": 0 +} +] +] +}, +"Set parsed fileds": { +"main": [ +[ +{ +"node": "Convert employment history to HTML", +"type": "main", +"index": 0 +}, +{ +"node": "Convert education to HTML", +"type": "main", +"index": 0 +}, +{ +"node": "Convert projects to HTML", +"type": "main", +"index": 0 +}, +{ +"node": "Personal info", +"type": "main", +"index": 0 +}, +{ +"node": "Convert volunteering to HTML", +"type": "main", +"index": 0 +}, +{ +"node": "Technologies", +"type": "main", +"index": 0 +} +] +] +}, +"Employment history": { +"main": [ +[ +{ +"node": "Merge education and employment history", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model1": { +"ai_languageModel": [ +[ +{ +"node": "Auto-fixing Output Parser", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Convert raw to base64": { +"main": [ +[ +{ +"node": "Convert to HTML", +"type": "main", +"index": 0 +} +] +] +}, +"Extract text from PDF": { +"main": [ +[ +{ +"node": "Parse resume data", +"type": "main", +"index": 0 +} +] +] +}, +"Check if start message": { +"main": [ +[ +{ +"node": "Get file", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "No operation (start message)", +"type": "main", +"index": 0 +} +] +] +}, +"Generate plain PDF doc": { +"main": [ +[ +{ +"node": "Send PDF to the user", +"type": "main", +"index": 0 +} +] +] +}, +"Convert projects to HTML": { +"main": [ +[ +{ +"node": "Projects", +"type": "main", +"index": 0 +} +] +] +}, +"Structured Output Parser": { +"ai_outputParser": [ +[ +{ +"node": "Auto-fixing Output Parser", +"type": "ai_outputParser", +"index": 0 +} +] +] +}, +"Auto-fixing Output Parser": { +"ai_outputParser": [ +[ +{ +"node": "Parse resume data", +"type": "ai_outputParser", +"index": 0 +} +] +] +}, +"Convert education to HTML": { +"main": [ +[ +{ +"node": "Education", +"type": "main", +"index": 0 +} +] +] +}, +"Convert volunteering to HTML": { +"main": [ +[ +{ +"node": "Volunteering", +"type": "main", +"index": 0 +} +] +] +}, +"Merge projects and volunteering": { +"main": [ +[ +{ +"node": "Merge other data", +"type": "main", +"index": 1 +} +] +] +}, +"Convert employment history to HTML": { +"main": [ +[ +{ +"node": "Employment history", +"type": "main", +"index": 0 +} +] +] +}, +"Merge personal info and technologies": { +"main": [ +[ +{ +"node": "Merge all", +"type": "main", +"index": 0 +} +] +] +}, +"Merge education and employment history": { +"main": [ +[ +{ +"node": "Merge other data", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Extract insights & analyse YouTube comments via AI Agent chat.txt b/Extract insights & analyse YouTube comments via AI Agent chat.txt new file mode 100644 index 0000000..c0a38de --- /dev/null +++ b/Extract insights & analyse YouTube comments via AI Agent chat.txt @@ -0,0 +1,1194 @@ +{ +"meta": { +"instanceId": "6a2a7715680b8313f7cb4676321c5baa46680adfb913072f089f2766f42e43bd" +}, +"nodes": [ +{ +"id": "f4b3833b-cf25-4bbc-927c-080586c5713c", +"name": "Sticky Note9", +"type": "n8n-nodes-base.stickyNote", +"position": [ +700, +760 +], +"parameters": { +"color": 7, +"width": 330.5152611046425, +"height": 239.5888196628349, +"content": "### ... or watch set up video [13 min]\n[![Youtube Thumbnail](https://cflobdhpqwnoisuctsoc.supabase.co/storage/v1/object/public/my_storage/Youtube%20AI%20Agent%20Blur.png)](https://youtu.be/6RmLZS8Yl4E)\n" +}, +"typeVersion": 1 +}, +{ +"id": "64d96c53-b3e2-4aea-9a29-9b9e5c729f4f", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +400, +240 +], +"parameters": { +"color": 7, +"width": 636.2128494576581, +"height": 497.1532689930921, +"content": "![5min Logo](https://cflobdhpqwnoisuctsoc.supabase.co/storage/v1/object/public/my_storage/banner.png)\n## AI Agent To Chat With Youtube\n**Made by [Mark Shcherbakov](https://www.linkedin.com/in/marklowcoding/) from community [5minAI](https://www.skool.com/5minai)**\n\nNavigating the content generation and optimization process can be complex, especially without significant audience insight. This workflow automates insights extraction from YouTube videos and comments, empowering users to create more engaging and relevant content effectively.\n\nThe workflow integrates various APIs to gather insights from YouTube videos, enabling automated commentary analysis, video transcription, and thumbnail evaluation. The main functionalities include:\n- Extracting user preferences from comments.\n- Transcribing video content for enhanced understanding.\n- Analyzing thumbnails via AI for maximum viewer engagement insights.\n\n" +}, +"typeVersion": 1 +}, +{ +"id": "57d2ede9-1bf9-4449-9dc9-af1ccee763b6", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +400, +760 +], +"parameters": { +"color": 7, +"width": 280.2462120317618, +"height": 545.9087885077763, +"content": "### Set up steps\n\n1. **API Setup**:\n - Create a [Google Cloud](https://console.cloud.google.com/apis/dashboard) project and enable the YouTube Data API.\n - Generate an API key for [Apify](https://www.apify.com?fpr=ujogj).\n - Generate API key for [OpenAI](https://platform.openai.com)\n - Create all credentials in N8N - OpenAI, Apify, Google Cloud.\n\n2. **YouTube Creator and Video Selection**:\n - Start by defining a request to identify top creators based on their video views.\n - Capture the YouTube video IDs for further analysis of comments and other video metrics.\n\n3. **Comment Analysis**:\n - Gather comments associated with the selected videos and analyze them for user insights.\n - Implement pagination to handle the maximum comment retrieval limits in API requests.\n\n4. **Video Transcription**:\n - Request transcriptions for videos of interest, ensuring to manage potential costs associated with longer video processing.\n - Utilize the insights from transcriptions to formulate content plans.\n\n5. **Thumbnail Analysis**:\n - Evaluate your video thumbnails by submitting the URL through the OpenAI API to gain insights into their effectiveness.\n\n6. **Data Management**:\n - Incorporate a database agent to organize video data and metrics, allowing efficient record management and future content planning." +}, +"typeVersion": 1 +}, +{ +"id": "ca0fd549-88a7-44fd-ab81-7fd5ca140dae", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +1540, +820 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "zJhr5piyEwVnWtaI", +"name": "OpenAi club" +} +}, +"typeVersion": 1 +}, +{ +"id": "7f2cf209-2e9d-4d6a-bc9e-d1bfd6df7266", +"name": "get_channel_details", +"type": "@n8n/n8n-nodes-langchain.toolWorkflow", +"position": [ +1900, +820 +], +"parameters": { +"name": "get_channel_details", +"fields": { +"values": [ +{ +"name": "command", +"stringValue": "=get_channel_details" +} +] +}, +"schemaType": "manual", +"workflowId": { +"__rl": true, +"mode": "list", +"value": "FgknOUpOBkpY85NX", +"cachedResultName": "Youtube parser - tools" +}, +"description": "Get channel_id, title and description by handle/username.\nChannel_id is required to find videos and details about this channel.\nIf Youtube link to channel provided - parse handle from there or return channel_id. (e.g. https://www.youtube.com/@example_handle - example_handle)\n\n\nExample Input:\nexample_handle\n\nExample Output:\nid:UCOgz_YflAsYnGbdvzXuKNCA\ntitle:Daniel Simmons\ndescription:Digital Diary 🤎\\n\\n\\nWeekly videos around fashion...", +"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"handle\": {\n \"type\": \"string\",\n \"description\": \"Handle/username of channel\"\n }},\n \"required\": [\"handle\"]\n}", +"specifyInputSchema": true +}, +"typeVersion": 1.2 +}, +{ +"id": "c02f5c19-6e50-4a06-95b9-eceb3eec1012", +"name": "get_video_description", +"type": "@n8n/n8n-nodes-langchain.toolWorkflow", +"position": [ +2020, +820 +], +"parameters": { +"name": "get_video_description", +"fields": { +"values": [ +{ +"name": "command", +"stringValue": "video_details" +} +] +}, +"schemaType": "manual", +"workflowId": { +"__rl": true, +"mode": "list", +"value": "FgknOUpOBkpY85NX", +"cachedResultName": "Youtube parser - tools" +}, +"description": "Fetch video details - the full description, title, and publish date of a video using its video_id.\n\nExample input:\nvideo_id:dQw4w9WgXcQ\n\nExample Output:\ntitle:Never Gonna Give You Up\ndescription: \"The official video for “Never Gonna Give You Up” by Rick Astley.\nduration:4 min\nviewCount:154\nlikeCount:6\nthumbnails: urls", +"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"video_id\": {\n \"type\": \"string\",\n \"description\": \"The ID of the video to fetch details for\"\n }\n },\n \"required\": [\"video_id\"]\n}", +"specifyInputSchema": true +}, +"typeVersion": 1.2 +}, +{ +"id": "2d61160b-3a65-4766-ace6-947a7c5de6e5", +"name": "get_list_of_videos", +"type": "@n8n/n8n-nodes-langchain.toolWorkflow", +"position": [ +2140, +820 +], +"parameters": { +"name": "get_list_of_videos", +"fields": { +"values": [ +{ +"name": "command", +"stringValue": "videos" +} +] +}, +"schemaType": "manual", +"workflowId": { +"__rl": true, +"mode": "list", +"value": "FgknOUpOBkpY85NX", +"cachedResultName": "Youtube parser - tools" +}, +"description": "Retrieve a list of videos from a channel using channel_id. Supports sorting by date, relevance, or view count.\n\nExample Input:\nchannel_id\": \"UCxxxxxxxxxxxxxxxx\"\nnumber_of_videos\": 5\norder: \"date\"\npublishedAfter: \"timestamp\"\n\nExample Output:\nvideo_id:abc123\ntitle:Latest Video\nshort cut description:Latest Video\npublished_at:2023-12-05T10:00:00Z", +"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"channel_id\": {\n \"type\": \"string\",\n \"description\": \"The ID of the channel to fetch videos from\"\n },\n \"number_of_videos\": {\n \"type\": \"integer\",\n \"description\": \"The maximum number of videos to retrieve (max 50)\"\n },\n \"order\": {\n \"type\": \"string\",\n \"enum\": [\"date\", \"relevance\", \"viewCount\"],\n \"description\": \"Order in which to fetch videos\"\n },\n \"publishedAfter\": {\n \"type\": \"string\",\n \"description\": \"Timestamp for filtering like 2023-11-03T15:28:05Z.\"\n }\n },\n \"required\": [\"channel_id\", \"number_of_videos\", \"order\"]\n}", +"specifyInputSchema": true +}, +"typeVersion": 1.2 +}, +{ +"id": "c5aa2f7c-7748-4f88-abb6-fd274ad1295a", +"name": "get_list_of_comments", +"type": "@n8n/n8n-nodes-langchain.toolWorkflow", +"position": [ +2260, +820 +], +"parameters": { +"name": "get_list_of_comments", +"fields": { +"values": [ +{ +"name": "command", +"stringValue": "comments" +} +] +}, +"schemaType": "manual", +"workflowId": { +"__rl": true, +"mode": "list", +"value": "FgknOUpOBkpY85NX", +"cachedResultName": "Youtube parser - tools" +}, +"description": "Retrieve a list of comments from a video using video_id.\n\nInput:\n \"video_id\": \"dQw4w9WgXcQ\"\n\nOutput:\n \"author\": \"John Doe\",\n \"comment\": \"This is an amazing video!\",\n \"published_at\": \"2023-12-04T12:00:00Z\"", +"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"video_id\": {\n \"type\": \"string\",\n \"description\": \"The ID of the video to fetch comments from\"\n }\n },\n \"required\": [\"video_id\"]\n}", +"specifyInputSchema": true +}, +"typeVersion": 1.2 +}, +{ +"id": "c68cad77-1d71-45a3-b94b-8f7c701f56fb", +"name": "search", +"type": "@n8n/n8n-nodes-langchain.toolWorkflow", +"position": [ +2380, +820 +], +"parameters": { +"name": "search", +"fields": { +"values": [ +{ +"name": "command", +"stringValue": "search" +} +] +}, +"schemaType": "manual", +"workflowId": { +"__rl": true, +"mode": "list", +"value": "FgknOUpOBkpY85NX", +"cachedResultName": "Youtube parser - tools" +}, +"description": "Search for videos or channels using a query. Supports filtering by type (video or channel) and sorting (date, viewCount, relevance). Use | for OR and - to exclude terms in the query.\n\nInput:\ntype: video or channel\nquery: search query\nsorting: date, viewCount, relevance\npublishedAfter: timestamp\n\nOutput:\n- id, title, short cut description, and published_at.", +"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"type\": {\n \"type\": \"string\",\n \"enum\": [\"video\", \"channel\"],\n \"description\": \"Type of results to retrieve: video or channel\"\n },\n \"query\": {\n \"type\": \"string\",\n \"description\": \"Search query. Supports | for OR and - to exclude terms\"\n },\n \"sorting\": {\n \"type\": \"string\",\n \"enum\": [\"date\", \"viewCount\", \"relevance\"],\n \"description\": \"Sorting criteria for search results\"\n },\n \"publishedAfter\": {\n \"type\": \"string\",\n \"description\": \"Timestamp for filtering like 2023-11-03T15:28:05Z\"\n }\n },\n \"required\": [\"type\", \"query\", \"sorting\"]\n}", +"specifyInputSchema": true +}, +"typeVersion": 1.2 +}, +{ +"id": "c87d5392-8a5c-4999-9e58-89a5e0700c40", +"name": "analyze_thumbnail", +"type": "@n8n/n8n-nodes-langchain.toolWorkflow", +"position": [ +2500, +820 +], +"parameters": { +"name": "analyze_thumbnail", +"fields": { +"values": [ +{ +"name": "command", +"stringValue": "analyze_thumbnail" +} +] +}, +"schemaType": "manual", +"workflowId": { +"__rl": true, +"mode": "list", +"value": "FgknOUpOBkpY85NX", +"cachedResultName": "Youtube parser - tools" +}, +"description": "Analyze a thumbnail image based on a given prompt. The prompt can be customized for specific analysis needs, such as design critique, color scheme evaluation, or content assessment.\nUse link of maxRes thumbnail. \n\nInput:\n- url: URL of the thumbnail image.\n- prompt: Customizable instruction for the analysis.\n\nOutput:\n- Results of the analysis based on the given prompt.", +"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"url\": {\n \"type\": \"string\",\n \"description\": \"URL of the thumbnail image to analyze\"\n },\n \"prompt\": {\n \"type\": \"string\",\n \"description\": \"Customizable instruction to guide the image analysis\"\n }\n },\n \"required\": [\"url\", \"prompt\"]\n}", +"specifyInputSchema": true +}, +"typeVersion": 1.2 +}, +{ +"id": "1be2fa35-9091-4db8-a8eb-50f822d618d3", +"name": "video_transcription", +"type": "@n8n/n8n-nodes-langchain.toolWorkflow", +"position": [ +2620, +820 +], +"parameters": { +"name": "video_transcription", +"fields": { +"values": [ +{ +"name": "command", +"stringValue": "video_transcription" +} +] +}, +"schemaType": "manual", +"workflowId": { +"__rl": true, +"mode": "list", +"value": "FgknOUpOBkpY85NX", +"cachedResultName": "Youtube parser - tools" +}, +"description": "Transcribe a video and retrieve its text transcription. Useful for analyzing video content or repurposing it for other formats.\n\nInput:\n- video_url: URL of the video to transcribe.\n\nOutput:\n- The text transcription of the video.", +"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"video_url\": {\n \"type\": \"string\",\n \"description\": \"URL of the video to transcribe\"\n }\n },\n \"required\": [\"video_url\"]\n}", +"specifyInputSchema": true +}, +"typeVersion": 1.2 +}, +{ +"id": "fbfcd82f-e247-4a21-be12-339df7afe681", +"name": "Postgres Chat Memory", +"type": "@n8n/n8n-nodes-langchain.memoryPostgresChat", +"position": [ +1700, +820 +], +"parameters": { +"sessionKey": "={{ $('When chat message received').item.json.sessionId }}", +"sessionIdType": "customKey" +}, +"credentials": { +"postgres": { +"id": "AO9cER6p8uX7V07T", +"name": "Postgres 5minai" +} +}, +"typeVersion": 1.3 +}, +{ +"id": "6a4bbad9-27ab-448b-9222-2c8843fe241a", +"name": "AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +1760, +560 +], +"parameters": { +"text": "={{ $('When chat message received').item.json.chatInput }}", +"agent": "openAiFunctionsAgent", +"options": { +"systemMessage": "You are Youtube assistant. \nYou need to process user's requests and run relevant tools for that. \n\nPlan and execute in right order runs of tools to get data for user's request.\n\nIMPORTANT Search query and list of videos for channel tools returns all videos including shorts - use Get Video description tool to identify shorts (less than minute) and filter them out if needed.\n\nFeel free to ask questions before do actions - especially if you noticed some inconcistency in user requests that might be error/misspelling. " +}, +"promptType": "define" +}, +"typeVersion": 1.6 +}, +{ +"id": "739cc12a-27d1-48e9-b124-7f83fb372514", +"name": "When chat message received", +"type": "@n8n/n8n-nodes-langchain.chatTrigger", +"position": [ +1460, +600 +], +"webhookId": "6e95bc27-99a6-417c-8bf7-2831d7f7a4be", +"parameters": { +"options": {} +}, +"typeVersion": 1.1 +}, +{ +"id": "613af9f2-77fa-42c4-86d3-87e20f2c0c89", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1380, +500 +], +"parameters": { +"width": 1430.34590072234, +"height": 588.1344471094899, +"content": "## Scenario 1: AI agent" +}, +"typeVersion": 1 +}, +{ +"id": "54116346-bc73-4a6a-8bca-f2a6e6699374", +"name": "Get Comments", +"type": "n8n-nodes-base.httpRequest", +"position": [ +2064, +1598 +], +"parameters": { +"url": "=https://www.googleapis.com/youtube/v3/commentThreads", +"options": {}, +"sendQuery": true, +"authentication": "genericCredentialType", +"genericAuthType": "httpQueryAuth", +"queryParameters": { +"parameters": [ +{ +"name": "part", +"value": "id,snippet,replies" +}, +{ +"name": "videoId", +"value": "={{ $('Execute Workflow Trigger').item.json.query.video_id }}" +}, +{ +"name": "maxResults", +"value": "100" +} +] +} +}, +"credentials": { +"httpQueryAuth": { +"id": "1DXeuNaLSixqGPaU", +"name": "Query Auth account Youtube" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "faabf71a-69f2-4113-802e-124a09fa9a0a", +"name": "Execute Workflow Trigger", +"type": "n8n-nodes-base.executeWorkflowTrigger", +"position": [ +1444, +1598 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "4b3ec3aa-7c69-4a72-a989-02f97acdf612", +"name": "Get Channel Details", +"type": "n8n-nodes-base.httpRequest", +"position": [ +2064, +1278 +], +"parameters": { +"url": "=https://www.googleapis.com/youtube/v3/channels", +"options": {}, +"sendQuery": true, +"authentication": "genericCredentialType", +"genericAuthType": "httpQueryAuth", +"queryParameters": { +"parameters": [ +{ +"name": "part", +"value": "snippet" +}, +{ +"name": "forHandle", +"value": "={{ $('Execute Workflow Trigger').item.json.query.handle }}" +} +] +} +}, +"credentials": { +"httpQueryAuth": { +"id": "1DXeuNaLSixqGPaU", +"name": "Query Auth account Youtube" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "ed8dec73-8c50-4eb9-8efe-68ee72c4d5e6", +"name": "Get Video Description", +"type": "n8n-nodes-base.httpRequest", +"position": [ +2064, +1438 +], +"parameters": { +"url": "=https://www.googleapis.com/youtube/v3/videos", +"options": {}, +"sendQuery": true, +"authentication": "genericCredentialType", +"genericAuthType": "httpQueryAuth", +"queryParameters": { +"parameters": [ +{ +"name": "part", +"value": "snippet,contentDetails,statistics" +}, +{ +"name": "id", +"value": "={{ $('Execute Workflow Trigger').item.json.query.video_id }}" +} +] +} +}, +"credentials": { +"httpQueryAuth": { +"id": "1DXeuNaLSixqGPaU", +"name": "Query Auth account Youtube" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "c1ff3837-8d7e-49ad-a333-c177833fcd05", +"name": "Edit Fields", +"type": "n8n-nodes-base.set", +"position": [ +2224, +1598 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "469d89ba-23fc-482a-b4ae-ce5d3bc13579", +"name": "response", +"type": "string", +"value": "={{ JSON.stringify(` Comments: ${$json.items.map(item => { const topLevelComment = `${item.snippet.topLevelComment.snippet.authorDisplayName}: ${item.snippet.topLevelComment.snippet.textOriginal}`; const replies = item.replies?.comments.map(reply => `${reply.snippet.authorDisplayName}: ${reply.snippet.textOriginal}` ).join('\\n') || ''; return [topLevelComment, replies].filter(Boolean).join('\\n'); }).join('\\n\\n')} `) }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "5f0c44fe-2523-4170-a27d-0ccd1bef24a7", +"name": "Run Query", +"type": "n8n-nodes-base.httpRequest", +"position": [ +2064, +1758 +], +"parameters": { +"url": "=https://www.googleapis.com/youtube/v3/search", +"options": {}, +"sendQuery": true, +"authentication": "genericCredentialType", +"genericAuthType": "httpQueryAuth", +"queryParameters": { +"parameters": [ +{ +"name": "part", +"value": "snippet" +}, +{ +"name": "q", +"value": "={{ $('Execute Workflow Trigger').item.json.query.query }}" +}, +{ +"name": "order", +"value": "={{ $('Execute Workflow Trigger').item.json.query.order }}" +}, +{ +"name": "type", +"value": "={{ $('Execute Workflow Trigger').item.json.query.type }}" +}, +{ +"name": "maxResults", +"value": "={{ $('Execute Workflow Trigger').item.json.query.number_of_videos }}" +}, +{ +"name": "publishedAfter", +"value": "={{ $('Execute Workflow Trigger').item.json.query.publishedAfter }}" +} +] +} +}, +"credentials": { +"httpQueryAuth": { +"id": "1DXeuNaLSixqGPaU", +"name": "Query Auth account Youtube" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "3e192718-6710-4143-ac6e-15df79ee5363", +"name": "Get Videos by Channel", +"type": "n8n-nodes-base.httpRequest", +"position": [ +2064, +1918 +], +"parameters": { +"url": "=https://www.googleapis.com/youtube/v3/search", +"options": {}, +"sendQuery": true, +"authentication": "genericCredentialType", +"genericAuthType": "httpQueryAuth", +"queryParameters": { +"parameters": [ +{ +"name": "part", +"value": "snippet" +}, +{ +"name": "channelId", +"value": "={{ $('Execute Workflow Trigger').item.json.query.channel_id }}" +}, +{ +"name": "order", +"value": "={{ $('Execute Workflow Trigger').item.json.query.order }}" +}, +{ +"name": "maxResults", +"value": "={{ $('Execute Workflow Trigger').item.json.query.number_of_videos }}" +}, +{ +"name": "type", +"value": "video" +}, +{ +"name": "publishedAfter", +"value": "={{ $('Execute Workflow Trigger').item.json.query.publishedAfter }}" +} +] +} +}, +"credentials": { +"httpQueryAuth": { +"id": "1DXeuNaLSixqGPaU", +"name": "Query Auth account Youtube" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "8bcb50a4-0cd1-4311-ac6a-2ee8653cfb71", +"name": "Response", +"type": "n8n-nodes-base.set", +"position": [ +2564, +1598 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "cfdbe2f5-921e-496d-87bd-9c57fdc22a7a", +"name": "response", +"type": "object", +"value": "={{$json}}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "7f5a36d3-6710-4e69-8459-7c8c748ee7d9", +"name": "Switch", +"type": "n8n-nodes-base.switch", +"position": [ +1624, +1578 +], +"parameters": { +"rules": { +"values": [ +{ +"outputKey": "get_channel_details", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"operator": { +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $('Execute Workflow Trigger').item.json.command }}", +"rightValue": "get_channel_details" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "video_details", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "26a3ffe8-c8a6-4564-8d18-5494a8059372", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $('Execute Workflow Trigger').item.json.command }}", +"rightValue": "video_details" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "comments", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "0f51cc26-2e42-42e1-a5c2-cb1d2e384962", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $('Execute Workflow Trigger').item.json.command }}", +"rightValue": "comments" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "search", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "51031140-5ceb-48aa-9f33-d314131a9653", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $('Execute Workflow Trigger').item.json.command }}", +"rightValue": "search" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "videos", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "f160bf0a-423f-448d-ab80-50a0b6a177ca", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $('Execute Workflow Trigger').item.json.command }}", +"rightValue": "videos" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "analyze_thumbnail", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "29542ac4-7b9d-413f-aabb-a1cdabed2fa7", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $('Execute Workflow Trigger').item.json.command }}", +"rightValue": "analyze_thumbnail" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "video_transcription", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "35fc39b8-6cf1-4ea6-9609-4a195c5526f8", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $('Execute Workflow Trigger').item.json.command }}", +"rightValue": "video_transcription" +} +] +}, +"renameOutput": true +} +] +}, +"options": {} +}, +"typeVersion": 3.2 +}, +{ +"id": "df432d53-33bf-4e91-9ead-7f4b36bd788a", +"name": "Get Video Transcription", +"type": "n8n-nodes-base.httpRequest", +"position": [ +2064, +2238 +], +"parameters": { +"url": "=https://api.apify.com/v2/acts/dB9f4B02ocpTICIEY/run-sync-get-dataset-items", +"method": "POST", +"options": {}, +"jsonBody": "={\n \"startUrls\": [\n \"{{ $('Execute Workflow Trigger').item.json.query.video_url }}\"\n ]\n}", +"sendBody": true, +"specifyBody": "json", +"authentication": "genericCredentialType", +"genericAuthType": "httpQueryAuth" +}, +"credentials": { +"httpQueryAuth": { +"id": "XDavOaI9qH5Zi3QC", +"name": "Apify" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "8079e5c9-4a52-45ce-ac41-7fc707177a5a", +"name": "OpenAI", +"type": "@n8n/n8n-nodes-langchain.openAi", +"position": [ +2064, +2078 +], +"parameters": { +"text": "={{ $('Execute Workflow Trigger').item.json.query.prompt }}", +"modelId": { +"__rl": true, +"mode": "list", +"value": "gpt-4o", +"cachedResultName": "GPT-4O" +}, +"options": {}, +"resource": "image", +"imageUrls": "={{ $('Execute Workflow Trigger').item.json.query.url }}", +"operation": "analyze" +}, +"credentials": { +"openAiApi": { +"id": "SphXAX7rlwRLkiox", +"name": "Test club key" +} +}, +"typeVersion": 1.7 +}, +{ +"id": "7847e82a-fe82-498c-8c14-4c1c718d632c", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1380, +1140 +], +"parameters": { +"width": 1427.3810326521016, +"height": 1313.2689194736308, +"content": "## Scenario 2: Agent tools" +}, +"typeVersion": 1 +}, +{ +"id": "3a0fbbb0-4c0e-41f1-abb3-c87e955ad1b3", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1540, +960 +], +"parameters": { +"color": 4, +"width": 266.7375650720483, +"height": 80, +"content": "### Replace credentials" +}, +"typeVersion": 1 +}, +{ +"id": "363eaca0-aaa5-4551-845f-528f19bba57a", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2004, +1178 +], +"parameters": { +"color": 4, +"width": 266.7375650720483, +"height": 80, +"content": "### Replace credentials in all nodes - Apify, OpenAI, Google" +}, +"typeVersion": 1 +} +], +"pinData": { +"Execute Workflow Trigger": [ +{ +"query": { +"type": "video", +"query": "Web scraping data with n8n and Puppeteer", +"sorting": "relevance" +}, +"command": "search" +} +] +}, +"connections": { +"OpenAI": { +"main": [ +[ +{ +"node": "Response", +"type": "main", +"index": 0 +} +] +] +}, +"Switch": { +"main": [ +[ +{ +"node": "Get Channel Details", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Get Video Description", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Get Comments", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Run Query", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Get Videos by Channel", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "OpenAI", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Get Video Transcription", +"type": "main", +"index": 0 +} +] +] +}, +"search": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Run Query": { +"main": [ +[ +{ +"node": "Response", +"type": "main", +"index": 0 +} +] +] +}, +"Edit Fields": { +"main": [ +[ +{ +"node": "Response", +"type": "main", +"index": 0 +} +] +] +}, +"Get Comments": { +"main": [ +[ +{ +"node": "Edit Fields", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"analyze_thumbnail": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"get_list_of_videos": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Get Channel Details": { +"main": [ +[ +{ +"node": "Response", +"type": "main", +"index": 0 +} +] +] +}, +"get_channel_details": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"video_transcription": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Postgres Chat Memory": { +"ai_memory": [ +[ +{ +"node": "AI Agent", +"type": "ai_memory", +"index": 0 +} +] +] +}, +"get_list_of_comments": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Get Video Description": { +"main": [ +[ +{ +"node": "Response", +"type": "main", +"index": 0 +} +] +] +}, +"Get Videos by Channel": { +"main": [ +[ +{ +"node": "Response", +"type": "main", +"index": 0 +} +] +] +}, +"get_video_description": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Get Video Transcription": { +"main": [ +[ +{ +"node": "Response", +"type": "main", +"index": 0 +} +] +] +}, +"Execute Workflow Trigger": { +"main": [ +[ +{ +"node": "Switch", +"type": "main", +"index": 0 +} +] +] +}, +"When chat message received": { +"main": [ +[ +{ +"node": "AI Agent", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Extract license plate number from image uploaded via an n8n form.txt b/Extract license plate number from image uploaded via an n8n form.txt new file mode 100644 index 0000000..b8b068a --- /dev/null +++ b/Extract license plate number from image uploaded via an n8n form.txt @@ -0,0 +1,182 @@ +{ +"id": "B37wvB0tdKgjuabw", +"meta": { +"instanceId": "98bf0d6aef1dd8b7a752798121440fb171bf7686b95727fd617f43452393daa3", +"templateCredsSetupCompleted": true +}, +"name": "Image to license plate number", +"tags": [], +"nodes": [ +{ +"id": "a656334a-0135-4d93-a6df-ca97222c9753", +"name": "Basic LLM Chain", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +-140, +-380 +], +"parameters": { +"text": "={{ $json.prompt }}", +"messages": { +"messageValues": [ +{ +"type": "HumanMessagePromptTemplate", +"messageType": "imageBinary", +"binaryImageDataKey": "Image" +} +] +}, +"promptType": "define" +}, +"typeVersion": 1.5 +}, +{ +"id": "41a90592-2a91-40ff-abf4-3a795733d521", +"name": "FormResultPage", +"type": "n8n-nodes-base.form", +"position": [ +220, +-380 +], +"webhookId": "218822fe-5eb9-4451-ae8a-14b8f484fdde", +"parameters": { +"options": { +"formTitle": "" +}, +"operation": "completion", +"completionTitle": "Extracted information:", +"completionMessage": "={{ $json.text }}" +}, +"typeVersion": 1 +}, +{ +"id": "c23b95d9-b7a2-4e9e-a019-5724a9662abd", +"name": "OpenRouter LLM", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter", +"position": [ +-60, +-180 +], +"parameters": { +"model": "={{ $json.model }}", +"options": {} +}, +"credentials": { +"openRouterApi": { +"id": "bs7tPtvgDTJNGAFJ", +"name": "OpenRouter account" +} +}, +"typeVersion": 1 +}, +{ +"id": "8298cd51-8c47-4bc4-af78-2c216207ef76", +"name": "Settings", +"type": "n8n-nodes-base.set", +"position": [ +-340, +-380 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "1b8381dc-5b9a-42a2-8a67-cc706b433180", +"name": "model", +"type": "string", +"value": "openai/gpt-4o" +}, +{ +"id": "72aec130-ab56-4e61-b60b-9a31dd8d02e6", +"name": "prompt", +"type": "string", +"value": "Extract the number of the license plate on the front-most car depicted in the attached image and return only the extracted characters without any other text or structure." +} +] +}, +"includeOtherFields": true +}, +"typeVersion": 3.4 +}, +{ +"id": "fae79fc9-b510-44a4-beec-4dc26dc2a13a", +"name": "FromTrigger", +"type": "n8n-nodes-base.formTrigger", +"position": [ +-560, +-380 +], +"webhookId": "41e3f34b-7abe-4c64-95cd-2942503d5e98", +"parameters": { +"options": {}, +"formTitle": "Analyse image", +"formFields": { +"values": [ +{ +"fieldType": "file", +"fieldLabel": "Image", +"requiredField": true, +"acceptFileTypes": ".jpg, .png" +} +] +}, +"responseMode": "lastNode", +"formDescription": "To analyse an image, upload it here." +}, +"typeVersion": 2.2 +} +], +"active": true, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "5b9c53b9-3998-4676-999d-1ba117bf6695", +"connections": { +"Settings": { +"main": [ +[ +{ +"node": "Basic LLM Chain", +"type": "main", +"index": 0 +} +] +] +}, +"FromTrigger": { +"main": [ +[ +{ +"node": "Settings", +"type": "main", +"index": 0 +} +] +] +}, +"OpenRouter LLM": { +"ai_languageModel": [ +[ +{ +"node": "Basic LLM Chain", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Basic LLM Chain": { +"main": [ +[ +{ +"node": "FormResultPage", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Extract personal data with self-hosted LLM Mistral NeMo.txt b/Extract personal data with self-hosted LLM Mistral NeMo.txt new file mode 100644 index 0000000..6d49542 --- /dev/null +++ b/Extract personal data with self-hosted LLM Mistral NeMo.txt @@ -0,0 +1,292 @@ +{ +"id": "HMoUOg8J7RzEcslH", +"meta": { +"instanceId": "3f91626b10fcfa8a3d3ab8655534ff3e94151838fd2709ecd2dcb14afb3d061a", +"templateCredsSetupCompleted": true +}, +"name": "Extract personal data with a self-hosted LLM Mistral NeMo", +"tags": [], +"nodes": [ +{ +"id": "7e67ae65-88aa-4e48-aa63-2d3a4208cf4b", +"name": "When chat message received", +"type": "@n8n/n8n-nodes-langchain.chatTrigger", +"position": [ +-500, +20 +], +"webhookId": "3a7b0ea1-47f3-4a94-8ff2-f5e1f3d9dc32", +"parameters": { +"options": {} +}, +"typeVersion": 1.1 +}, +{ +"id": "e064921c-69e6-4cfe-a86e-4e3aa3a5314a", +"name": "Ollama Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOllama", +"position": [ +-280, +420 +], +"parameters": { +"model": "mistral-nemo:latest", +"options": { +"useMLock": true, +"keepAlive": "2h", +"temperature": 0.1 +} +}, +"credentials": { +"ollamaApi": { +"id": "vgKP7LGys9TXZ0KK", +"name": "Ollama account" +} +}, +"typeVersion": 1 +}, +{ +"id": "fe1379da-a12e-4051-af91-9d67a7c9a76b", +"name": "Auto-fixing Output Parser", +"type": "@n8n/n8n-nodes-langchain.outputParserAutofixing", +"position": [ +-200, +220 +], +"parameters": { +"options": { +"prompt": "Instructions:\n--------------\n{instructions}\n--------------\nCompletion:\n--------------\n{completion}\n--------------\n\nAbove, the Completion did not satisfy the constraints given in the Instructions.\nError:\n--------------\n{error}\n--------------\n\nPlease try again. Please only respond with an answer that satisfies the constraints laid out in the Instructions:" +} +}, +"typeVersion": 1 +}, +{ +"id": "b6633b00-6ebb-43ca-8e5c-664a53548c17", +"name": "Structured Output Parser", +"type": "@n8n/n8n-nodes-langchain.outputParserStructured", +"position": [ +60, +400 +], +"parameters": { +"schemaType": "manual", +"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\",\n \"description\": \"Name of the user\"\n },\n \"surname\": {\n \"type\": \"string\",\n \"description\": \"Surname of the user\"\n },\n \"commtype\": {\n \"type\": \"string\",\n \"enum\": [\"email\", \"phone\", \"other\"],\n \"description\": \"Method of communication\"\n },\n \"contacts\": {\n \"type\": \"string\",\n \"description\": \"Contact details. ONLY IF PROVIDED\"\n },\n \"timestamp\": {\n \"type\": \"string\",\n \"format\": \"date-time\",\n \"description\": \"When the communication occurred\"\n },\n \"subject\": {\n \"type\": \"string\",\n \"description\": \"Brief description of the communication topic\"\n }\n },\n \"required\": [\"name\", \"commtype\"]\n}" +}, +"typeVersion": 1.2 +}, +{ +"id": "23681a6c-cf62-48cb-86ee-08d5ce39bc0a", +"name": "Basic LLM Chain", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"onError": "continueErrorOutput", +"position": [ +-240, +20 +], +"parameters": { +"messages": { +"messageValues": [ +{ +"message": "=Please analyse the incoming user request. Extract information according to the JSON schema. Today is: \"{{ $now.toISO() }}\"" +} +] +}, +"hasOutputParser": true +}, +"typeVersion": 1.5 +}, +{ +"id": "8f4d1b4b-58c0-41ec-9636-ac555e440821", +"name": "On Error", +"type": "n8n-nodes-base.noOp", +"position": [ +200, +140 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "f4d77736-4470-48b4-8f61-149e09b70e3e", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-560, +-160 +], +"parameters": { +"color": 2, +"width": 960, +"height": 500, +"content": "## Update data source\nWhen you change the data source, remember to update the `Prompt Source (User Message)` setting in the **Basic LLM Chain node**." +}, +"typeVersion": 1 +}, +{ +"id": "5fd273c8-e61d-452b-8eac-8ac4b7fff6c2", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-560, +340 +], +"parameters": { +"color": 2, +"width": 440, +"height": 220, +"content": "## Configure local LLM\nOllama offers additional settings \nto optimize model performance\nor memory usage." +}, +"typeVersion": 1 +}, +{ +"id": "63cbf762-0134-48da-a6cd-0363e870decd", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +0, +340 +], +"parameters": { +"color": 2, +"width": 400, +"height": 220, +"content": "## Define JSON Schema" +}, +"typeVersion": 1 +}, +{ +"id": "9625294f-3cb4-4465-9dae-9976e0cf5053", +"name": "Extract JSON Output", +"type": "n8n-nodes-base.set", +"position": [ +200, +-80 +], +"parameters": { +"mode": "raw", +"options": {}, +"jsonOutput": "={{ $json.output }}\n" +}, +"typeVersion": 3.4 +}, +{ +"id": "2c6fba3b-0ffe-4112-b904-823f52cc220b", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-560, +200 +], +"parameters": { +"width": 960, +"height": 120, +"content": "If the LLM response does not pass \nthe **Structured Output Parser** checks,\n**Auto-Fixer** will call the model again with a different \nprompt to correct the original response." +}, +"typeVersion": 1 +}, +{ +"id": "c73ba1ca-d727-4904-a5fd-01dd921a4738", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-560, +460 +], +"parameters": { +"height": 80, +"content": "The same LLM connects to both **Basic LLM Chain** and to the **Auto-fixing Output Parser**. \n" +}, +"typeVersion": 1 +}, +{ +"id": "193dd153-8511-4326-aaae-47b89d0cd049", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +200, +440 +], +"parameters": { +"width": 200, +"height": 100, +"content": "When the LLM model responds, the output is checked in the **Structured Output Parser**" +}, +"typeVersion": 1 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "9f3721a8-f340-43d5-89e7-3175c29c2f3a", +"connections": { +"Basic LLM Chain": { +"main": [ +[ +{ +"node": "Extract JSON Output", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "On Error", +"type": "main", +"index": 0 +} +] +] +}, +"Ollama Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Auto-fixing Output Parser", +"type": "ai_languageModel", +"index": 0 +}, +{ +"node": "Basic LLM Chain", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Structured Output Parser": { +"ai_outputParser": [ +[ +{ +"node": "Auto-fixing Output Parser", +"type": "ai_outputParser", +"index": 0 +} +] +] +}, +"Auto-fixing Output Parser": { +"ai_outputParser": [ +[ +{ +"node": "Basic LLM Chain", +"type": "ai_outputParser", +"index": 0 +} +] +] +}, +"When chat message received": { +"main": [ +[ +{ +"node": "Basic LLM Chain", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Extract spending history from gmail to google sheet.txt b/Extract spending history from gmail to google sheet.txt new file mode 100644 index 0000000..5a19eb2 --- /dev/null +++ b/Extract spending history from gmail to google sheet.txt @@ -0,0 +1,1134 @@ +{ +"id": "nkMjcOC4hpte1a0t", +"meta": { +"instanceId": "3986dc65ca3ddc4ee46e71fc194b0a9d4ef46d960a5e71624f9f7eaa198213cb", +"templateCredsSetupCompleted": true +}, +"name": "Extract spend details (template)", +"tags": [ +{ +"id": "9mCuuNEpnYNvVzb8", +"name": "Finance", +"createdAt": "2024-09-15T07:22:30.749Z", +"updatedAt": "2024-09-15T07:22:30.749Z" +} +], +"nodes": [ +{ +"id": "8e1e0861-9f06-4fe2-a9c1-423bab246959", +"name": "Get invoice", +"type": "n8n-nodes-base.gmailTrigger", +"position": [ +600, +380 +], +"parameters": { +"simple": false, +"filters": { +"labelIds": [ +"Label_7885838942566773656" +] +}, +"options": { +"downloadAttachments": true +}, +"pollTimes": { +"item": [ +{ +"mode": "everyMinute" +} +] +} +}, +"credentials": { +"gmailOAuth2": { +"id": "fegneFqi8XJX3NJH", +"name": "Gmail account (hana@hanamizuki.tw)" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "364fe355-672a-4074-800a-a7496c4fb1b2", +"name": "Get payment", +"type": "n8n-nodes-base.gmailTrigger", +"position": [ +600, +580 +], +"parameters": { +"simple": false, +"filters": { +"labelIds": [ +"Label_371722915607774622" +] +}, +"options": { +"downloadAttachments": true +}, +"pollTimes": { +"item": [ +{ +"mode": "everyMinute" +} +] +} +}, +"credentials": { +"gmailOAuth2": { +"id": "fegneFqi8XJX3NJH", +"name": "Gmail account (hana@hanamizuki.tw)" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "e3218faf-2486-46e0-bf43-3bc52927e2bd", +"name": "Extract invoice", +"type": "n8n-nodes-base.extractFromFile", +"notes": "No attachements", +"onError": "continueRegularOutput", +"position": [ +820, +380 +], +"parameters": { +"options": { +"password": "E223706995" +}, +"operation": "pdf", +"binaryPropertyName": "attachment_0" +}, +"typeVersion": 1 +}, +{ +"id": "3772b3dc-7601-4005-9b61-263b2c1abd5f", +"name": "Extract payment", +"type": "n8n-nodes-base.extractFromFile", +"notes": "No attachements", +"onError": "continueRegularOutput", +"position": [ +820, +580 +], +"parameters": { +"options": { +"password": "E223706995" +}, +"operation": "pdf", +"binaryPropertyName": "attachment_0" +}, +"typeVersion": 1 +}, +{ +"id": "10d57038-940e-47aa-84ea-3850f61ac757", +"name": "HTML", +"type": "n8n-nodes-base.html", +"notes": "\".spend-table\" here is an example when the email use \"spend\" html tags to display each spends.\ne.g.\n
Spend 1
\n
Spend 2
", +"position": [ +1440, +200 +], +"parameters": { +"options": {}, +"operation": "extractHtmlContent", +"dataPropertyName": "=html", +"extractionValues": { +"values": [ +{ +"key": "spend", +"cssSelector": ".spend-table", +"returnArray": true +} +] +} +}, +"typeVersion": 1.2 +}, +{ +"id": "dae6d22e-587d-4102-b006-20a341ede5ee", +"name": "Split Out", +"type": "n8n-nodes-base.splitOut", +"position": [ +1660, +200 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "spend" +}, +"typeVersion": 1 +}, +{ +"id": "0d75443d-0d23-4120-95e5-b3128a760fb4", +"name": "Structured Output Parser1", +"type": "@n8n/n8n-nodes-langchain.outputParserStructured", +"position": [ +2500, +640 +], +"parameters": { +"schemaType": "manual", +"inputSchema": "{\n \"title\": \"Expense Record Schema\",\n \"description\": \"Schema used to parse expense record emails, including date, service name, transaction details, amount, category, currency, and card.\",\n \"type\": \"object\",\n \"properties\": {\n \"date\": {\n \"type\": \"string\",\n \"description\": \"Transaction date, can refer to the email date or the consumption date within the content. If there are multiple dates, use the earliest one. The format is 'YYYY-MM-DD hh:mm', e.g., '2024-09-02 10:12'.\",\n \"examples\": [\"2024-09-02 10:12\"]\n },\n \"service\": {\n \"type\": [\"string\", \"null\"],\n \"description\": \"Name of the service or store, such as 'GOOGLE', 'Uber', etc.\",\n \"examples\": [\"GOOGLE\", \"Uber Eats\", \"Uber\", \"CLAUDE.AI\"]\n },\n \"details\": {\n \"type\": [\"string\", \"null\"],\n \"description\": \"Detailed transaction information, such as overseas card usage, online transactions, restaurant names, or consumption details. If none, can be left blank or null.\",\n \"examples\": [\"Uber: from Fuxing North Road to Minquan East Road\", \"Restaurant name\", null]\n },\n \"amount\": {\n \"type\": \"number\",\n \"description\": \"Transaction amount. If in USD, keep two decimal places (e.g., 50.12); if in TWD, use integers (e.g., 550).\",\n \"examples\": [50.12, 550]\n },\n \"category\": {\n \"type\": \"string\",\n \"description\": \"Transaction category\",\n \"enum\": [\"Food & Beverage\", \"Transportation\", \"Daily Necessities\", \"Housing\", \"Electronics\", \"Beauty & Hair\", \"Apparel & Accessories\", \"Medical & Healthcare\", \"Pets\", \"Education\", \"Entertainment\", \"Cloud Services\", \"Automobile\", \"Gifts\", \"Family Care\", \"Counseling\", \"Insurance\", \"Taxes\", \"Transfer Fees\", \"Music\", \"Fitness\", \"Travel\", \"Lending\", \"Donations\", \"Advertising\", \"Finance\"],\n \"examples\": [\"Food & Beverage\", \"Transportation\"]\n },\n \"currency\": {\n \"type\": \"string\",\n \"description\": \"Currency code used in the transaction. If the amount starts with NT$, then currency is TWD.\",\n \"enum\": [\"TWD\", \"USD\", \"JPY\", \"EUR\", \"SGD\"],\n \"examples\": [\"USD\", \"TWD\"]\n },\n \"card\": {\n \"type\": [\"string\", \"null\"],\n \"description\": \"Credit card used for the transaction.\",\n \"enum\": [\"HSBC 3088\", \"HSBC 3854\", \"Fubon Card\", \"Crypto.com Card\", \"Cathay Card\", null],\n \"examples\": [\"HSBC 3088\", \"HSBC 3854\"]\n }\n },\n \"required\": [\"date\", \"amount\", \"category\", \"currency\"]\n}\n" +}, +"typeVersion": 1.2 +}, +{ +"id": "7ade499c-015b-4903-8129-6c135264bf75", +"name": "Google Gemini Chat Model1", +"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini", +"position": [ +2320, +640 +], +"parameters": { +"options": {}, +"modelName": "models/gemini-1.5-flash" +}, +"credentials": { +"googlePalmApi": { +"id": "QR3KfTwhKpbgAGWU", +"name": "Google Gemini(PaLM) Api account" +} +}, +"typeVersion": 1 +}, +{ +"id": "10fe4a38-139b-4284-9e86-dd36e472f59e", +"name": "Send", +"type": "n8n-nodes-base.googleSheets", +"position": [ +2740, +480 +], +"parameters": { +"columns": { +"value": { +"date": "={{ $json.output.date }}", +"amount": "={{ $json.output.amount }}", +"source": "n8n", +"details": "={{ $json.output.details }}", +"payment": "={{ $json.output.card }}", +"service": "={{ $json.output.service }}", +"category": "={{ $json.output.category }}", +"currency": "={{ $json.output.currency }}" +}, +"schema": [ +{ +"id": "date", +"type": "string", +"display": true, +"required": false, +"displayName": "date", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "service", +"type": "string", +"display": true, +"required": false, +"displayName": "service", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "details", +"type": "string", +"display": true, +"required": false, +"displayName": "details", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "amount", +"type": "string", +"display": true, +"required": false, +"displayName": "amount", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "category", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "category", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "currency", +"type": "string", +"display": true, +"required": false, +"displayName": "currency", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "payment", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "payment", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "source", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "source", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [] +}, +"options": {}, +"operation": "append", +"sheetName": { +"__rl": true, +"mode": "list", +"value": 2071031170, +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ccwhQeUSUkINccAucC6_clRyNF5Mw4IjIxAtcH4ftIs/edit#gid=2071031170", +"cachedResultName": "raw data 2" +}, +"documentId": { +"__rl": true, +"mode": "url", +"value": "https://docs.google.com/spreadsheets/d/1ccwhQeUSUkINccAucC6_clRyNF5Mw4IjIxAtcH4ftIs/edit?gid=370005862#gid=370005862" +} +}, +"credentials": { +"googleSheetsOAuth2Api": { +"id": "flAcWUeyvdjh7MiW", +"name": "Google Sheets account: hana@hanamizuki.tw (GCP: n8n)" +} +}, +"retryOnFail": true, +"typeVersion": 4.5 +}, +{ +"id": "87ab4932-aae5-4c5a-a175-c782bebdf781", +"name": "Set data 0", +"type": "n8n-nodes-base.set", +"position": [ +1860, +200 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "75b16672-71cf-4157-bcb6-683099ff1620", +"name": "email_date", +"type": "string", +"value": "={{ $('Switch').item.json.date }}" +}, +{ +"id": "3298f680-5d17-42fd-8b41-a6ca621af37d", +"name": "email_subject", +"type": "string", +"value": "={{ $('Switch').item.json.subject }}" +}, +{ +"id": "cf7181b7-fef9-437a-8bbe-cd4a4eda85b8", +"name": "email_content", +"type": "string", +"value": "={{ $ifEmpty($json.spend, $ifEmpty( $json.text, $json.html)) }}" +}, +{ +"id": "1a524cb4-6975-4d45-ac0e-f1ac1f9b0417", +"name": "email_type", +"type": "number", +"value": "=0" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "c2829f41-1e3f-40bc-8d4b-9fd1bac41381", +"name": "Set data 1", +"type": "n8n-nodes-base.set", +"position": [ +1660, +440 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "75b16672-71cf-4157-bcb6-683099ff1620", +"name": "email_date", +"type": "string", +"value": "={{ $json.date }}" +}, +{ +"id": "3298f680-5d17-42fd-8b41-a6ca621af37d", +"name": "email_subject", +"type": "string", +"value": "={{ $json.subject }}" +}, +{ +"id": "cf7181b7-fef9-437a-8bbe-cd4a4eda85b8", +"name": "email_content", +"type": "string", +"value": "={{ $ifEmpty( $json.text, $json.html) }}" +}, +{ +"id": "1a524cb4-6975-4d45-ac0e-f1ac1f9b0417", +"name": "email_type", +"type": "number", +"value": "=1" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "ecf9ea3c-3f34-43ef-b101-ca4a420e4c24", +"name": "Set data 2", +"type": "n8n-nodes-base.set", +"position": [ +1640, +740 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "75b16672-71cf-4157-bcb6-683099ff1620", +"name": "email_date", +"type": "string", +"value": "={{ $json.date }}" +}, +{ +"id": "3298f680-5d17-42fd-8b41-a6ca621af37d", +"name": "email_subject", +"type": "string", +"value": "={{ $json.subject }}" +}, +{ +"id": "cf7181b7-fef9-437a-8bbe-cd4a4eda85b8", +"name": "email_content", +"type": "string", +"value": "={{ $ifEmpty( $json.text, $json.html) }}" +}, +{ +"id": "1a524cb4-6975-4d45-ac0e-f1ac1f9b0417", +"name": "email_type", +"type": "number", +"value": "=2" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "0d9f8bde-af54-480c-bdc9-15cd5b0e6f28", +"name": "Invoice data", +"type": "n8n-nodes-base.set", +"position": [ +1040, +380 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "ac7c18ba-1944-4019-aa85-03d7751a7e1c", +"name": "html", +"type": "string", +"value": "={{ $('Get invoice').item.json.html }}" +}, +{ +"id": "5eb54501-9c55-437d-9918-e5eff92e2229", +"name": "subject", +"type": "string", +"value": "={{ $('Get invoice').item.json.subject }}" +}, +{ +"id": "87eebc48-0b95-46ae-b41b-b6540b1afaa9", +"name": "date", +"type": "string", +"value": "={{ $('Get invoice').item.json.date }}" +}, +{ +"id": "c6b75367-239e-4e88-9e17-90ee75a064e2", +"name": "text", +"type": "string", +"value": "={{ $('Get invoice').item.json.text }} \\n {{ $json.text }}" +}, +{ +"id": "7d5b4b42-6b90-4ffe-ab8f-4288771d1302", +"name": "label", +"type": "string", +"value": "={{ $('Get invoice').item.json.labelIds }}" +}, +{ +"id": "551ea1c3-01ca-4615-9d52-a880e24252ed", +"name": "from", +"type": "string", +"value": "={{ $('Get invoice').item.json.from.text }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "c1c4c490-d7a9-4b16-a81b-a338103764b6", +"name": "Payment data", +"type": "n8n-nodes-base.set", +"position": [ +1040, +580 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "ac7c18ba-1944-4019-aa85-03d7751a7e1c", +"name": "html", +"type": "string", +"value": "={{ $('Get payment').item.json.html }}" +}, +{ +"id": "5eb54501-9c55-437d-9918-e5eff92e2229", +"name": "subject", +"type": "string", +"value": "={{ $('Get payment').item.json.subject }}" +}, +{ +"id": "87eebc48-0b95-46ae-b41b-b6540b1afaa9", +"name": "date", +"type": "string", +"value": "={{ $('Get payment').item.json.date }}" +}, +{ +"id": "c6b75367-239e-4e88-9e17-90ee75a064e2", +"name": "text", +"type": "string", +"value": "={{ $('Get payment').item.json.text }} \\n {{ $json.text }}" +}, +{ +"id": "7d5b4b42-6b90-4ffe-ab8f-4288771d1302", +"name": "label", +"type": "string", +"value": "={{ $('Get payment').item.json.labelIds }}" +}, +{ +"id": "2c976be1-48b8-42fa-b1c9-2fd315da89ae", +"name": "from", +"type": "string", +"value": "={{ $('Get payment').item.json.from.text }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "01c5a934-9412-4ef9-81a8-c4aef19c8868", +"name": "Switch", +"type": "n8n-nodes-base.switch", +"position": [ +1300, +480 +], +"parameters": { +"rules": { +"values": [ +{ +"outputKey": "Multiple payment info in one mail", +"conditions": { +"options": { +"version": 1, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"operator": { +"type": "string", +"operation": "contains" +}, +"leftValue": "={{ $json.from }}", +"rightValue": "service@pxbillrc01.cathaybk.com.tw" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "One payment info in one mail", +"conditions": { +"options": { +"version": 1, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "47e3b84f-903c-4594-9297-785cfbea0316", +"operator": { +"type": "string", +"operation": "regex" +}, +"leftValue": "={{ $json.from }}", +"rightValue": "\\b(?:noreply@messaging\\.hsbc\\.com\\.tw|hello@crypto\\.com|taipeifubon\\.com\\.tw)\\b" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "Invoices", +"conditions": { +"options": { +"version": 1, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "db9d40f1-8fa4-4908-9010-985072b3f319", +"operator": { +"type": "string", +"operation": "notRegex" +}, +"leftValue": "={{ $json.from }}", +"rightValue": "\\b(?:noreply@messaging\\.hsbc\\.com\\.tw|hello@crypto\\.com|taipeifubon\\.com\\.tw)\\b" +} +] +}, +"renameOutput": true +} +] +}, +"options": {} +}, +"executeOnce": false, +"typeVersion": 3.1, +"alwaysOutputData": false +}, +{ +"id": "250bbd9a-3d22-4a04-910c-7cec437b3c33", +"name": "Groq Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatGroq", +"position": [ +2320, +1120 +], +"parameters": { +"model": "llama-3.2-11b-text-preview", +"options": {} +}, +"credentials": { +"groqApi": { +"id": "vaG2nZFaKeQarQHw", +"name": "Groq account" +} +}, +"typeVersion": 1 +}, +{ +"id": "b8d2b2fc-748c-43c5-a82b-d5e7357bbef8", +"name": "Structured Output Parser", +"type": "@n8n/n8n-nodes-langchain.outputParserStructured", +"position": [ +2520, +1120 +], +"parameters": { +"schemaType": "manual", +"inputSchema": "{\n \"title\": \"Transaction Record Schema\",\n \"description\": \"Schema for parsing transaction record emails, including date, service name, transaction details, amount, category, currency, and card.\",\n \"type\": \"object\",\n \"properties\": {\n \"date\": {\n \"type\": \"string\",\n \"description\": \"Transaction date, can refer to email date or transaction date in content. If multiple dates exist, use the earliest date. Format is 'YYYY-MM-DD hh:mm', e.g., '2024-09-02 10:12'.\",\n \"examples\": [\"2024-09-02 10:12\"]\n },\n \"service\": {\n \"type\": [\"string\", \"null\"],\n \"description\": \"Name of service or store, e.g., 'GOOGLE', 'Uber', etc.\",\n \"examples\": [\"GOOGLE\", \"Uber Eats\", \"Uber\", \"CLAUDE.AI\"]\n },\n \"details\": {\n \"type\": [\"string\", \"null\"],\n \"description\": \"Detailed transaction information, such as overseas purchase, online purchase, restaurant name, or consumption details. Can be empty or null if not available.\",\n \"examples\": [\"Uber: From Fuxing North Road to Minquan East Road\", \"Restaurant name\", null]\n },\n \"amount\": {\n \"type\": \"number\",\n \"description\": \"Transaction amount. For USD, keep two decimal places (e.g., 50.12); for TWD, use integers (e.g., 550).\",\n \"examples\": [50.12, 550]\n },\n \"category\": {\n \"type\": \"string\",\n \"description\": \"Transaction category\",\n \"enum\": [\"Food & Beverage\", \"Transportation\", \"Daily Necessities\", \"Housing\", \"Electronics\", \"Beauty & Hair\", \"Clothing & Accessories\", \"Healthcare\", \"Pets\", \"Education\", \"Entertainment\", \"Cloud Services\", \"Automotive\", \"Gifts\", \"Family Support\", \"Counseling\", \"Insurance\", \"Taxes\", \"Transfer Fee\", \"Music\", \"Fitness\", \"Travel\", \"Lending\", \"Donations\", \"Advertising\", \"Finance\"],\n \"examples\": [\"Food & Beverage\", \"Transportation\"]\n },\n \"currency\": {\n \"type\": \"string\",\n \"description\": \"Currency code used for the transaction, if amount starts with NT$, currency is TWD.\",\n \"enum\": [\"TWD\", \"USD\", \"JPY\", \"EUR\", \"SGD\"],\n \"examples\": [\"USD\", \"TWD\"]\n }\n },\n \"required\": [\"date\", \"amount\", \"category\", \"currency\"]\n}" +}, +"typeVersion": 1.2 +}, +{ +"id": "39b10715-54fe-4c07-9ca1-afbe43ae519e", +"name": "Send1", +"type": "n8n-nodes-base.googleSheets", +"position": [ +2740, +900 +], +"parameters": { +"columns": { +"value": { +"date": "={{ $json.output.date }}", +"amount": "={{ $json.output.amount }}", +"source": "n8n", +"details": "={{ $json.output.details }}", +"payment": "=", +"service": "={{ $json.output.service }}", +"category": "={{ $json.output.category }}", +"currency": "={{ $json.output.currency }}" +}, +"schema": [ +{ +"id": "date", +"type": "string", +"display": true, +"required": false, +"displayName": "date", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "service", +"type": "string", +"display": true, +"required": false, +"displayName": "service", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "details", +"type": "string", +"display": true, +"required": false, +"displayName": "details", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "amount", +"type": "string", +"display": true, +"required": false, +"displayName": "amount", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "category", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "category", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "currency", +"type": "string", +"display": true, +"required": false, +"displayName": "currency", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "payment", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "payment", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "source", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "source", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [] +}, +"options": {}, +"operation": "append", +"sheetName": { +"__rl": true, +"mode": "list", +"value": 2071031170, +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ccwhQeUSUkINccAucC6_clRyNF5Mw4IjIxAtcH4ftIs/edit#gid=2071031170", +"cachedResultName": "raw data 2" +}, +"documentId": { +"__rl": true, +"mode": "url", +"value": "https://docs.google.com/spreadsheets/d/1ccwhQeUSUkINccAucC6_clRyNF5Mw4IjIxAtcH4ftIs/edit?gid=370005862#gid=370005862" +} +}, +"credentials": { +"googleSheetsOAuth2Api": { +"id": "flAcWUeyvdjh7MiW", +"name": "Google Sheets account: hana@hanamizuki.tw (GCP: n8n)" +} +}, +"retryOnFail": true, +"typeVersion": 4.5 +}, +{ +"id": "112f5198-871e-42f9-9376-5fa074497413", +"name": "Extract details1", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +2320, +900 +], +"parameters": { +"text": "=Email Date: {{ $json.email_date }}\nEmail Subject: {{ $json.email_subject }}\nEmail Content:\n{{ $json.email_content }}", +"messages": { +"messageValues": [ +{ +"message": "=Please analyze the following email to extract transaction details for bookkeeping purposes.\n\nPlease extract relevant transaction details such as transaction date, amount, merchant name, and any other pertinent information, and provide them in a structured format suitable for accounting records." +} +] +}, +"promptType": "define", +"hasOutputParser": true +}, +"retryOnFail": true, +"typeVersion": 1.4 +}, +{ +"id": "b9c3cb29-e68e-4ae0-8930-185c17bc6cab", +"name": "Merge", +"type": "n8n-nodes-base.merge", +"position": [ +2060, +440 +], +"parameters": {}, +"typeVersion": 3 +}, +{ +"id": "b50d632c-b762-4f61-b34a-91f941100668", +"name": "Extract details", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +2320, +480 +], +"parameters": { +"text": "=Email Date: {{ $json.email_date }}\nEmail Subject: {{ $json.email_subject }}\nEmail Content:\n{{ $json.email_content }}\nEmail Source: {{ $json.email_type }}", +"messages": { +"messageValues": [ +{ +"message": "=Please analyze the following email to extract transaction details for bookkeeping purposes. The \"Email Source\" field indicates the origin of the email, where 0 represents Cathay Bank card statements and 1 represents other credit card statements.\n\nPlease extract relevant transaction details such as transaction date, amount, merchant name, and any other pertinent information, and provide them in a structured format suitable for accounting records." +} +] +}, +"promptType": "define", +"hasOutputParser": true +}, +"retryOnFail": true, +"typeVersion": 1.4 +}, +{ +"id": "7a7e2e36-a8b6-48dc-ad57-2f5eea691285", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +500, +220 +], +"parameters": { +"width": 720, +"height": 560, +"content": "# A. Get data\n- Set up labels in Gmail\n- Suggested using Gmail filters to move emails to labels automatically" +}, +"typeVersion": 1 +}, +{ +"id": "108becad-1a7b-4409-9cb3-36a1c7b64786", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1280, +-20 +], +"parameters": { +"width": 920, +"height": 960, +"content": "# B. Deal with the data\n1. Multiple payment info in one mail: input the \"sender\" of the emails that contain more than one payment info. e.g. credit card daily spend notification\n2. One payment info in one mail: input the \"sender\" of the emails that contain only one payment info. e.g. instant credit card spend notification\n3. Invoices: input the mails that contain one invoice in one mail" +}, +"typeVersion": 1 +}, +{ +"id": "7123f576-87f9-4df1-ae24-f3e5289c7234", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2240, +320 +], +"parameters": { +"width": 840, +"height": 980, +"content": "# C. Get spend details and send to google sheet\n- Edit the output schema to fit your google sheet format\n- Edit the prompt to fit your needs" +}, +"typeVersion": 1 +} +], +"active": false, +"pinData": {}, +"settings": { +"callerPolicy": "workflowsFromSameOwner", +"executionOrder": "v1", +"saveManualExecutions": true, +"saveExecutionProgress": true +}, +"versionId": "211d9ccc-7a66-41c8-bda1-eacde400eeff", +"connections": { +"HTML": { +"main": [ +[ +{ +"node": "Split Out", +"type": "main", +"index": 0 +} +] +] +}, +"Merge": { +"main": [ +[ +{ +"node": "Extract details", +"type": "main", +"index": 0 +} +] +] +}, +"Switch": { +"main": [ +[ +{ +"node": "HTML", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Set data 1", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Set data 2", +"type": "main", +"index": 0 +} +] +] +}, +"Split Out": { +"main": [ +[ +{ +"node": "Set data 0", +"type": "main", +"index": 0 +} +] +] +}, +"Set data 0": { +"main": [ +[ +{ +"node": "Merge", +"type": "main", +"index": 0 +} +] +] +}, +"Set data 1": { +"main": [ +[ +{ +"node": "Merge", +"type": "main", +"index": 1 +} +] +] +}, +"Set data 2": { +"main": [ +[ +{ +"node": "Extract details1", +"type": "main", +"index": 0 +} +] +] +}, +"Get invoice": { +"main": [ +[ +{ +"node": "Extract invoice", +"type": "main", +"index": 0 +} +] +] +}, +"Get payment": { +"main": [ +[ +{ +"node": "Extract payment", +"type": "main", +"index": 0 +} +] +] +}, +"Invoice data": { +"main": [ +[ +{ +"node": "Switch", +"type": "main", +"index": 0 +} +] +] +}, +"Payment data": { +"main": [ +[ +{ +"node": "Switch", +"type": "main", +"index": 0 +} +] +] +}, +"Extract details": { +"main": [ +[ +{ +"node": "Send", +"type": "main", +"index": 0 +} +] +] +}, +"Extract invoice": { +"main": [ +[ +{ +"node": "Invoice data", +"type": "main", +"index": 0 +} +] +] +}, +"Extract payment": { +"main": [ +[ +{ +"node": "Payment data", +"type": "main", +"index": 0 +} +] +] +}, +"Groq Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Extract details1", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Extract details1": { +"main": [ +[ +{ +"node": "Send1", +"type": "main", +"index": 0 +} +] +] +}, +"Structured Output Parser": { +"ai_outputParser": [ +[ +{ +"node": "Extract details1", +"type": "ai_outputParser", +"index": 0 +} +] +] +}, +"Google Gemini Chat Model1": { +"ai_languageModel": [ +[ +{ +"node": "Extract details", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Structured Output Parser1": { +"ai_outputParser": [ +[ +{ +"node": "Extract details", +"type": "ai_outputParser", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Extract text from PDF and image using Vertex AI (Gemini) into CSV.txt b/Extract text from PDF and image using Vertex AI (Gemini) into CSV.txt new file mode 100644 index 0000000..786cf15 --- /dev/null +++ b/Extract text from PDF and image using Vertex AI (Gemini) into CSV.txt @@ -0,0 +1,500 @@ +{ +"id": "sUIPemKdKqmUQFt6", +"meta": { +"instanceId": "558d88703fb65b2d0e44613bc35916258b0f0bf983c5d4730c00c424b77ca36a", +"templateCredsSetupCompleted": true +}, +"name": "Extract text from PDF and image using Vertex AI (Gemini) into CSV", +"tags": [], +"nodes": [ +{ +"id": "f60ef5f9-bc08-4cc9-804e-697ae6f88b9b", +"name": "Google Gemini Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini", +"position": [ +980, +920 +], +"parameters": { +"options": {}, +"modelName": "models/gemini-1.5-pro-latest" +}, +"credentials": { +"googlePalmApi": { +"id": "hmNTKSKfppgtDbM5", +"name": "Google Gemini(PaLM) Api account" +} +}, +"typeVersion": 1 +}, +{ +"id": "81d3f7b8-20cb-4aac-82a9-d4e8e6581105", +"name": "Get PDF or Images", +"type": "n8n-nodes-base.googleDriveTrigger", +"position": [ +220, +420 +], +"parameters": { +"event": "fileCreated", +"options": {}, +"pollTimes": { +"item": [ +{ +"mode": "everyMinute" +} +] +}, +"triggerOn": "specificFolder", +"folderToWatch": { +"__rl": true, +"mode": "list", +"value": "1HOeRP5iwccg93UPUYmWYD7DyDmRREkhj", +"cachedResultUrl": "https://drive.google.com/drive/folders/1HOeRP5iwccg93UPUYmWYD7DyDmRREkhj", +"cachedResultName": "Actual Budget" +}, +"authentication": "serviceAccount" +}, +"credentials": { +"googleApi": { +"id": "axkK6IN61bEAT6GM", +"name": "Google Service Account account" +} +}, +"typeVersion": 1 +}, +{ +"id": "fe9a8228-7950-4e2c-8982-328e03725782", +"name": "Route based on PDF or Image", +"type": "n8n-nodes-base.switch", +"position": [ +480, +420 +], +"parameters": { +"rules": { +"rules": [ +{ +"value2": "application/pdf", +"outputKey": "pdf" +}, +{ +"value2": "image/", +"operation": "contains", +"outputKey": "image" +} +] +}, +"value1": "={{$json.mimeType}}", +"dataType": "string" +}, +"typeVersion": 2 +}, +{ +"id": "f62b71e5-af17-4f85-abff-7cee5100affc", +"name": "Download PDF", +"type": "n8n-nodes-base.googleDrive", +"position": [ +740, +320 +], +"parameters": { +"fileId": { +"__rl": true, +"mode": "id", +"value": "={{ $('Get PDF or Images').item.json.id }}" +}, +"options": {}, +"operation": "download", +"authentication": "serviceAccount" +}, +"credentials": { +"googleApi": { +"id": "axkK6IN61bEAT6GM", +"name": "Google Service Account account" +} +}, +"executeOnce": true, +"typeVersion": 3 +}, +{ +"id": "fa99fbcf-1353-410d-a0db-48cea1178a76", +"name": "Download Image", +"type": "n8n-nodes-base.googleDrive", +"position": [ +740, +740 +], +"parameters": { +"fileId": { +"__rl": true, +"mode": "id", +"value": "={{ $('Get PDF or Images').item.json.id }}" +}, +"options": {}, +"operation": "download", +"authentication": "serviceAccount" +}, +"credentials": { +"googleApi": { +"id": "axkK6IN61bEAT6GM", +"name": "Google Service Account account" +} +}, +"executeOnce": true, +"retryOnFail": false, +"typeVersion": 3, +"alwaysOutputData": true +}, +{ +"id": "e4979746-44bb-493e-b5eb-f9646b510888", +"name": "Extract data from PDF", +"type": "n8n-nodes-base.extractFromFile", +"position": [ +980, +320 +], +"parameters": { +"options": {}, +"operation": "pdf" +}, +"typeVersion": 1 +}, +{ +"id": "6549c335-e749-4b95-b77d-096a5e77af5e", +"name": "Send data to A.I.", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1180, +320 +], +"parameters": { +"url": "https://openrouter.ai/api/v1/chat/completions", +"method": "POST", +"options": {}, +"jsonBody": "={\n \"model\": \"meta-llama/llama-3.1-70b-instruct:free\",\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"You are given a bank statement.{{encodeURIComponent($json.text)}}. Read the PDF and export all the transactions as CSV. Add a column called category and based on the information assign a category name. Return only the CSV data starting with the header row.\"\n }\n ]\n}", +"sendBody": true, +"specifyBody": "json", +"authentication": "genericCredentialType", +"genericAuthType": "httpHeaderAuth" +}, +"credentials": { +"httpHeaderAuth": { +"id": "WY7UkF14ksPKq3S8", +"name": "Header Auth account 2" +} +}, +"typeVersion": 4.2, +"alwaysOutputData": false +}, +{ +"id": "42341f03-c9fc-4290-963e-1a723202a739", +"name": "Convert to CSV", +"type": "n8n-nodes-base.convertToFile", +"position": [ +1400, +320 +], +"parameters": { +"options": {} +}, +"typeVersion": 1.1 +}, +{ +"id": "bb446447-3f46-47e7-96a2-3fc720715828", +"name": "Upload to Google Drive", +"type": "n8n-nodes-base.googleDrive", +"position": [ +1640, +320 +], +"parameters": { +"name": "={{$today}}", +"driveId": { +"__rl": true, +"mode": "list", +"value": "My Drive", +"cachedResultUrl": "https://drive.google.com/drive/my-drive", +"cachedResultName": "My Drive" +}, +"options": {}, +"folderId": { +"__rl": true, +"mode": "list", +"value": "1Zo4OFCv1qWRX1jo0VL_iqUBf4v0fZEXe", +"cachedResultUrl": "https://drive.google.com/drive/folders/1Zo4OFCv1qWRX1jo0VL_iqUBf4v0fZEXe", +"cachedResultName": "CSV Exports" +}, +"authentication": "serviceAccount" +}, +"credentials": { +"googleApi": { +"id": "axkK6IN61bEAT6GM", +"name": "Google Service Account account" +} +}, +"typeVersion": 3 +}, +{ +"id": "843bc9c1-79a6-4f42-b9ee-fbec5f30b18d", +"name": "Convert to CSV2", +"type": "n8n-nodes-base.convertToFile", +"position": [ +1360, +740 +], +"parameters": { +"options": {} +}, +"typeVersion": 1.1 +}, +{ +"id": "6404bf65-3a7e-4be9-9b7f-98a23dca2ffd", +"name": "Upload to Google Drive1", +"type": "n8n-nodes-base.googleDrive", +"position": [ +1640, +740 +], +"parameters": { +"name": "={{$today}}", +"driveId": { +"__rl": true, +"mode": "list", +"value": "My Drive", +"cachedResultUrl": "https://drive.google.com/drive/my-drive", +"cachedResultName": "My Drive" +}, +"options": {}, +"folderId": { +"__rl": true, +"mode": "list", +"value": "1Zo4OFCv1qWRX1jo0VL_iqUBf4v0fZEXe", +"cachedResultUrl": "https://drive.google.com/drive/folders/1Zo4OFCv1qWRX1jo0VL_iqUBf4v0fZEXe", +"cachedResultName": "CSV Exports" +}, +"authentication": "serviceAccount" +}, +"credentials": { +"googleApi": { +"id": "axkK6IN61bEAT6GM", +"name": "Google Service Account account" +} +}, +"typeVersion": 3 +}, +{ +"id": "5dd5771f-6ccb-47ab-acbb-d6cbec60d22b", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +220, +-40 +], +"parameters": { +"width": 589.0376569037658, +"height": 163.2468619246862, +"content": "## How to extract PDF and image text into CSV using n8n (without manual data entry)\n\nThis workflow will extract text data from PDF and images, then store it as CSV.\n\n[💡 You can read more about this workflow here](https://rumjahn.com/how-to-create-an-a-i-agent-to-analyze-matomo-analytics-using-n8n-for-free/)" +}, +"typeVersion": 1 +}, +{ +"id": "37416630-9b52-4ce6-98d0-1bdd39ff0d6b", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +160, +160 +], +"parameters": { +"color": 4, +"width": 248.11715481171547, +"height": 432.7364016736402, +"content": "## Get PDF or image\nYou need to create a new folder inside Google Drive for uploading your PDF and images.\n\nOnce you create a folder, you need to add your Google cloud user by going to Share -> Add user. The user email should be like: n8n-server@n8n-server-435232.iam.gserviceaccount.com" +}, +"typeVersion": 1 +}, +{ +"id": "3ab10f17-de8f-4263-aef8-cc2fb090ffe5", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1120, +52.864368048917754 +], +"parameters": { +"color": 5, +"height": 446.3929762816575, +"content": "## Send to Openrouter\nYou need to set up an Openrouter account to use this. It sends the data to openrouter to extract text.\n\nUse Header Auth. Name is \"Authorization\" and value is \"Bearer {API token}\"." +}, +"typeVersion": 1 +}, +{ +"id": "e966f95c-c54e-4d11-895d-d5f75c53aca5", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +920, +540 +], +"parameters": { +"color": 6, +"width": 399.0962343096232, +"height": 517.154811715481, +"content": "## Vertex AI for image recogniztion\nWe send the photo to Vertex AI to extract text. You'll need to activate Vertex AI and add the correct rights to your Google cloud credentials. \n- Enable Vertex API\n- Add vertex to user account" +}, +"typeVersion": 1 +}, +{ +"id": "daa3ab66-fa14-4792-96d0-3bcbeffd5d60", +"name": "Vertex A.I. extract text", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +980, +740 +], +"parameters": { +"text": "=Extract the transactions from the image", +"messages": { +"messageValues": [ +{ +"message": "=You are given a screenshot of payment transactions. Read the image and export all the transactions as CSV. Add a column called category and based on the information assign a category name. Return only the CSV data starting with the header row." +}, +{ +"type": "HumanMessagePromptTemplate", +"messageType": "imageBinary" +} +] +}, +"promptType": "define", +"hasOutputParser": true +}, +"typeVersion": 1.4 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "80635382-3d1c-4e46-a753-84b033cfc3a7", +"connections": { +"Download PDF": { +"main": [ +[ +{ +"node": "Extract data from PDF", +"type": "main", +"index": 0 +} +] +] +}, +"Convert to CSV": { +"main": [ +[ +{ +"node": "Upload to Google Drive", +"type": "main", +"index": 0 +} +] +] +}, +"Download Image": { +"main": [ +[ +{ +"node": "Vertex A.I. extract text", +"type": "main", +"index": 0 +} +] +] +}, +"Convert to CSV2": { +"main": [ +[ +{ +"node": "Upload to Google Drive1", +"type": "main", +"index": 0 +} +] +] +}, +"Get PDF or Images": { +"main": [ +[ +{ +"node": "Route based on PDF or Image", +"type": "main", +"index": 0 +} +] +] +}, +"Send data to A.I.": { +"main": [ +[ +{ +"node": "Convert to CSV", +"type": "main", +"index": 0 +} +] +] +}, +"Extract data from PDF": { +"main": [ +[ +{ +"node": "Send data to A.I.", +"type": "main", +"index": 0 +} +] +] +}, +"Google Gemini Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Vertex A.I. extract text", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Vertex A.I. extract text": { +"main": [ +[ +{ +"node": "Convert to CSV2", +"type": "main", +"index": 0 +} +] +] +}, +"Route based on PDF or Image": { +"main": [ +[ +{ +"node": "Download PDF", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Download Image", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Fetch Dynamic Prompts from GitHub and Auto-Populate n8n Expressions in Prompt.txt b/Fetch Dynamic Prompts from GitHub and Auto-Populate n8n Expressions in Prompt.txt new file mode 100644 index 0000000..cc086b5 --- /dev/null +++ b/Fetch Dynamic Prompts from GitHub and Auto-Populate n8n Expressions in Prompt.txt @@ -0,0 +1,503 @@ +{ +"id": "QyMyf3zraY0wxXDf", +"meta": { +"instanceId": "ba3fa76a571c35110ef5f67e5099c9a5c1768ef125c2f3b804ba20de75248c0b", +"templateCredsSetupCompleted": true +}, +"name": "Load Prompts from Github Repo and auto populate n8n expressions", +"tags": [], +"nodes": [ +{ +"id": "34781446-b06e-41eb-83b8-b96bda1a5595", +"name": "When clicking ‘Test workflow’", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +-80, +0 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "c53b7243-7c82-47e0-a5ee-bd82bc51c386", +"name": "GitHub", +"type": "n8n-nodes-base.github", +"position": [ +600, +0 +], +"parameters": { +"owner": { +"__rl": true, +"mode": "name", +"value": "={{ $json.Account }}" +}, +"filePath": "={{ $json.path }}{{ $json.prompt }}", +"resource": "file", +"operation": "get", +"repository": { +"__rl": true, +"mode": "name", +"value": "={{ $json.repo }}" +}, +"additionalParameters": {} +}, +"credentials": { +"githubApi": { +"id": "ostHZNoe8GSsbaQM", +"name": "The GitHub account" +} +}, +"typeVersion": 1 +}, +{ +"id": "9976b199-b744-47a7-9d75-4b831274c01b", +"name": "Extract from File", +"type": "n8n-nodes-base.extractFromFile", +"position": [ +840, +0 +], +"parameters": { +"options": {}, +"operation": "text" +}, +"typeVersion": 1 +}, +{ +"id": "26aa4e6a-c487-4cdf-91d5-df660cf826a6", +"name": "setVars", +"type": "n8n-nodes-base.set", +"position": [ +180, +0 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "150618c5-09b1-4f8b-a7b4-984662bf3381", +"name": "Account", +"type": "string", +"value": "TPGLLC-US" +}, +{ +"id": "22e8a3b0-bd53-485c-b971-7f1dd0686f0e", +"name": "repo", +"type": "string", +"value": "PeresPrompts" +}, +{ +"id": "ab94d0a1-ef3a-4fe9-9076-6882c6fda0ac", +"name": "path", +"type": "string", +"value": "SEO/" +}, +{ +"id": "66f122eb-1cbd-4769-aac8-3f05cdb6c116", +"name": "prompt", +"type": "string", +"value": "keyword_research.md" +}, +{ +"id": "03fe26a3-04e6-439c-abcb-d438fc5203c0", +"name": "company", +"type": "string", +"value": "South Nassau Physical Therapy" +}, +{ +"id": "c133d216-a457-4872-a060-0ba4d94549af", +"name": "product", +"type": "string", +"value": "Manual Therapy" +}, +{ +"id": "584864dd-2518-45e2-b501-02828757fc3a", +"name": "features", +"type": "string", +"value": "pain relief" +}, +{ +"id": "0c4594cc-302a-4215-bdad-12cf54f57967", +"name": "sector", +"type": "string", +"value": "physical therapy" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "9d92f581-8cd9-448c-aa1d-023a96c1ddda", +"name": "replace variables", +"type": "n8n-nodes-base.code", +"position": [ +1900, +-20 +], +"parameters": { +"jsCode": "// Fetch the prompt text\nconst prompt = $('SetPrompt').first().json.data; // Ensure the prompt contains placeholders like {{ some.node.value }}\n\n// Example variables object\nconst variables = {\n company: $('setVars').first().json.company,\n features: \"Awesome Software\",\n keyword: \"2025-02-07\"\n};\n\n// Function to replace placeholders dynamically\nconst replaceVariables = (text, vars) => {\n return text.replace(/{{(.*?)}}/g, (match, key) => {\n const trimmedKey = key.trim();\n \n // Extract last part after the last dot\n const finalKey = trimmedKey.split('.').pop();\n\n // Replace if key exists, otherwise leave placeholder unchanged\n return vars.hasOwnProperty(finalKey) ? vars[finalKey] : match;\n });\n};\n\n// Replace and return result\nreturn [{\n prompt: replaceVariables(prompt, variables)\n}];\n" +}, +"typeVersion": 2 +}, +{ +"id": "6c6c4fde-6ee5-47a8-894d-44d1afcedc2a", +"name": "If", +"type": "n8n-nodes-base.if", +"position": [ +1560, +0 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "2717a7e5-095a-42bf-8b5b-8050c3389ec5", +"operator": { +"type": "boolean", +"operation": "true", +"singleValue": true +}, +"leftValue": "={{ $json.success }}", +"rightValue": "={{ $('Check All Prompt Vars Present').item.json.keys()}}" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "3b7712b8-5152-4f60-9401-03c89c39e227", +"name": "Check All Prompt Vars Present", +"type": "n8n-nodes-base.code", +"position": [ +1280, +0 +], +"parameters": { +"jsCode": "// Get prompt text\nconst prompt = $json.data;\n\n// Extract variables inside {{ }} dynamically\nconst matches = [...prompt.matchAll(/{{(.*?)}}/g)];\nconst uniqueVars = [...new Set(matches.map(match => match[1].trim().split('.').pop()))];\n\n// Get variables from the Set Node\nconst setNodeVariables = $node[\"setVars\"].json || {};\n\n// Log extracted variables and Set Node keys\nconsole.log(\"Extracted Variables:\", uniqueVars);\nconsole.log(\"Set Node Keys:\", Object.keys(setNodeVariables));\n\n// Check if all required variables are present in the Set Node\nconst missingKeys = uniqueVars.filter(varName => !setNodeVariables.hasOwnProperty(varName));\n\nconsole.log(\"Missing Keys:\", missingKeys);\n\n// Return false if any required variable is missing, otherwise return true\nreturn [{\n success: missingKeys.length === 0,\n missingKeys: missingKeys\n}];\n" +}, +"typeVersion": 2 +}, +{ +"id": "32618e10-3285-4c16-9e78-058dde329337", +"name": "SetPrompt", +"type": "n8n-nodes-base.set", +"position": [ +1060, +0 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "335b450d-542a-4714-83d8-ccc237188fc5", +"name": "data", +"type": "string", +"value": "={{ $json.data }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "4d8b34ca-50dd-4f37-b4f7-542291461662", +"name": "Stop and Error", +"type": "n8n-nodes-base.stopAndError", +"position": [ +1900, +200 +], +"parameters": { +"errorMessage": "=Missing Prompt Variables : {{ $('Check All Prompt Vars Present').item.json.missingKeys }}\n" +}, +"typeVersion": 1 +}, +{ +"id": "a78c1e17-9152-4241-bcdf-c0d723da543b", +"name": "Set Completed Prompt", +"type": "n8n-nodes-base.set", +"position": [ +2220, +-20 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "57a9625b-adea-4ee7-a72a-2be8db15f3d4", +"name": "Prompt", +"type": "string", +"value": "={{ $json.prompt }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "51447c90-a222-4172-a49b-86ec43332559", +"name": "AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +2440, +-20 +], +"parameters": { +"text": "={{ $json.Prompt }}", +"options": {}, +"promptType": "define" +}, +"typeVersion": 1.7 +}, +{ +"id": "f15b6af1-7af2-4515-be8f-960211118dce", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +60, +-120 +], +"parameters": { +"width": 340, +"height": 260, +"content": "# Set The variables in your prompt here" +}, +"typeVersion": 1 +}, +{ +"id": "163db6cc-5b06-4ae6-ac97-5890b37cdb18", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +520, +-120 +], +"parameters": { +"color": 5, +"content": "## The repo is currently public for you to test with" +}, +"typeVersion": 1 +}, +{ +"id": "83ff6a86-a759-42a9-ace4-e20d57b906db", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1780, +-200 +], +"parameters": { +"width": 360, +"height": 260, +"content": "## Replaces the values in the prompt with the variables in the \n# 'setVars' Node" +}, +"typeVersion": 1 +}, +{ +"id": "7dd61153-84ac-4b59-b449-333825476c33", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2000, +180 +], +"parameters": { +"color": 3, +"content": "## If you're missing variables they will be listed here" +}, +"typeVersion": 1 +}, +{ +"id": "1f070dc3-3d25-41d8-b534-912ba7c8b2b0", +"name": "Prompt Output", +"type": "n8n-nodes-base.set", +"position": [ +2800, +-20 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "01a30683-c348-4712-a3b1-739fc4a17718", +"name": "promptResponse", +"type": "string", +"value": "={{ $json.output }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "2d12a6e2-7976-41b0-8cb2-01466b28269d", +"name": "Ollama Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOllama", +"position": [ +2480, +200 +], +"parameters": { +"options": {} +}, +"credentials": { +"ollamaApi": { +"id": "ERfZ8mAfQ1b0aoxZ", +"name": "Ollama account" +} +}, +"typeVersion": 1 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "4327a337-59e7-4b5b-98e8-93c6be550972", +"connections": { +"If": { +"main": [ +[ +{ +"node": "replace variables", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Stop and Error", +"type": "main", +"index": 0 +} +] +] +}, +"GitHub": { +"main": [ +[ +{ +"node": "Extract from File", +"type": "main", +"index": 0 +} +] +] +}, +"setVars": { +"main": [ +[ +{ +"node": "GitHub", +"type": "main", +"index": 0 +} +] +] +}, +"AI Agent": { +"main": [ +[ +{ +"node": "Prompt Output", +"type": "main", +"index": 0 +} +] +] +}, +"SetPrompt": { +"main": [ +[ +{ +"node": "Check All Prompt Vars Present", +"type": "main", +"index": 0 +} +] +] +}, +"Extract from File": { +"main": [ +[ +{ +"node": "SetPrompt", +"type": "main", +"index": 0 +} +] +] +}, +"Ollama Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"replace variables": { +"main": [ +[ +{ +"node": "Set Completed Prompt", +"type": "main", +"index": 0 +} +] +] +}, +"Set Completed Prompt": { +"main": [ +[ +{ +"node": "AI Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Check All Prompt Vars Present": { +"main": [ +[ +{ +"node": "If", +"type": "main", +"index": 0 +} +] +] +}, +"When clicking ‘Test workflow’": { +"main": [ +[ +{ +"node": "setVars", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Flux AI Image Generator.txt b/Flux AI Image Generator.txt new file mode 100644 index 0000000..e161a71 --- /dev/null +++ b/Flux AI Image Generator.txt @@ -0,0 +1,716 @@ +{ +"nodes": [ +{ +"id": "6abe578b-d503-4da5-9af8-f9977de71139", +"name": "Vivid Pop Explosion", +"type": "n8n-nodes-base.set", +"notes": " ", +"position": [ +380, +980 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "9ec60f33-b940-40a6-9f8a-cb944b7065f1", +"name": "stylePrompt", +"type": "string", +"value": "=rule of thirds, golden ratio, hyper-maximalist, vibrant neon, high-contrast, octane render, photorealism, 8k ::7 --ar 16:9 --s 1000\n\nDesign a fun, energetic scene filled with bold, neon colors, and playful shapes that pop off the screen. The image should evoke a sense of joy and movement, using fluid, organic forms and exaggerated, cartoon-like proportions. Focus on creating a lively atmosphere with contrasting, saturated tones and dynamic lighting. Use a mix of asymmetrical and balanced compositions to create a playful visual flow. Render in 8K with a hyper-maximalist approach using Octane Render for vibrant, high-gloss textures and photorealistic lighting effects. Include:" +} +] +}, +"includeOtherFields": true +}, +"notesInFlow": true, +"typeVersion": 3.4 +}, +{ +"id": "7de1ea42-3b18-4bfb-8ea4-a8b6c8d16763", +"name": "AI Dystopia", +"type": "n8n-nodes-base.set", +"notes": " ", +"position": [ +380, +620 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "9ec60f33-b940-40a6-9f8a-cb944b7065f1", +"name": "stylePrompt", +"type": "string", +"value": "=golden ratio, rule of thirds, cyberpunk, glitch art, octane render, cinematic realism, 8k ::7 --ar 16:9 --s 1000\n\nGenerate a futuristic, cyberpunk dystopia with metallic textures, digital glitches, and neon lights. Blend cold, dystopian structures with traces of organic life. Use photorealistic lighting and dynamic reflections to enhance the visual depth of the scene. Include:" +} +] +}, +"includeOtherFields": true +}, +"notesInFlow": true, +"typeVersion": 3.4 +}, +{ +"id": "aa17c288-78e0-48d9-9c60-0e63e351d0b6", +"name": "Post-Analog Glitchscape", +"type": "n8n-nodes-base.set", +"notes": " ", +"position": [ +380, +420 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "9ec60f33-b940-40a6-9f8a-cb944b7065f1", +"name": "stylePrompt", +"type": "string", +"value": "=rule of thirds, asymmetric composition, glitch art, pixelation, VHS noise, octane render, unreal engine, 8k ::7 --ar 16:9 --s 1200\nDesign a glitchy, post-analog world with digital decay and broken visuals. Utilize pixelated elements, VHS noise, and neon glitches to create a fragmented aesthetic. Use bold, contrasting colors against muted backgrounds for a high-contrast, otherworldly feel. The composition should follow asymmetrical rules, focusing on chaotic yet intentional visual balance. Include:" +} +] +}, +"includeOtherFields": true +}, +"notesInFlow": true, +"typeVersion": 3.4 +}, +{ +"id": "769ff46c-630f-456d-ae19-4c6496270fda", +"name": "Neon Fauvism", +"type": "n8n-nodes-base.set", +"notes": " ", +"position": [ +380, +800 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "9ec60f33-b940-40a6-9f8a-cb944b7065f1", +"name": "stylePrompt", +"type": "string", +"value": "=asymmetric composition, golden ratio, neon colors, abstract forms, octane render, cinematic realism, unreal engine, 8k ::7 --ar 16:9 --s 1000\nCreate a bold, vivid composition using neon colors and fluid shapes that break away from reality. Focus on abstract forms, blending Fauvism's exaggerated color palette with modern digital art techniques. Use asymmetric composition and dynamic lighting. Render with a vibrant, high-energy aesthetic. Include:" +} +] +}, +"includeOtherFields": true +}, +"notesInFlow": true, +"typeVersion": 3.4 +}, +{ +"id": "ccc67dcb-84e6-476a-9bc2-b5382b700d5e", +"name": "None", +"type": "n8n-nodes-base.set", +"notes": " ", +"position": [ +380, +1160 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "9ec60f33-b940-40a6-9f8a-cb944b7065f1", +"name": "stylePrompt", +"type": "string", +"value": "=Include: " +} +] +}, +"includeOtherFields": true +}, +"notesInFlow": true, +"typeVersion": 3.4 +}, +{ +"id": "fea2039c-48e5-4077-af2c-ea72838e1a5d", +"name": "Serve webpage", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +1460, +580 +], +"parameters": { +"options": {}, +"respondWith": "text", +"responseBody": "=\n\n\n \n \n Flux Image Generation Result\n \n\n\n
\n
\n \"Generated\n
\n
Style: {{ $('Route by style').item.json.Style }}
\n Duplicate this AI template\n
\n \n \n
\n
\n \"Recent\n
\n
\n \"Recent\n
\n
\n \"Recent\n
\n
\n \n
\n
\n\n\n" +}, +"typeVersion": 1.1 +}, +{ +"id": "2df7b738-9584-48b4-8adc-cafb0c026928", +"name": "Respond with error", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +1460, +820 +], +"parameters": { +"options": {}, +"respondWith": "json", +"responseBody": "{\n \"formSubmittedText\": \"Flux API failed. It does this ~10% of the time. Refresh and try again.\"\n}" +}, +"typeVersion": 1.1 +}, +{ +"id": "54cba7c4-db24-4abb-9638-ee66236d8676", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-20, +440 +], +"parameters": { +"color": 7, +"width": 205.9419250888625, +"height": 107.99633347519193, +"content": "### Set style prompt\nEach Edit fields node after the Switch sets `stylePrompt`, used in huggingface node." +}, +"typeVersion": 1 +}, +{ +"id": "f4aa76f8-d35f-4332-aa39-0c34582618eb", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +720, +840 +], +"parameters": { +"color": 7, +"width": 419.0156901664085, +"height": 226.2264013670822, +"content": "### Run flux model\nIn `Call huggingface inference api` You can change `black-forest-labs/FLUX.1-schnell` in URL parameter to other models:\n- `black-forest-labs/FLUX.1-dev`\n- `Shakker-Labs/FLUX.1-dev-LoRA-AntiBlur`\n- `XLabs-AI/flux-RealismLora`\n- `ByteDance/Hyper-SD`\n\n[See more models on huggingface.co](https://huggingface.co/models?pipeline_tag=text-to-image&sort=trending)\n" +}, +"typeVersion": 1 +}, +{ +"id": "2b0b29ce-82c2-4428-bf12-cb25262e5291", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1120, +440 +], +"parameters": { +"color": 7, +"width": 247.37323750873333, +"height": 90.99855957953969, +"content": "### Host image on S3\n[Cloudflare](https://cloudflare.com) has free S3 compatible hosting. They call it \"R2\"." +}, +"typeVersion": 1 +}, +{ +"id": "6fccc88f-9e72-49a3-952d-b7b1d9612091", +"name": "Upload image to S3", +"type": "n8n-nodes-base.s3", +"onError": "continueErrorOutput", +"position": [ +1120, +580 +], +"parameters": { +"fileName": "=fg-{{ $execution.id }}.jpg", +"operation": "upload", +"bucketName": "flux-generator", +"additionalFields": {} +}, +"credentials": { +"s3": { +"id": "HZqaz9hPFlZp3BZ7", +"name": "S3 account" +} +}, +"typeVersion": 1 +}, +{ +"id": "7824dc49-c546-424e-8ba9-5f34b190d5f0", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1460, +440 +], +"parameters": { +"color": 7, +"width": 302.9292231993488, +"height": 90.99855957953969, +"content": "### Respond to Form\nServe a webform with image on success. On error, send message to form." +}, +"typeVersion": 1 +}, +{ +"id": "71739ba4-b8db-439e-b8c3-06f3208126e3", +"name": "Hyper-Surreal Escape", +"type": "n8n-nodes-base.set", +"notes": " ", +"position": [ +380, +240 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "9ec60f33-b940-40a6-9f8a-cb944b7065f1", +"name": "stylePrompt", +"type": "string", +"value": "=golden ratio, rule of thirds, cyberpunk, glitch art, octane render, cinematic realism, 8k ::7 --ar 16:9 --s 1000\nCreate a hyper-realistic yet surreal landscape that bends reality, incorporating dreamlike elements and exaggerated proportions. Use vibrant, almost neon colors, and focus on a sense of wonder, play, and fantasy. Include:\n" +} +] +}, +"includeOtherFields": true +}, +"notesInFlow": true, +"typeVersion": 3.4 +}, +{ +"id": "dcfdb152-a055-4f0f-baa5-7cf8afba36ae", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-320, +440 +], +"parameters": { +"color": 7, +"width": 186.9444130878394, +"height": 103.99685726445023, +"content": "### Serve form to user\nCaptures `Prompt to flux` and `Style` from user." +}, +"typeVersion": 1 +}, +{ +"id": "310f6c63-9441-4332-82dc-09b56e4f625a", +"name": "n8n Form Trigger", +"type": "n8n-nodes-base.formTrigger", +"position": [ +-280, +660 +], +"webhookId": "a35eb005-f795-4c85-9d00-0fe9797cb509", +"parameters": { +"path": "flux4free", +"options": {}, +"formTitle": "flux.schnell image generator", +"formFields": { +"values": [ +{ +"fieldType": "textarea", +"fieldLabel": "Prompt to flux", +"placeholder": " An astronaut riding a horse in 35mm style", +"requiredField": true +}, +{ +"fieldType": "dropdown", +"fieldLabel": "Style", +"fieldOptions": { +"values": [ +{ +"option": "Hyper-Surreal Escape" +}, +{ +"option": "Neon Fauvism" +}, +{ +"option": "Post-Analog Glitchscape" +}, +{ +"option": "AI Dystopia" +}, +{ +"option": "Vivid Pop Explosion" +} +] +} +} +] +}, +"responseMode": "responseNode", +"formDescription": "No ads, no BS. Uses hugginface inference API." +}, +"typeVersion": 2.1 +}, +{ +"id": "ad10a84f-851a-40f8-b10e-18356c4eeed6", +"name": "Call hugginface inference api", +"type": "n8n-nodes-base.httpRequest", +"notes": " ", +"onError": "continueErrorOutput", +"position": [ +740, +660 +], +"parameters": { +"url": "https://api-inference.huggingface.co/models/black-forest-labs/FLUX.1-schnell", +"method": "POST", +"options": {}, +"sendBody": true, +"sendHeaders": true, +"authentication": "genericCredentialType", +"bodyParameters": { +"parameters": [ +{ +"name": "inputs", +"value": "=Depict {{ $json['Prompt to flux'] }}\n\nStyle: {{ $json.stylePrompt }}" +} +] +}, +"genericAuthType": "httpHeaderAuth", +"headerParameters": { +"parameters": [ +{} +] +} +}, +"credentials": { +"httpHeaderAuth": { +"id": "r98SNEAnA5arilQO", +"name": "huggingface-nathan" +} +}, +"notesInFlow": true, +"typeVersion": 4.2 +}, +{ +"id": "e740dd3c-e23e-485b-bb4c-bb0515897a08", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-880, +600 +], +"parameters": { +"color": 7, +"width": 506.8102696237577, +"height": 337.24177957113216, +"content": "### Watch Set Up Video 👇\n[![Flux Generator](https://uploads.n8n.io/devrel/fluxgenerator.png#full-width)](https://youtu.be/Rv_1jt5WvtY)\n\n" +}, +"typeVersion": 1 +}, +{ +"id": "71d01821-3e0d-4c08-8571-58a158817e2c", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-880, +440 +], +"parameters": { +"color": 7, +"width": 506.8102696237577, +"height": 134.27496896630808, +"content": "# flux image generator\nBuilt by [@maxtkacz](https://x.com/maxtkacz) as part of the [30 Day AI Sprint](https://30dayaisprint.notion.site/)\nCheck out the project's [Notion page](https://30dayaisprint.notion.site/Flux-image-generator-bc94a8d2de8447c6ab70aacf2c4179f2) for more details" +}, +"typeVersion": 1 +}, +{ +"id": "0cc26680-ba63-464f-ba84-68c2616f95e2", +"name": "Route by style", +"type": "n8n-nodes-base.switch", +"position": [ +0, +640 +], +"parameters": { +"rules": { +"values": [ +{ +"outputKey": "Hyper-Surreal Escape", +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"operator": { +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.Style }}", +"rightValue": "Hyper-Surreal Escape" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "Post-Analog Glitchscape", +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "106969fa-994c-4b1e-b693-fc0b48ce5f3d", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.Style }}", +"rightValue": "Post-Analog Glitchscape" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "AI Dystopia", +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "24318e7d-4dc1-4369-b045-bb7d0a484def", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.Style }}", +"rightValue": "AI Dystopia" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "Neon Fauvism", +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "a80911ff-67fc-416d-b135-0401c336d6d8", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.Style }}", +"rightValue": "Neon Fauvism" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "Vivid Pop Explosion", +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "7fdeec28-194e-415e-8da2-8bac90e4c011", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.Style }}", +"rightValue": "Vivid Pop Explosion" +} +] +}, +"renameOutput": true +} +] +}, +"options": { +"fallbackOutput": "extra" +} +}, +"typeVersion": 3.1 +} +], +"pinData": {}, +"connections": { +"None": { +"main": [ +[ +{ +"node": "Call hugginface inference api", +"type": "main", +"index": 0 +} +] +] +}, +"AI Dystopia": { +"main": [ +[ +{ +"node": "Call hugginface inference api", +"type": "main", +"index": 0 +} +] +] +}, +"Neon Fauvism": { +"main": [ +[ +{ +"node": "Call hugginface inference api", +"type": "main", +"index": 0 +} +] +] +}, +"Route by style": { +"main": [ +[ +{ +"node": "Hyper-Surreal Escape", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Post-Analog Glitchscape", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "AI Dystopia", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Neon Fauvism", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Vivid Pop Explosion", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "None", +"type": "main", +"index": 0 +} +] +] +}, +"n8n Form Trigger": { +"main": [ +[ +{ +"node": "Route by style", +"type": "main", +"index": 0 +} +] +] +}, +"Upload image to S3": { +"main": [ +[ +{ +"node": "Serve webpage", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Respond with error", +"type": "main", +"index": 0 +} +] +] +}, +"Vivid Pop Explosion": { +"main": [ +[ +{ +"node": "Call hugginface inference api", +"type": "main", +"index": 0 +} +] +] +}, +"Hyper-Surreal Escape": { +"main": [ +[ +{ +"node": "Call hugginface inference api", +"type": "main", +"index": 0 +} +] +] +}, +"Post-Analog Glitchscape": { +"main": [ +[ +{ +"node": "Call hugginface inference api", +"type": "main", +"index": 0 +} +] +] +}, +"Call hugginface inference api": { +"main": [ +[ +{ +"node": "Upload image to S3", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Respond with error", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Flux Dev Image Generation (Fal.ai) to Google Drive.txt b/Flux Dev Image Generation (Fal.ai) to Google Drive.txt new file mode 100644 index 0000000..4a63c6b --- /dev/null +++ b/Flux Dev Image Generation (Fal.ai) to Google Drive.txt @@ -0,0 +1,380 @@ +{ +"id": "nJwkSOrJIFvutw1n", +"meta": { +"instanceId": "08daa2aa5b6032ff63690600b74f68f5b0f34a3b100102e019b35c4419168977" +}, +"name": "Flux Dev Image Generation Fal.ai", +"tags": [], +"nodes": [ +{ +"id": "00f3a7d9-9931-40a4-8eb5-5b9086d6995c", +"name": "Fal Flux", +"type": "n8n-nodes-base.httpRequest", +"position": [ +420, +0 +], +"parameters": { +"url": "https://queue.fal.run/fal-ai/flux/dev", +"method": "POST", +"options": {}, +"jsonBody": "={\n \"prompt\": \"{{ $json.Prompt }}\",\n \"image_size\": {\n \"width\": {{ $json.Width }},\n \"height\": {{ $json.Height }}\n},\n \"num_inference_steps\": {{ $json.Steps }},\n \"guidance_scale\": {{ $json.Guidance }},\n \"num_images\": 1,\n \"enable_safety_checker\": true\n}", +"sendBody": true, +"specifyBody": "json", +"authentication": "genericCredentialType", +"genericAuthType": "httpHeaderAuth" +}, +"credentials": { +"httpHeaderAuth": { +"id": "lNxvZHlUafPAHBYN", +"name": "Fal Flux Header Auth account" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "3032a543-2e21-415e-a5bd-d56ea33e4411", +"name": "Get Image Result URL", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1220, +-20 +], +"parameters": { +"url": "=https://queue.fal.run/fal-ai/flux/requests/{{ $json.request_id }}", +"options": {}, +"authentication": "genericCredentialType", +"genericAuthType": "httpHeaderAuth" +}, +"credentials": { +"httpHeaderAuth": { +"id": "lNxvZHlUafPAHBYN", +"name": "Fal Flux Header Auth account" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "56e13e53-1697-4970-9bea-b75e0e849425", +"name": "Download Image", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1400, +-20 +], +"parameters": { +"url": "={{ $json.images[0].url }}", +"options": {} +}, +"typeVersion": 4.2 +}, +{ +"id": "dd2efd2c-8712-4a77-8786-cccebdec876b", +"name": "Google Drive", +"type": "n8n-nodes-base.googleDrive", +"position": [ +1580, +-20 +], +"parameters": { +"name": "={{ $binary.data.fileName }}", +"driveId": { +"__rl": true, +"mode": "list", +"value": "My Drive" +}, +"options": {}, +"folderId": { +"__rl": true, +"mode": "list", +"value": "1R3PSyHXWHlY9DRFdOUEAPEop2fZy-_-K", +"cachedResultUrl": "https://drive.google.com/drive/folders/1R3PSyHXWHlY9DRFdOUEAPEop2fZy-_-K", +"cachedResultName": "Flux Image" +} +}, +"credentials": { +"googleDriveOAuth2Api": { +"id": "CFiX9XTXGg4hGaGV", +"name": "Google Drive account" +} +}, +"typeVersion": 3 +}, +{ +"id": "a598d868-0461-41fc-b6aa-f9998e9d6146", +"name": "When clicking ‘Test workflow’", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +-60, +0 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "a576d7b6-b2f3-4d53-8e7f-bb6449ff9c64", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +80, +-120 +], +"parameters": { +"width": 260, +"height": 120, +"content": "## Set Parameter Here \nset Image Prompt and related settings" +}, +"typeVersion": 1 +}, +{ +"id": "d39e85a8-3ddd-4f10-ba4c-beb86a850e10", +"name": "Wait 3 Sec", +"type": "n8n-nodes-base.wait", +"position": [ +640, +0 +], +"webhookId": "61a8626c-e281-4d4b-abb0-b9d87d1b4e7c", +"parameters": { +"amount": 3 +}, +"typeVersion": 1.1 +}, +{ +"id": "b27ac2f1-3f14-467e-81c4-af8b8fb37138", +"name": "Check Status", +"type": "n8n-nodes-base.httpRequest", +"position": [ +840, +0 +], +"parameters": { +"url": "=https://queue.fal.run/fal-ai/flux/requests/{{ $json.request_id }}/status", +"options": {}, +"authentication": "genericCredentialType", +"genericAuthType": "httpHeaderAuth" +}, +"credentials": { +"httpHeaderAuth": { +"id": "lNxvZHlUafPAHBYN", +"name": "Fal Flux Header Auth account" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "7ee45dab-8e31-44de-bbb1-e99a565ee19c", +"name": "Completed?", +"type": "n8n-nodes-base.if", +"position": [ +1020, +0 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "299a7c34-dcff-4991-a73f-5b1a84f188ea", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.status }}", +"rightValue": "COMPLETED" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "c5036a7d-1879-449f-8ce9-9c1cf2c7426b", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1300, +-100 +], +"parameters": { +"width": 220, +"height": 100, +"content": "## Set Drive Folder Here " +}, +"typeVersion": 1 +}, +{ +"id": "c8887168-6234-486c-b7cb-cc0752c6341c", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +360, +-180 +], +"parameters": { +"width": 260, +"height": 180, +"content": "### Generic Credential Type\n### Header : Authorization\nKey $FAL_KEY\"\n\nfor example:\nKey 6f2960baxxxxxxxxx" +}, +"typeVersion": 1 +}, +{ +"id": "587043c4-e808-4c3f-910f-60f5eb8aff15", +"name": "Edit Fields", +"type": "n8n-nodes-base.set", +"position": [ +180, +0 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "f0a033cf-fa2b-4930-93b9-ff9c45fa7c14", +"name": "Prompt", +"type": "string", +"value": "Thai young woman net idol 25 yrs old, walking on the street" +}, +{ +"id": "2b56185d-5c61-4c17-85f1-53ac4aab2b18", +"name": "Width", +"type": "number", +"value": 1024 +}, +{ +"id": "51eb65c0-ae0a-4ce7-ab00-9d13f05ce1e6", +"name": "Height", +"type": "number", +"value": 768 +}, +{ +"id": "8e89fca7-d380-4876-b973-69caa0394bc5", +"name": "Steps", +"type": "number", +"value": 30 +}, +{ +"id": "875e06b7-352a-4dde-8595-3274e9969c9c", +"name": "Guidance", +"type": "number", +"value": 3.5 +} +] +} +}, +"typeVersion": 3.4 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "82877b10-5bbc-4c59-828b-4abc3ad53a5f", +"connections": { +"Fal Flux": { +"main": [ +[ +{ +"node": "Wait 3 Sec", +"type": "main", +"index": 0 +} +] +] +}, +"Completed?": { +"main": [ +[ +{ +"node": "Get Image Result URL", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Wait 3 Sec", +"type": "main", +"index": 0 +} +] +] +}, +"Wait 3 Sec": { +"main": [ +[ +{ +"node": "Check Status", +"type": "main", +"index": 0 +} +] +] +}, +"Edit Fields": { +"main": [ +[ +{ +"node": "Fal Flux", +"type": "main", +"index": 0 +} +] +] +}, +"Check Status": { +"main": [ +[ +{ +"node": "Completed?", +"type": "main", +"index": 0 +} +] +] +}, +"Download Image": { +"main": [ +[ +{ +"node": "Google Drive", +"type": "main", +"index": 0 +} +] +] +}, +"Get Image Result URL": { +"main": [ +[ +{ +"node": "Download Image", +"type": "main", +"index": 0 +} +] +] +}, +"When clicking ‘Test workflow’": { +"main": [ +[ +{ +"node": "Edit Fields", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Force AI to use a specific output format.txt b/Force AI to use a specific output format.txt new file mode 100644 index 0000000..9211666 --- /dev/null +++ b/Force AI to use a specific output format.txt @@ -0,0 +1,250 @@ +{ +"id": "cKRViOHDPsosO7UX", +"meta": { +"instanceId": "ec7a5f4ffdb34436e59d23eaccb5015b5238de2a877e205b28572bf1ffecfe04" +}, +"name": "[AI/LangChain] Output Parser 4", +"tags": [], +"nodes": [ +{ +"id": "3d669ba2-65b7-4502-92d9-645c4e51b26d", +"name": "When clicking \"Execute Workflow\"", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +380, +240 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "9a509299-746d-4a3f-b379-8a4a9a92c75a", +"name": "Prompt", +"type": "n8n-nodes-base.set", +"position": [ +600, +240 +], +"parameters": { +"values": { +"string": [ +{ +"name": "input", +"value": "Return the 5 largest states by area in the USA with their 3 largest cities and their population." +} +] +}, +"options": {} +}, +"typeVersion": 2 +}, +{ +"id": "e2092fe6-d803-43e9-b2df-b0fc7aa83b02", +"name": "LLM Chain", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +1060, +240 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "711734d0-1003-4639-bdee-c160f6f976b3", +"name": "Structured Output Parser", +"type": "@n8n/n8n-nodes-langchain.outputParserStructured", +"position": [ +1560, +900 +], +"parameters": { +"jsonSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"state\": {\n \"type\": \"string\"\n },\n \"cities\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": \"string\",\n \"population\": \"number\"\n }\n }\n }\n }\n}" +}, +"typeVersion": 1 +}, +{ +"id": "f9b782f8-bb7b-4d65-be0d-d65c11de03d2", +"name": "Auto-fixing Output Parser", +"type": "@n8n/n8n-nodes-langchain.outputParserAutofixing", +"position": [ +1260, +540 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "a26f034e-ea19-47ba-8fef-4f0a0d447c01", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1480, +795 +], +"parameters": { +"height": 264.69900963477494, +"content": "### Parser which defines the output format and which gets used to validate the output" +}, +"typeVersion": 1 +}, +{ +"id": "d902971a-e304-449c-a933-900c9c49ce55", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1080, +792 +], +"parameters": { +"height": 266.9506012398238, +"content": "### The LLM which gets used to try to autofix the output in case it was not valid" +}, +"typeVersion": 1 +}, +{ +"id": "b4c3b935-61b1-4243-b7df-ba4b7fd6e3ce", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +920, +440 +], +"parameters": { +"height": 245.56048099185898, +"content": "### The LLM to process the original prompt" +}, +"typeVersion": 1 +}, +{ +"id": "916d2998-cf0e-40f9-a373-149c609ed229", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1200, +449 +], +"parameters": { +"width": 348.0763970423483, +"height": 233.17672716408998, +"content": "### Autofixing parser which tries to fix invalid outputs with the help of an LLM" +}, +"typeVersion": 1 +}, +{ +"id": "5cabf993-6bdd-4401-bb6d-fa20ff703127", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +980, +540 +], +"parameters": { +"options": { +"temperature": 0 +} +}, +"credentials": { +"openAiApi": { +"id": "wJtZwsVKW5v6R2Iy", +"name": "OpenAi account 2" +} +}, +"typeVersion": 1 +}, +{ +"id": "7f666edb-ecb7-4a6d-9dc7-ba67ef41d71f", +"name": "OpenAI Chat Model1", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +1140, +900 +], +"parameters": { +"options": { +"temperature": 0 +} +}, +"credentials": { +"openAiApi": { +"id": "wJtZwsVKW5v6R2Iy", +"name": "OpenAi account 2" +} +}, +"typeVersion": 1 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "976446d0-eb9d-478e-8178-69017329d736", +"connections": { +"Prompt": { +"main": [ +[ +{ +"node": "LLM Chain", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "LLM Chain", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"OpenAI Chat Model1": { +"ai_languageModel": [ +[ +{ +"node": "Auto-fixing Output Parser", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Structured Output Parser": { +"ai_outputParser": [ +[ +{ +"node": "Auto-fixing Output Parser", +"type": "ai_outputParser", +"index": 0 +} +] +] +}, +"Auto-fixing Output Parser": { +"ai_outputParser": [ +[ +{ +"node": "LLM Chain", +"type": "ai_outputParser", +"index": 0 +} +] +] +}, +"When clicking \"Execute Workflow\"": { +"main": [ +[ +{ +"node": "Prompt", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Generate 9_16 Images from Content and Brand Guidelines.txt b/Generate 9_16 Images from Content and Brand Guidelines.txt new file mode 100644 index 0000000..3f5994a --- /dev/null +++ b/Generate 9_16 Images from Content and Brand Guidelines.txt @@ -0,0 +1,1975 @@ +{ +"id": "VlCgU5K9SYQbdxTa", +"meta": { +"instanceId": "d868e3d040e7bda892c81b17cf446053ea25d2556fcef89cbe19dd61a3e876e9" +}, +"name": "Content to 9:16 Aspect Image Generator v1", +"tags": [ +{ +"id": "QsH2EXuw2e7YCv0K", +"name": "OpenAI", +"createdAt": "2024-11-15T04:05:20.872Z", +"updatedAt": "2024-11-15T04:05:20.872Z" +}, +{ +"id": "04PL2irdWYmF2Dg3", +"name": "RunwayML", +"createdAt": "2024-11-15T05:55:30.783Z", +"updatedAt": "2024-11-15T05:55:30.783Z" +}, +{ +"id": "yrY6updwSCXMsT0z", +"name": "Video", +"createdAt": "2024-11-15T05:55:34.333Z", +"updatedAt": "2024-11-15T05:55:34.333Z" +}, +{ +"id": "lvPj9rYRsKOHCi4J", +"name": "Creatomate", +"createdAt": "2024-11-19T15:59:16.134Z", +"updatedAt": "2024-11-19T15:59:16.134Z" +}, +{ +"id": "9LXACqpQLNtrM6or", +"name": "Leonardo", +"createdAt": "2024-11-19T15:59:21.368Z", +"updatedAt": "2024-11-19T15:59:21.368Z" +}, +{ +"id": "2DYOnQD6moK2E2VF", +"name": "App 2", +"createdAt": "2024-12-19T04:43:15.771Z", +"updatedAt": "2024-12-19T04:43:15.771Z" +} +], +"nodes": [ +{ +"id": "be5c3e43-cc86-4081-aa98-e7af3d22267d", +"name": "When clicking ‘Test workflow’", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +200, +-960 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "28f70c3a-bc45-4f43-80a6-69b592c8ce2e", +"name": "Sticky Note20", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-180, +-1200 +], +"parameters": { +"color": 6, +"width": 290, +"height": 1110, +"content": "# AlexK1919 \n![Alex Kim](https://media.licdn.com/dms/image/v2/D5603AQFOYMkqCPl6Sw/profile-displayphoto-shrink_400_400/profile-displayphoto-shrink_400_400/0/1718309808352?e=1736985600&v=beta&t=pQKm7lQfUU1ytuC2Gq1PRxNY-XmROFWbo-BjzUPxWOs)\n\n#### I’m Alex, an AI-Native Workflow Automation Architect Building Solutions to Optimize your Personal and Professional Life.\n\n### Example AirTable Base\nhttps://airtable.com/appRDq3E42JNtruIP/shrnc9EzlxpCq7Vxe\n\n### Link to my n8n Workflow Templates\nhttps://n8n.io/creators/alexk1919\n\n### Workflow Overview Video\nhttps://www.youtube.com/@alexk1919_\n\n### Products Used\n[AirTable](https://airtable.com)\n[OpenAI](https://openai.com/)\n[Leonardo.ai](https://app.leonardo.ai/?via=alexk1919)\n\n### About Me\nhttps://beacons.ai/alexk1919\n" +}, +"typeVersion": 1 +}, +{ +"id": "334044d8-e9a6-497e-9a11-63134233c8fa", +"name": "Sticky Note9", +"type": "n8n-nodes-base.stickyNote", +"position": [ +140, +-1200 +], +"parameters": { +"color": 7, +"width": 247, +"height": 1111, +"content": "# Triggers" +}, +"typeVersion": 1 +}, +{ +"id": "fcdf5c1a-3ddd-44cf-9b6d-a9afdd1fc256", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +420, +-1200 +], +"parameters": { +"color": 3, +"width": 427, +"height": 1111, +"content": "# 1. Retrieve Brand Guidelines" +}, +"typeVersion": 1 +}, +{ +"id": "a5a2bfcf-e2b7-4a9f-a766-7d08168c3d6f", +"name": "Set Guidelines", +"type": "n8n-nodes-base.set", +"position": [ +680, +-960 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "f803283a-f895-4794-87ad-46c63542ea4f", +"name": "id", +"type": "string", +"value": "={{ $json.id }}" +} +] +}, +"includeOtherFields": true +}, +"typeVersion": 3.4 +}, +{ +"id": "ab26d351-144d-477c-8dd3-a010c3fce0ca", +"name": "Sticky Note10", +"type": "n8n-nodes-base.stickyNote", +"position": [ +880, +-1200 +], +"parameters": { +"color": 4, +"width": 667, +"height": 1111, +"content": "# 2. Retrieve Blog Post/s" +}, +"typeVersion": 1 +}, +{ +"id": "f8e46822-cf7e-4697-bee4-99221b6063a7", +"name": "Get Brand Guidelines", +"type": "n8n-nodes-base.airtable", +"position": [ +480, +-960 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appRDq3E42JNtruIP", +"cachedResultUrl": "https://airtable.com/appRDq3E42JNtruIP", +"cachedResultName": "Content Manager" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblF8Ye2g0gPdpsaI", +"cachedResultUrl": "https://airtable.com/appRDq3E42JNtruIP/tblF8Ye2g0gPdpsaI", +"cachedResultName": "Brand Guidelines" +}, +"options": {}, +"operation": "search" +}, +"credentials": { +"airtableTokenApi": { +"id": "zS1BIbs19PvAC2d0", +"name": "AlexK Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "c6609f11-d04d-4e83-8fc0-af3c0e2cc9bd", +"name": "Get SEO Keywords", +"type": "n8n-nodes-base.airtable", +"position": [ +940, +-960 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appRDq3E42JNtruIP", +"cachedResultUrl": "https://airtable.com/appRDq3E42JNtruIP", +"cachedResultName": "Content Manager" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblU1fgGH1LXwnWRb", +"cachedResultUrl": "https://airtable.com/appRDq3E42JNtruIP/tblU1fgGH1LXwnWRb", +"cachedResultName": "SEO Keywords" +}, +"options": { +"fields": [ +"Keyword", +"RelatedContent" +] +}, +"operation": "search" +}, +"credentials": { +"airtableTokenApi": { +"id": "zS1BIbs19PvAC2d0", +"name": "AlexK Airtable Personal Access Token account" +} +}, +"executeOnce": false, +"typeVersion": 2.1 +}, +{ +"id": "d9201fa0-05d9-492b-896d-2cdc26e84f2e", +"name": "Remove Duplicates", +"type": "n8n-nodes-base.removeDuplicates", +"position": [ +1340, +-960 +], +"parameters": { +"compare": "selectedFields", +"options": {}, +"fieldsToCompare": "id" +}, +"typeVersion": 2 +}, +{ +"id": "68f2a29b-0e29-4a64-986b-9c1204c1d1ef", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1080, +-1040 +], +"parameters": { +"color": 3, +"width": 220, +"height": 240, +"content": "## Set keyword filter" +}, +"typeVersion": 1 +}, +{ +"id": "530dfb77-0aee-445d-8a1f-d8f2cbcd1640", +"name": "Keyword Filter", +"type": "n8n-nodes-base.filter", +"position": [ +1140, +-960 +], +"parameters": { +"options": { +"ignoreCase": true +}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": false, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "1b854a48-286a-486f-8a0f-4eb3b8d302ea", +"operator": { +"type": "string", +"operation": "contains" +}, +"leftValue": "={{ $json.Keyword }}", +"rightValue": "ai automation" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "75da86d6-22d4-42d6-8451-ea75db76ae57", +"name": "Get Content", +"type": "n8n-nodes-base.airtable", +"position": [ +1140, +-740 +], +"parameters": { +"id": "={{ $json.RelatedContent }}", +"base": { +"__rl": true, +"mode": "list", +"value": "appRDq3E42JNtruIP", +"cachedResultUrl": "https://airtable.com/appRDq3E42JNtruIP", +"cachedResultName": "Content Manager" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblU1fgGH1LXwnWRb", +"cachedResultUrl": "https://airtable.com/appRDq3E42JNtruIP/tblU1fgGH1LXwnWRb", +"cachedResultName": "SEO Keywords" +}, +"options": {} +}, +"credentials": { +"airtableTokenApi": { +"id": "zS1BIbs19PvAC2d0", +"name": "AlexK Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "7524c5d8-78bb-4a4e-9c56-af97b851b767", +"name": "Split Out Content", +"type": "n8n-nodes-base.splitOut", +"position": [ +1340, +-740 +], +"parameters": { +"include": "allOtherFields", +"options": {}, +"fieldToSplitOut": "id" +}, +"typeVersion": 1 +}, +{ +"id": "45d55ea1-ad01-4771-a2b2-67bb0cd1f983", +"name": "Split Out Keywords", +"type": "n8n-nodes-base.splitOut", +"position": [ +940, +-740 +], +"parameters": { +"include": "allOtherFields", +"options": {}, +"fieldToSplitOut": "RelatedContent" +}, +"typeVersion": 1 +}, +{ +"id": "349c64c2-2085-4b61-b9d2-dc1f0d7f46f6", +"name": "Limit", +"type": "n8n-nodes-base.limit", +"position": [ +1340, +-520 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "3b689583-6f40-4a6b-9afc-af128b2d4fca", +"name": "Sticky Note11", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1580, +-1200 +], +"parameters": { +"color": 5, +"width": 727, +"height": 1111, +"content": "# 3. Prepare Short Form Video Content" +}, +"typeVersion": 1 +}, +{ +"id": "bcdf8e9e-463c-43d4-a29e-7f90076815a1", +"name": "Script Prep", +"type": "@n8n/n8n-nodes-langchain.openAi", +"onError": "continueErrorOutput", +"position": [ +1640, +-960 +], +"parameters": { +"modelId": { +"__rl": true, +"mode": "list", +"value": "gpt-4o-mini", +"cachedResultName": "GPT-4O-MINI" +}, +"options": {}, +"messages": { +"values": [ +{ +"content": "=Prepare a script with 4 scenes for a short form video based on the following blog post:\n\nTitle:\n{{ $json.Title }}\n\nContent:\n{{ $json.Content }}\n\nThe video should be less than 30 seconds in length.\n\nAlso create image prompts for each scene within the script.\n\nThen output a image prompt for the video thmbnail.\n\nThe video will use a 9:16 aspect." +}, +{ +"role": "system", +"content": "Output format:\nMake sure you number each script and image prompt.\n\nScene 1 - 4\n- script #\n- image prompt #\n\nThumbnail Prompt" +} +] +}, +"jsonOutput": true +}, +"credentials": { +"openAiApi": { +"id": "ysxujEYFiY5ozRTS", +"name": "AlexK OpenAi Key" +} +}, +"typeVersion": 1.6 +}, +{ +"id": "be07f6e3-1e2d-4d4f-a8e0-1d642ca4b789", +"name": "Split Out Scenes", +"type": "n8n-nodes-base.splitOut", +"position": [ +2060, +-520 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "message.content.scenes" +}, +"typeVersion": 1 +}, +{ +"id": "83b3213d-70db-46d4-8dcc-5f399a64467d", +"name": "Split Out TN Prompt", +"type": "n8n-nodes-base.splitOut", +"position": [ +2060, +-1020 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "message.content.thumbnail_prompt" +}, +"typeVersion": 1 +}, +{ +"id": "d4f30eff-220a-4682-9072-f1bbbce3655c", +"name": "Leo - Improve Prompt1", +"type": "n8n-nodes-base.httpRequest", +"position": [ +2600, +-1020 +], +"parameters": { +"url": "https://cloud.leonardo.ai/api/rest/v1/prompt/improve", +"method": "POST", +"options": { +"response": { +"response": { +"fullResponse": true +} +} +}, +"jsonBody": "={\n \"prompt\": \"{{ $json['message.content[\\'Thumbnail Prompt\\']'] }}\"\n}", +"sendBody": true, +"sendHeaders": true, +"specifyBody": "json", +"authentication": "genericCredentialType", +"genericAuthType": "httpCustomAuth", +"headerParameters": { +"parameters": [ +{ +"name": "accept", +"value": "application/json" +} +] +} +}, +"credentials": { +"httpCustomAuth": { +"id": "pJguwbEclNjPgU6F", +"name": "Leo Custom Auth account" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "a1d32bae-67a0-487d-9583-0b53ab25d184", +"name": "Leo - Get imageId1", +"type": "n8n-nodes-base.httpRequest", +"position": [ +3200, +-1020 +], +"parameters": { +"url": "=https://cloud.leonardo.ai/api/rest/v1/generations/{{ $json.body.sdGenerationJob.generationId }}", +"options": { +"response": { +"response": { +"fullResponse": true +} +} +}, +"sendHeaders": true, +"authentication": "genericCredentialType", +"genericAuthType": "httpCustomAuth", +"headerParameters": { +"parameters": [ +{ +"name": "content-type", +"value": "application/json" +} +] +} +}, +"credentials": { +"httpCustomAuth": { +"id": "pJguwbEclNjPgU6F", +"name": "Leo Custom Auth account" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "89436c9d-1898-4f32-abf4-1f4fef7473a8", +"name": "Prompt Settings", +"type": "n8n-nodes-base.set", +"position": [ +2400, +-1020 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "56c8f20d-d9d9-4be7-ac2a-38df6ffdd722", +"name": "model", +"type": "string", +"value": "de7d3faf-762f-48e0-b3b7-9d0ac3a3fcf3" +}, +{ +"id": "dc66dd4a-9209-4790-b844-e19931accc39", +"name": "additional", +"type": "string", +"value": "Use the rule of thirds, leading lines, & balance." +} +] +}, +"includeOtherFields": true +}, +"typeVersion": 3.4 +}, +{ +"id": "9791db0e-c9a5-4fd8-b3fc-fd92b65c6362", +"name": "Leo - Generate Image1", +"type": "n8n-nodes-base.httpRequest", +"position": [ +2800, +-1020 +], +"parameters": { +"url": "https://cloud.leonardo.ai/api/rest/v1/generations", +"method": "POST", +"options": { +"response": { +"response": { +"fullResponse": true +} +} +}, +"jsonBody": "={\n \"alchemy\": true,\n \"width\": 768,\n \"height\": 1376,\n \"modelId\": \"{{ $('Prompt Settings').item.json.model }}\",\n \"num_images\": 1,\n \"presetStyle\": \"DYNAMIC\",\n \"prompt\": \"{{ $json.body.promptGeneration.prompt }};\",\n \"guidance_scale\": 7,\n \"highResolution\": true,\n \"promptMagic\": false,\n \"promptMagicStrength\": 0.5,\n \"promptMagicVersion\": \"v3\",\n \"public\": false,\n \"ultra\": false,\n \"photoReal\": false,\n \"negative_prompt\": \"\"\n} ", +"sendBody": true, +"sendHeaders": true, +"specifyBody": "json", +"authentication": "genericCredentialType", +"genericAuthType": "httpCustomAuth", +"headerParameters": { +"parameters": [ +{ +"name": "accept", +"value": "application/json" +} +] +} +}, +"credentials": { +"httpCustomAuth": { +"id": "pJguwbEclNjPgU6F", +"name": "Leo Custom Auth account" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "8b77e0b5-5ed5-401b-964f-e2a651b774ee", +"name": "Sticky Note12", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2340, +-1200 +], +"parameters": { +"color": 6, +"width": 1447, +"height": 531, +"content": "# 4. Generate Thumbnail Image" +}, +"typeVersion": 1 +}, +{ +"id": "64c5d0f0-07ce-493d-b974-69051ed41e0d", +"name": "Wait 30 Seconds", +"type": "n8n-nodes-base.wait", +"position": [ +3000, +-1020 +], +"webhookId": "08a6381f-bd3d-4cc1-8420-62c886406000", +"parameters": { +"amount": 30 +}, +"typeVersion": 1.1 +}, +{ +"id": "94e8f4a6-c22e-4938-bfc6-b5a040e3aa5e", +"name": "Sticky Note13", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2740, +-1100 +], +"parameters": { +"color": 3, +"width": 220, +"height": 280, +"content": "### Uses the latest Leonardo.ai Model: Phoenix 1.0" +}, +"typeVersion": 1 +}, +{ +"id": "d418088f-cebd-483a-b413-09f62faac1b7", +"name": "Leo - Improve Prompt", +"type": "n8n-nodes-base.httpRequest", +"position": [ +2800, +-420 +], +"parameters": { +"url": "https://cloud.leonardo.ai/api/rest/v1/prompt/improve", +"method": "POST", +"options": { +"response": { +"response": { +"fullResponse": true +} +} +}, +"jsonBody": "={\n \"prompt\": \"{{ $json.image_prompt }}\"\n}", +"sendBody": true, +"sendHeaders": true, +"specifyBody": "json", +"authentication": "genericCredentialType", +"genericAuthType": "httpCustomAuth", +"headerParameters": { +"parameters": [ +{ +"name": "accept", +"value": "application/json" +} +] +} +}, +"credentials": { +"httpCustomAuth": { +"id": "pJguwbEclNjPgU6F", +"name": "Leo Custom Auth account" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "c77d1f84-8db8-4ca5-9bcf-854a4bda9cf5", +"name": "Leo - Get imageId", +"type": "n8n-nodes-base.httpRequest", +"position": [ +3400, +-420 +], +"parameters": { +"url": "=https://cloud.leonardo.ai/api/rest/v1/generations/{{ $json.body.sdGenerationJob.generationId }}", +"options": { +"response": { +"response": { +"fullResponse": true +} +} +}, +"sendHeaders": true, +"authentication": "genericCredentialType", +"genericAuthType": "httpCustomAuth", +"headerParameters": { +"parameters": [ +{ +"name": "content-type", +"value": "application/json" +} +] +} +}, +"credentials": { +"httpCustomAuth": { +"id": "pJguwbEclNjPgU6F", +"name": "Leo Custom Auth account" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "3f8fef1e-c7ff-43d2-9385-4ab8a6dce553", +"name": "Prompt Settings1", +"type": "n8n-nodes-base.set", +"position": [ +2600, +-420 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "56c8f20d-d9d9-4be7-ac2a-38df6ffdd722", +"name": "model", +"type": "string", +"value": "de7d3faf-762f-48e0-b3b7-9d0ac3a3fcf3" +}, +{ +"id": "dc66dd4a-9209-4790-b844-e19931accc39", +"name": "additional", +"type": "string", +"value": "Use the rule of thirds, leading lines, & balance." +} +] +}, +"includeOtherFields": true +}, +"typeVersion": 3.4 +}, +{ +"id": "b6c43a16-29e8-4074-9dda-5661dfd3da5d", +"name": "Leo - Generate Image", +"type": "n8n-nodes-base.httpRequest", +"position": [ +3000, +-420 +], +"parameters": { +"url": "https://cloud.leonardo.ai/api/rest/v1/generations", +"method": "POST", +"options": { +"response": { +"response": { +"fullResponse": true +} +} +}, +"jsonBody": "={\n \"alchemy\": false,\n \"width\": 768,\n \"height\": 1376,\n \"modelId\": \"{{ $('Prompt Settings1').item.json.model }}\",\n \"num_images\": 1,\n \"presetStyle\": \"DYNAMIC\",\n \"prompt\": \"{{ $json.body.promptGeneration.prompt }};\",\n \"guidance_scale\": 7,\n \"highResolution\": true,\n \"promptMagic\": false,\n \"promptMagicStrength\": 0.5,\n \"promptMagicVersion\": \"v3\",\n \"public\": false,\n \"ultra\": true,\n \"photoReal\": false,\n \"negative_prompt\": \"\"\n} ", +"sendBody": true, +"sendHeaders": true, +"specifyBody": "json", +"authentication": "genericCredentialType", +"genericAuthType": "httpCustomAuth", +"headerParameters": { +"parameters": [ +{ +"name": "accept", +"value": "application/json" +} +] +} +}, +"credentials": { +"httpCustomAuth": { +"id": "pJguwbEclNjPgU6F", +"name": "Leo Custom Auth account" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "c3910b17-9a27-4419-ab01-409cc7090c68", +"name": "Wait 30 Seconds1", +"type": "n8n-nodes-base.wait", +"position": [ +3200, +-420 +], +"webhookId": "08a6381f-bd3d-4cc1-8420-62c886406000", +"parameters": { +"amount": 30 +}, +"typeVersion": 1.1 +}, +{ +"id": "85a320a3-7a06-41f9-a34a-de3fd1ce2950", +"name": "Loop Over Items", +"type": "n8n-nodes-base.splitInBatches", +"position": [ +2400, +-520 +], +"parameters": { +"options": { +"reset": false +} +}, +"typeVersion": 3 +}, +{ +"id": "8b3158d1-6be6-4446-8083-f3a9fa18e074", +"name": "Sticky Note14", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2340, +-640 +], +"parameters": { +"color": 6, +"width": 1447, +"height": 551, +"content": "# 4. Generate Scene Images" +}, +"typeVersion": 1 +}, +{ +"id": "3ee7e646-8690-4a7c-9820-ce2985b02e7a", +"name": "Add Asset Info", +"type": "n8n-nodes-base.airtable", +"position": [ +3400, +-1020 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appRDq3E42JNtruIP", +"cachedResultUrl": "https://airtable.com/appRDq3E42JNtruIP", +"cachedResultName": "Content Manager" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblqoaJ7bRLBgENED", +"cachedResultUrl": "https://airtable.com/appRDq3E42JNtruIP/tblqoaJ7bRLBgENED", +"cachedResultName": "Assets" +}, +"columns": { +"value": { +"Asset URL": "={{ $json.body.generations_by_pk.generated_images[0].url }}", +"File Size": 0, +"Asset Name": "=TN - {{ $('Get Content').item.json.Title }}", +"Asset Type": "Image" +}, +"schema": [ +{ +"id": "id", +"type": "string", +"display": true, +"removed": false, +"readOnly": true, +"required": false, +"displayName": "id", +"defaultMatch": true +}, +{ +"id": "Asset Name", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Asset Name", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Asset Type", +"type": "options", +"display": true, +"options": [ +{ +"name": "Image", +"value": "Image" +}, +{ +"name": "Video", +"value": "Video" +}, +{ +"name": "Document", +"value": "Document" +} +], +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Asset Type", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Upload Date", +"type": "dateTime", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Upload Date", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "File Size", +"type": "number", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "File Size", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Asset URL", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Asset URL", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Usage Rights", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Usage Rights", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Thumbnail", +"type": "array", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Thumbnail", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Associated Videos", +"type": "array", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Associated Videos", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Associated Social Media Posts", +"type": "array", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Associated Social Media Posts", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Associated Blog Posts", +"type": "array", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Associated Blog Posts", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Related Campaigns", +"type": "array", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Related Campaigns", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Schedules", +"type": "array", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Schedules", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Content Calendar", +"type": "array", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Content Calendar", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [ +"id" +] +}, +"options": {}, +"operation": "create" +}, +"credentials": { +"airtableTokenApi": { +"id": "zS1BIbs19PvAC2d0", +"name": "AlexK Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "88cd8514-9a54-47bf-b822-8c01ef05c08e", +"name": "Add Asset Info1", +"type": "n8n-nodes-base.airtable", +"position": [ +3600, +-420 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appRDq3E42JNtruIP", +"cachedResultUrl": "https://airtable.com/appRDq3E42JNtruIP", +"cachedResultName": "Content Manager" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblqoaJ7bRLBgENED", +"cachedResultUrl": "https://airtable.com/appRDq3E42JNtruIP/tblqoaJ7bRLBgENED", +"cachedResultName": "Assets" +}, +"columns": { +"value": { +"Asset URL": "={{ $json.body.generations_by_pk.generated_images[0].url }}", +"File Size": 0, +"Asset Name": "=Scene - {{ $('Loop Over Items').item.json.script }}", +"Asset Type": "Image" +}, +"schema": [ +{ +"id": "id", +"type": "string", +"display": true, +"removed": false, +"readOnly": true, +"required": false, +"displayName": "id", +"defaultMatch": true +}, +{ +"id": "Asset Name", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Asset Name", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Asset Type", +"type": "options", +"display": true, +"options": [ +{ +"name": "Image", +"value": "Image" +}, +{ +"name": "Video", +"value": "Video" +}, +{ +"name": "Document", +"value": "Document" +} +], +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Asset Type", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Upload Date", +"type": "dateTime", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Upload Date", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "File Size", +"type": "number", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "File Size", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Asset URL", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Asset URL", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Usage Rights", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Usage Rights", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Thumbnail", +"type": "array", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Thumbnail", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Associated Videos", +"type": "array", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Associated Videos", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Associated Social Media Posts", +"type": "array", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Associated Social Media Posts", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Associated Blog Posts", +"type": "array", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Associated Blog Posts", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Related Campaigns", +"type": "array", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Related Campaigns", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Schedules", +"type": "array", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Schedules", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Content Calendar", +"type": "array", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Content Calendar", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [ +"id" +] +}, +"options": {}, +"operation": "create" +}, +"credentials": { +"airtableTokenApi": { +"id": "zS1BIbs19PvAC2d0", +"name": "AlexK Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "67cd2444-506d-4754-a75d-e725239d6f7c", +"name": "Sticky Note15", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2740, +-500 +], +"parameters": { +"color": 3, +"width": 220, +"height": 280, +"content": "### Uses the latest Leonardo.ai Model: Phoenix 1.0" +}, +"typeVersion": 1 +}, +{ +"id": "1acc2d91-c4ba-4a26-bb74-a848875e9fac", +"name": "Wikipedia", +"type": "@n8n/n8n-nodes-langchain.toolWikipedia", +"position": [ +1640, +-740 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "1c5b5602-bf95-4534-8c73-69b8157765ee", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2940, +-840 +], +"parameters": { +"color": 7, +"width": 400, +"height": 80, +"content": "### Optionally, you can modify the number of images generated to provide more options" +}, +"typeVersion": 1 +}, +{ +"id": "79552e45-5dbc-4ddb-8543-039ca76dfe56", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2940, +-560 +], +"parameters": { +"color": 7, +"width": 400, +"height": 80, +"content": "### Optionally, you can modify the number of images generated to provide more options" +}, +"typeVersion": 1 +} +], +"active": false, +"pinData": { +"Set Guidelines": [ +{ +"json": { +"id": "rec3OS3As67j4mcGK", +"Name": "Imagery Style", +"createdTime": "2024-12-19T04:54:46.000Z" +} +}, +{ +"json": { +"id": "rec4h9vioTgCwE7f1", +"Name": "Tagline", +"Description": "Smart Automation. Smarter Results.", +"createdTime": "2024-12-19T04:54:02.000Z" +} +}, +{ +"json": { +"id": "rec5P2oEOUPHjplm6", +"Name": "Logo", +"createdTime": "2024-12-19T04:54:23.000Z" +} +}, +{ +"json": { +"id": "rec8DMroyovGEp8lP", +"Name": "Voice", +"Description": "Assertive, friendly, and educational – \"We sound like a trusted expert who’s here to help. We’re confident but approachable, breaking down complex ideas in a simple, actionable way.\"", +"createdTime": "2024-12-19T04:54:56.000Z" +} +}, +{ +"json": { +"id": "rec9BGsGreHnVAA6S", +"Name": "Audience", +"Description": "Primary Audience:\n\nMid-sized to enterprise businesses ($3M+ revenue)\nTech-savvy operations teams, AI enthusiasts, and digital creators\nSecondary Audience:\n\nWorkflow managers and automation specialists\nTech entrepreneurs and SaaS decision-makers\nPain Points Addressed:\n\nManual, repetitive tasks\nInefficient workflows slowing growth\nDifficulty leveraging AI and automation tools", +"createdTime": "2024-12-19T04:54:14.000Z" +} +}, +{ +"json": { +"id": "recMgJO7MkxxyigTC", +"Name": "Brand Don'ts", +"Description": "Overcomplicate messaging with jargon-heavy language.\nStretch, distort, or recolor the logo.\nUse off-brand imagery (e.g., cluttered visuals, low-quality images).\nCreate content without a clear takeaway or action.\nBe too formal or robotic – keep it human and approachable.", +"createdTime": "2024-12-19T04:55:24.000Z" +} +}, +{ +"json": { +"id": "recZYUAJk2TSaunVQ", +"Name": "Tone", +"Description": "Professional for enterprise communications (e.g., LinkedIn posts, newsletters).\nConversational and energetic for social media (e.g., YouTube, TikTok).\nInformative and engaging for tutorials and blogs.\n", +"createdTime": "2024-12-19T04:55:04.000Z" +} +}, +{ +"json": { +"id": "recfPdhqOCPFKtwBC", +"Name": "Vision", +"Description": "To build a future where AI-driven automation seamlessly integrates into every business, unlocking creativity, efficiency, and growth for all.", +"createdTime": "2024-12-19T04:50:31.000Z" +} +}, +{ +"json": { +"id": "recmVa42Fz4PI2h2E", +"Name": "Mission", +"Description": "To empower businesses and creators with smart, scalable automation and generative AI solutions that simplify workflows, save time, and drive innovation.", +"createdTime": "2024-12-19T04:50:31.000Z" +} +}, +{ +"json": { +"id": "recmsAphrjMsPfbbD", +"Name": "Brand Do's", +"Description": "Use the logo and brand colors consistently.\nSpeak clearly and simply about complex AI workflows.\nBalance creativity with professionalism in visuals.\nFocus on solving real problems with examples and storytelling.\nUse clean, modern designs in all content.", +"createdTime": "2024-12-19T04:55:15.000Z" +} +}, +{ +"json": { +"id": "recouwkSXqppzecEL", +"Name": "Brand Story", +"Description": "AlexK1919 was born from a love of AI, automation, and creativity. I saw businesses struggling with manual workflows and inefficiency, so I set out to build tools and share knowledge that simplify work and spark innovation. From branding to AI-native automations, the goal is simple: Empower businesses to work smarter, not harder.", +"createdTime": "2024-12-19T04:54:09.000Z" +} +}, +{ +"json": { +"id": "recrJ6KO6JOuB4xXT", +"Name": "Core Values", +"Description": "Exploration – \"We explore the edge of technology to uncover solutions that redefine possibilities.\"\nEfficiency – \"Every workflow, every solution – designed to optimize time, resources, and results.\"\nInnovation – \"We embrace new ideas, take risks, and push the boundaries of automation and AI.\"\nHonesty – \"Transparency is key; we say what we do and do what we say.\"\nImpact – \"We focus on meaningful results that create value for businesses and their teams.\"", +"createdTime": "2024-12-19T04:50:31.000Z" +} +}, +{ +"json": { +"id": "recvORk5EszN2Nopt", +"Name": "Color Palette", +"createdTime": "2024-12-19T04:54:31.000Z" +} +}, +{ +"json": { +"id": "reczwB6oMc7SGvboS", +"Name": "Typography", +"Description": "Inter", +"createdTime": "2024-12-19T04:54:39.000Z" +} +} +], +"Leo - Get imageId1": [ +{ +"json": { +"body": { +"generations_by_pk": { +"id": "40cf89f4-dc20-4546-b22c-26017f42d20f", +"seed": 711149708, +"ultra": false, +"motion": null, +"prompt": "Emerging from the computer screen, futuristic product designs intertwine with AI elements in a mesmerizing image of innovation. This digital creation depicts sleek, high-tech concepts in a dynamic and vibrant color palette. The visual is a highly detailed digital rendering that showcases cutting-edge technology and modern design aesthetics with impeccable precision. Each element exudes a sense of sophistication and creativity, capturing the essence of the boundary-pushing world of tech design.;", +"public": false, +"status": "COMPLETE", +"modelId": "de7d3faf-762f-48e0-b3b7-9d0ac3a3fcf3", +"createdAt": "2024-12-19T07:50:56.021", +"photoReal": false, +"scheduler": "EULER_DISCRETE", +"sdVersion": "PHOENIX", +"imageWidth": 768, +"imageHeight": 1376, +"motionModel": null, +"presetStyle": "DYNAMIC", +"promptMagic": false, +"imageToVideo": null, +"initStrength": null, +"fantasyAvatar": null, +"guidanceScale": 7, +"inferenceSteps": 12, +"motionStrength": null, +"negativePrompt": "", +"generated_images": [ +{ +"id": "03ae728b-f305-464d-9a61-92f624f50ee6", +"url": "https://cdn.leonardo.ai/users/18c4756f-8bfb-4e43-ac59-cc3ced68c735/generations/40cf89f4-dc20-4546-b22c-26017f42d20f/Leonardo_Phoenix_10_Emerging_from_the_computer_screen_futurist_0.jpg", +"nsfw": false, +"likeCount": 0, +"motionMP4URL": null, +"generated_image_variation_generics": [] +} +], +"photoRealStrength": null, +"promptMagicVersion": null, +"prompt_moderations": [ +{ +"moderationClassification": [] +} +], +"generation_elements": [], +"promptMagicStrength": null +} +}, +"headers": { +"date": "Thu, 19 Dec 2024 07:51:26 GMT", +"cf-ray": "8f45ceb46b4b2d15-IAD", +"server": "cloudflare", +"connection": "close", +"content-type": "application/json; charset=utf-8", +"x-request-id": "424eed5a65fd0dabcfa9f97ca9ea9a6b", +"content-length": "897", +"cf-cache-status": "DYNAMIC", +"referrer-policy": "strict-origin-when-cross-origin", +"x-frame-options": "SAMEORIGIN", +"x-xss-protection": "0", +"x-content-type-options": "nosniff", +"content-security-policy": "upgrade-insecure-requests", +"strict-transport-security": "max-age=31536000; includeSubDomains" +}, +"statusCode": 200, +"statusMessage": "OK" +} +} +], +"Get Brand Guidelines": [ +{ +"json": { +"id": "rec3OS3As67j4mcGK", +"Name": "Imagery Style", +"createdTime": "2024-12-19T04:54:46.000Z" +} +}, +{ +"json": { +"id": "rec4h9vioTgCwE7f1", +"Name": "Tagline", +"Content": "Smart Automation. Smarter Results.", +"createdTime": "2024-12-19T04:54:02.000Z" +} +}, +{ +"json": { +"id": "rec5P2oEOUPHjplm6", +"Name": "Logo", +"createdTime": "2024-12-19T04:54:23.000Z" +} +}, +{ +"json": { +"id": "rec8DMroyovGEp8lP", +"Name": "Voice", +"Content": "Assertive, friendly, and educational – \"We sound like a trusted expert who’s here to help. We’re confident but approachable, breaking down complex ideas in a simple, actionable way.\"", +"createdTime": "2024-12-19T04:54:56.000Z" +} +}, +{ +"json": { +"id": "rec9BGsGreHnVAA6S", +"Name": "Audience", +"Content": "Primary Audience:\n\nMid-sized to enterprise businesses ($3M+ revenue)\nTech-savvy operations teams, AI enthusiasts, and digital creators\nSecondary Audience:\n\nWorkflow managers and automation specialists\nTech entrepreneurs and SaaS decision-makers\nPain Points Addressed:\n\nManual, repetitive tasks\nInefficient workflows slowing growth\nDifficulty leveraging AI and automation tools", +"createdTime": "2024-12-19T04:54:14.000Z" +} +}, +{ +"json": { +"id": "recMgJO7MkxxyigTC", +"Name": "Brand Don'ts", +"Content": "Overcomplicate messaging with jargon-heavy language.\nStretch, distort, or recolor the logo.\nUse off-brand imagery (e.g., cluttered visuals, low-quality images).\nCreate content without a clear takeaway or action.\nBe too formal or robotic – keep it human and approachable.", +"createdTime": "2024-12-19T04:55:24.000Z" +} +}, +{ +"json": { +"id": "recZYUAJk2TSaunVQ", +"Name": "Tone", +"Content": "Professional for enterprise communications (e.g., LinkedIn posts, newsletters).\nConversational and energetic for social media (e.g., YouTube, TikTok).\nInformative and engaging for tutorials and blogs.\n", +"createdTime": "2024-12-19T04:55:04.000Z" +} +}, +{ +"json": { +"id": "recfPdhqOCPFKtwBC", +"Name": "Vision", +"Content": "To build a future where AI-driven automation seamlessly integrates into every business, unlocking creativity, efficiency, and growth for all.", +"createdTime": "2024-12-19T04:50:31.000Z" +} +}, +{ +"json": { +"id": "recmVa42Fz4PI2h2E", +"Name": "Mission", +"Content": "To empower businesses and creators with smart, scalable automation and generative AI solutions that simplify workflows, save time, and drive innovation.", +"createdTime": "2024-12-19T04:50:31.000Z" +} +}, +{ +"json": { +"id": "recmsAphrjMsPfbbD", +"Name": "Brand Do's", +"Content": "Use the logo and brand colors consistently.\nSpeak clearly and simply about complex AI workflows.\nBalance creativity with professionalism in visuals.\nFocus on solving real problems with examples and storytelling.\nUse clean, modern designs in all content.", +"createdTime": "2024-12-19T04:55:15.000Z" +} +}, +{ +"json": { +"id": "recouwkSXqppzecEL", +"Name": "Brand Story", +"Content": "AlexK1919 was born from a love of AI, automation, and creativity. I saw businesses struggling with manual workflows and inefficiency, so I set out to build tools and share knowledge that simplify work and spark innovation. From branding to AI-native automations, the goal is simple: Empower businesses to work smarter, not harder.", +"createdTime": "2024-12-19T04:54:09.000Z" +} +}, +{ +"json": { +"id": "recrJ6KO6JOuB4xXT", +"Name": "Core Values", +"Content": "Exploration – \"We explore the edge of technology to uncover solutions that redefine possibilities.\"\nEfficiency – \"Every workflow, every solution – designed to optimize time, resources, and results.\"\nInnovation – \"We embrace new ideas, take risks, and push the boundaries of automation and AI.\"\nHonesty – \"Transparency is key; we say what we do and do what we say.\"\nImpact – \"We focus on meaningful results that create value for businesses and their teams.\"", +"createdTime": "2024-12-19T04:50:31.000Z" +} +}, +{ +"json": { +"id": "recvORk5EszN2Nopt", +"Name": "Color Palette", +"createdTime": "2024-12-19T04:54:31.000Z" +} +}, +{ +"json": { +"id": "reczwB6oMc7SGvboS", +"Name": "Typography", +"Content": "Inter", +"createdTime": "2024-12-19T04:54:39.000Z" +} +} +], +"Leo - Generate Image1": [ +{ +"json": { +"body": { +"sdGenerationJob": { +"generationId": "40cf89f4-dc20-4546-b22c-26017f42d20f", +"apiCreditCost": 31 +} +}, +"headers": { +"date": "Thu, 19 Dec 2024 07:50:56 GMT", +"cf-ray": "8f45cdf2998557ea-IAD", +"server": "cloudflare", +"connection": "close", +"content-type": "application/json; charset=utf-8", +"x-request-id": "f8009585ede2caca5369318c9587883c", +"cf-cache-status": "DYNAMIC", +"referrer-policy": "strict-origin-when-cross-origin", +"x-frame-options": "SAMEORIGIN", +"x-xss-protection": "0", +"transfer-encoding": "chunked", +"x-content-type-options": "nosniff", +"content-security-policy": "upgrade-insecure-requests", +"strict-transport-security": "max-age=31536000; includeSubDomains" +}, +"statusCode": 200, +"statusMessage": "OK" +} +} +], +"Leo - Improve Prompt1": [ +{ +"json": { +"body": { +"promptGeneration": { +"prompt": "Emerging from the computer screen, futuristic product designs intertwine with AI elements in a mesmerizing image of innovation. This digital creation depicts sleek, high-tech concepts in a dynamic and vibrant color palette. The visual is a highly detailed digital rendering that showcases cutting-edge technology and modern design aesthetics with impeccable precision. Each element exudes a sense of sophistication and creativity, capturing the essence of the boundary-pushing world of tech design.", +"apiCreditCost": 4 +} +}, +"headers": { +"date": "Thu, 19 Dec 2024 07:50:01 GMT", +"cf-ray": "8f45cc9b28d8e5f8-IAD", +"server": "cloudflare", +"connection": "close", +"content-type": "application/json; charset=utf-8", +"x-request-id": "345fea24320e4c2d091413164b66b1a3", +"cf-cache-status": "DYNAMIC", +"referrer-policy": "strict-origin-when-cross-origin", +"x-frame-options": "SAMEORIGIN", +"x-xss-protection": "0", +"transfer-encoding": "chunked", +"x-content-type-options": "nosniff", +"content-security-policy": "upgrade-insecure-requests", +"strict-transport-security": "max-age=31536000; includeSubDomains" +}, +"statusCode": 200, +"statusMessage": "OK" +} +} +] +}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "fbfa83f0-1109-4c7e-9cd7-abfabc810f48", +"connections": { +"Limit": { +"main": [ +[ +{ +"node": "Script Prep", +"type": "main", +"index": 0 +} +] +] +}, +"Wikipedia": { +"ai_tool": [ +[ +{ +"node": "Script Prep", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Get Content": { +"main": [ +[ +{ +"node": "Split Out Content", +"type": "main", +"index": 0 +} +] +] +}, +"Script Prep": { +"main": [ +[ +{ +"node": "Split Out TN Prompt", +"type": "main", +"index": 0 +}, +{ +"node": "Split Out Scenes", +"type": "main", +"index": 0 +} +] +] +}, +"Keyword Filter": { +"main": [ +[ +{ +"node": "Remove Duplicates", +"type": "main", +"index": 0 +} +] +] +}, +"Set Guidelines": { +"main": [ +[ +{ +"node": "Get SEO Keywords", +"type": "main", +"index": 0 +} +] +] +}, +"Add Asset Info1": { +"main": [ +[ +{ +"node": "Loop Over Items", +"type": "main", +"index": 0 +} +] +] +}, +"Loop Over Items": { +"main": [ +[], +[ +{ +"node": "Prompt Settings1", +"type": "main", +"index": 0 +} +] +] +}, +"Prompt Settings": { +"main": [ +[ +{ +"node": "Leo - Improve Prompt1", +"type": "main", +"index": 0 +} +] +] +}, +"Wait 30 Seconds": { +"main": [ +[ +{ +"node": "Leo - Get imageId1", +"type": "main", +"index": 0 +} +] +] +}, +"Get SEO Keywords": { +"main": [ +[ +{ +"node": "Keyword Filter", +"type": "main", +"index": 0 +} +] +] +}, +"Prompt Settings1": { +"main": [ +[ +{ +"node": "Leo - Improve Prompt", +"type": "main", +"index": 0 +} +] +] +}, +"Split Out Scenes": { +"main": [ +[ +{ +"node": "Loop Over Items", +"type": "main", +"index": 0 +} +] +] +}, +"Wait 30 Seconds1": { +"main": [ +[ +{ +"node": "Leo - Get imageId", +"type": "main", +"index": 0 +} +] +] +}, +"Leo - Get imageId": { +"main": [ +[ +{ +"node": "Add Asset Info1", +"type": "main", +"index": 0 +} +] +] +}, +"Remove Duplicates": { +"main": [ +[ +{ +"node": "Split Out Keywords", +"type": "main", +"index": 0 +} +] +] +}, +"Split Out Content": { +"main": [ +[ +{ +"node": "Limit", +"type": "main", +"index": 0 +} +] +] +}, +"Leo - Get imageId1": { +"main": [ +[ +{ +"node": "Add Asset Info", +"type": "main", +"index": 0 +} +] +] +}, +"Split Out Keywords": { +"main": [ +[ +{ +"node": "Get Content", +"type": "main", +"index": 0 +} +] +] +}, +"Split Out TN Prompt": { +"main": [ +[ +{ +"node": "Prompt Settings", +"type": "main", +"index": 0 +} +] +] +}, +"Get Brand Guidelines": { +"main": [ +[ +{ +"node": "Set Guidelines", +"type": "main", +"index": 0 +} +] +] +}, +"Leo - Generate Image": { +"main": [ +[ +{ +"node": "Wait 30 Seconds1", +"type": "main", +"index": 0 +} +] +] +}, +"Leo - Improve Prompt": { +"main": [ +[ +{ +"node": "Leo - Generate Image", +"type": "main", +"index": 0 +} +] +] +}, +"Leo - Generate Image1": { +"main": [ +[ +{ +"node": "Wait 30 Seconds", +"type": "main", +"index": 0 +} +] +] +}, +"Leo - Improve Prompt1": { +"main": [ +[ +{ +"node": "Leo - Generate Image1", +"type": "main", +"index": 0 +} +] +] +}, +"When clicking ‘Test workflow’": { +"main": [ +[ +{ +"node": "Get Brand Guidelines", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Generate Instagram Content from Top Trends with AI Image Generation.txt b/Generate Instagram Content from Top Trends with AI Image Generation.txt new file mode 100644 index 0000000..8dae3ba --- /dev/null +++ b/Generate Instagram Content from Top Trends with AI Image Generation.txt @@ -0,0 +1,1434 @@ +{ +"id": "H7porcmXYj7StO23", +"meta": { +"instanceId": "35409808e3cc9dd8ecfa6f7b93ae931f074920a2f681e667da8974c0ecf81c52", +"templateId": "2537", +"templateCredsSetupCompleted": true +}, +"name": "Generate Instagram Content from Top Trends with AI Image Generation", +"tags": [], +"nodes": [ +{ +"id": "8c49be2b-6320-4eb0-8303-6448ced34636", +"name": "If media status is finished", +"type": "n8n-nodes-base.if", +"position": [ +1420, +260 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "0304efee-33b2-499e-bad1-9238c1fc2999", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.status_code }}", +"rightValue": "FINISHED" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "f0cc0be5-6d35-4334-a124-139fa8676d07", +"name": "If media status is finished1", +"type": "n8n-nodes-base.if", +"position": [ +2000, +260 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "0304efee-33b2-499e-bad1-9238c1fc2999", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.status_code }}", +"rightValue": "PUBLISHED" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "c8d8d8cd-8501-4d1b-ac28-8cb3fa74d9d7", +"name": "Telegram", +"type": "n8n-nodes-base.telegram", +"position": [ +1580, +440 +], +"parameters": { +"text": "Video upload edilmeden önce bir problem oldu", +"chatId": "={{ $('Telegram Params').item.json.telegram_chat_id }}", +"additionalFields": {} +}, +"credentials": { +"telegramApi": { +"id": "GcIVVl98RcazYBaB", +"name": "Telegram account" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "ae91a5e0-4f70-4a1c-afa5-41f5449facab", +"name": "Telegram1", +"type": "n8n-nodes-base.telegram", +"position": [ +2160, +100 +], +"parameters": { +"text": "Instagram Content is shared", +"chatId": "={{ $('Telegram Params').item.json.telegram_chat_id }}", +"additionalFields": {} +}, +"credentials": { +"telegramApi": { +"id": "GcIVVl98RcazYBaB", +"name": "Telegram account" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "b8b38440-14a7-43f6-ac49-6ca9502ff54d", +"name": "Telegram2", +"type": "n8n-nodes-base.telegram", +"position": [ +2160, +440 +], +"parameters": { +"text": "There was a problem when execution a upload content to instagram", +"chatId": "={{ $('Telegram Params').item.json.telegram_chat_id }}", +"additionalFields": {} +}, +"credentials": { +"telegramApi": { +"id": "GcIVVl98RcazYBaB", +"name": "Telegram account" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "82e0e5d0-bf50-4b2e-8693-2612dffe53e2", +"name": "Loop Over Items", +"type": "n8n-nodes-base.splitInBatches", +"position": [ +-1000, +220 +], +"parameters": { +"options": {} +}, +"typeVersion": 3 +}, +{ +"id": "fb72beb1-1a6a-4148-9ee4-cdc564c4dc5c", +"name": "Schedule Trigger1", +"type": "n8n-nodes-base.scheduleTrigger", +"position": [ +-3080, +300 +], +"parameters": { +"rule": { +"interval": [ +{ +"field": "cronExpression", +"expression": "5 13,19 * * *" +} +] +} +}, +"typeVersion": 1.2 +}, +{ +"id": "470f3406-19d2-420c-8f33-7031237d882c", +"name": "Telegram Params", +"type": "n8n-nodes-base.set", +"position": [ +-2320, +300 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "d18cdca7-d301-4c70-a4d0-8d6e7ecfc2d1", +"name": "telegram_chat_id", +"type": "string", +"value": "" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "12971505-7061-4d32-8921-d2e731eae9db", +"name": "Instagram params", +"type": "n8n-nodes-base.set", +"position": [ +-2560, +300 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "1e380c14-e908-4eeb-90e0-957a422829d0", +"name": "instagram_business_account_id", +"type": "string", +"value": "" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "3cb5f27d-eb3b-4fdc-bb55-1b54f85298e5", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-2860, +20 +], +"parameters": { +"color": 4, +"width": 1000, +"height": 600, +"content": "## All Credentials You Need\n** Instagram Business Account Id\n** Telegram Chat Id\n** Rapid Api Key\n** Replicate Token" +}, +"typeVersion": 1 +}, +{ +"id": "2bc617b8-835c-48ba-8de6-341a6c87b853", +"name": "Rapid Api params", +"type": "n8n-nodes-base.set", +"notes": "test", +"position": [ +-2080, +300 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "48a33ec7-2b4f-496a-ad77-e4d5f1907ee4", +"name": "x-rapid-api-key", +"type": "string", +"value": "" +} +] +} +}, +"notesInFlow": false, +"typeVersion": 3.4 +}, +{ +"id": "23bad41e-40ac-4488-8b2f-0d54d22a927a", +"name": "filter the image content", +"type": "n8n-nodes-base.code", +"position": [ +-1480, +380 +], +"parameters": { +"jsCode": "const filteredData = $input.first().json.data.items.filter(item=> !item.is_video)\nreturn filteredData.map((item)=>{\n return {\n id: item.id,\n prompt: item.caption.text,\n content_code: item.code,\n thumbnail_url: item.thumbnail_url,\n tag: $input.first().json.data.additional_data.name\n }\n}) \n\n" +}, +"typeVersion": 2 +}, +{ +"id": "a65690cd-4d30-4541-b80d-aae872326a77", +"name": "get top trends on instagram #blender3d", +"type": "n8n-nodes-base.httpRequest", +"position": [ +-1720, +180 +], +"parameters": { +"url": "https://instagram-scraper-api2.p.rapidapi.com/v1/hashtag", +"options": {}, +"sendQuery": true, +"sendHeaders": true, +"queryParameters": { +"parameters": [ +{ +"name": "hashtag", +"value": "blender3d" +}, +{ +"name": "feed_type", +"value": "top" +} +] +}, +"headerParameters": { +"parameters": [ +{ +"name": "x-rapidapi-host", +"value": "instagram-scraper-api2.p.rapidapi.com" +}, +{ +"name": "x-rapidapi-key", +"value": "={{ $json['x-rapid-api-key'] }}" +} +] +} +}, +"typeVersion": 4.2 +}, +{ +"id": "8707c475-7e28-4d80-92b8-ba24033c4632", +"name": "get top trends on instagram #isometric", +"type": "n8n-nodes-base.httpRequest", +"position": [ +-1720, +380 +], +"parameters": { +"url": "https://instagram-scraper-api2.p.rapidapi.com/v1/hashtag", +"options": {}, +"sendQuery": true, +"sendHeaders": true, +"queryParameters": { +"parameters": [ +{ +"name": "hashtag", +"value": "isometric" +}, +{ +"name": "feed_type", +"value": "top" +} +] +}, +"headerParameters": { +"parameters": [ +{ +"name": "x-rapidapi-host", +"value": "instagram-scraper-api2.p.rapidapi.com" +}, +{ +"name": "x-rapidapi-key", +"value": "={{ $json['x-rapid-api-key'] }}" +} +] +} +}, +"typeVersion": 4.2 +}, +{ +"id": "1c1bfd8f-b086-4147-ba08-578877f2a315", +"name": "merge the array content", +"type": "n8n-nodes-base.merge", +"position": [ +-1280, +280 +], +"parameters": {}, +"typeVersion": 3 +}, +{ +"id": "dcc2b6b6-9880-4676-8a1a-a3c21e583bba", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-3180, +20 +], +"parameters": { +"color": 3, +"width": 280, +"height": 600, +"content": "## Schedule Your Time To Post\n" +}, +"typeVersion": 1 +}, +{ +"id": "c1e0ac33-c4b7-47d8-bd2b-0b74b02afe38", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-2600, +160 +], +"parameters": { +"color": 5, +"width": 180, +"height": 300, +"content": "## Guide \n** [Guide](https://docs.matillion.com/metl/docs/6957316//) of getting of Instagram Business Account Id " +}, +"typeVersion": 1 +}, +{ +"id": "321680da-ca7a-4c6f-98d4-a0d8f8d0347f", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-2360, +160 +], +"parameters": { +"color": 5, +"width": 180, +"height": 300, +"content": "## Guide \n** [Guide](https://rapidapi.com/i-yqerddkq0t/api/telegram92/tutorials/how-to-get-the-id-of-a-telegram-channel,-chat,-user-or-bot%3F) of Getting of Telegram Chat Id " +}, +"typeVersion": 1 +}, +{ +"id": "b3d07cf7-8d03-4644-88f7-2e94de0c43c2", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-2120, +160 +], +"parameters": { +"color": 5, +"width": 180, +"height": 300, +"content": "## Guide \n** [Guide](https://docs.rapidapi.com/docs/keys-and-key-rotation) of Getting of Rapid Api Key " +}, +"typeVersion": 1 +}, +{ +"id": "b6dbdfaa-fc71-4def-a723-bf6c0facd372", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-2360, +480 +], +"parameters": { +"color": 7, +"width": 180, +"height": 120, +"content": "## Warning\n**Don't forgot the create bot and send a message to bot first" +}, +"typeVersion": 1 +}, +{ +"id": "81d598e2-8993-4315-9894-2e78dc26ad10", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1820, +20 +], +"parameters": { +"width": 660, +"height": 600, +"content": "## Getting Top Trend Posts On Instagram\n** Change the topic you want to get on http request" +}, +"typeVersion": 1 +}, +{ +"id": "6beb79ef-8205-4882-9bb0-6a2e1a33f1d4", +"name": "Check Data on Database Is Exist", +"type": "n8n-nodes-base.postgres", +"onError": "continueErrorOutput", +"position": [ +-760, +220 +], +"parameters": { +"table": { +"__rl": true, +"mode": "list", +"value": "top_trends", +"cachedResultName": "top_trends" +}, +"where": { +"values": [ +{ +"value": "={{$json.content_code}}", +"column": "code" +} +] +}, +"schema": { +"__rl": true, +"mode": "list", +"value": "public", +"cachedResultName": "public" +}, +"options": {}, +"operation": "select" +}, +"credentials": { +"postgres": { +"id": "sBHQ2psBsfnHkFrZ", +"name": "Postgres account" +} +}, +"typeVersion": 2.5, +"alwaysOutputData": true +}, +{ +"id": "5b0c05a8-3eb7-4ad8-88e8-ceef81fe7a61", +"name": "If Data is Exist", +"type": "n8n-nodes-base.if", +"position": [ +-540, +240 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "loose" +}, +"combinator": "and", +"conditions": [ +{ +"id": "9dc20983-ae4d-40db-b969-7d43fa8b0c3e", +"operator": { +"type": "boolean", +"operation": "true", +"singleValue": true +}, +"leftValue": "={{ !$json.isEmpty() }}", +"rightValue": "we" +}, +{ +"id": "0e1b9264-be56-4d0c-a83e-d9ca0b05b265", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "", +"rightValue": "" +} +] +}, +"looseTypeValidation": true +}, +"executeOnce": false, +"typeVersion": 2.2, +"alwaysOutputData": false +}, +{ +"id": "557aa2c3-8d0b-42c4-b444-953a538d7ff4", +"name": "Sticky Note9", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1120, +20 +], +"parameters": { +"width": 1060, +"height": 600, +"content": "## Looping Data And Checking For Is Exist On Database\n**We are checking until find a data we did not insert because we don't want to create content about in same content" +}, +"typeVersion": 1 +}, +{ +"id": "9b510f11-9a44-4d54-b162-3ffb55d66677", +"name": "send error message to telegram", +"type": "n8n-nodes-base.telegram", +"position": [ +-1000, +440 +], +"parameters": { +"text": "There was a problem execution a postgresql content", +"chatId": "={{ $('Telegram Params').item.json.telegram_chat_id}}", +"additionalFields": {} +}, +"credentials": { +"telegramApi": { +"id": "GcIVVl98RcazYBaB", +"name": "Telegram account" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "48bc61de-d416-4673-9e9b-8331ea841891", +"name": "insert data on db", +"type": "n8n-nodes-base.postgres", +"position": [ +-260, +240 +], +"parameters": { +"table": { +"__rl": true, +"mode": "list", +"value": "top_trends", +"cachedResultName": "top_trends" +}, +"schema": { +"__rl": true, +"mode": "list", +"value": "public" +}, +"columns": { +"value": { +"tag": "={{$('Loop Over Items').item.json.tag}}", +"code": "={{$('Loop Over Items').item.json.content_code}}", +"prompt": "={{$('Loop Over Items').item.json.prompt}}", +"isposted": false, +"thumbnail_url": "={{$('Loop Over Items').item.json.thumbnail_url}}" +}, +"schema": [ +{ +"id": "id", +"type": "number", +"display": true, +"removed": true, +"required": false, +"displayName": "id", +"defaultMatch": true, +"canBeUsedToMatch": true +}, +{ +"id": "prompt", +"type": "string", +"display": true, +"required": true, +"displayName": "prompt", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "isposted", +"type": "boolean", +"display": true, +"required": false, +"displayName": "isposted", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "createdat", +"type": "dateTime", +"display": true, +"removed": true, +"required": false, +"displayName": "createdat", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "updatedat", +"type": "dateTime", +"display": true, +"removed": true, +"required": false, +"displayName": "updatedat", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "deletedat", +"type": "dateTime", +"display": true, +"removed": true, +"required": false, +"displayName": "deletedat", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "code", +"type": "string", +"display": true, +"required": false, +"displayName": "code", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "tag", +"type": "string", +"display": true, +"required": false, +"displayName": "tag", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "thumbnail_url", +"type": "string", +"display": true, +"required": false, +"displayName": "thumbnail_url", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [ +"id" +], +"attemptToConvertTypes": false, +"convertFieldsToString": false +}, +"options": {} +}, +"credentials": { +"postgres": { +"id": "sBHQ2psBsfnHkFrZ", +"name": "Postgres account" +} +}, +"typeVersion": 2.5 +}, +{ +"id": "15e7d69d-a10f-48a1-b240-046e9950d077", +"name": "Analyze Image and give the content", +"type": "@n8n/n8n-nodes-langchain.openAi", +"position": [ +80, +240 +], +"parameters": { +"text": "Create a clear and concise description of the object in the image, focusing on its physical and general features. Avoid detailed environmental aspects like background, lighting, or colors. Describe the shape, texture, size, and any unique characteristics of the object. Mention any notable features that make the object stand out, such as its surface details, materials, and design. The description should be focused on the object itself, not its surroundings.\n\nFor example, describe the following image:\n", +"modelId": { +"__rl": true, +"mode": "list", +"value": "gpt-4o-mini", +"cachedResultName": "GPT-4O-MINI" +}, +"options": {}, +"resource": "image", +"imageUrls": "={{ $('Loop Over Items').item.json.thumbnail_url }}", +"operation": "analyze" +}, +"credentials": { +"openAiApi": { +"id": "1TwEayhZUT90fq8N", +"name": "OpenAi account" +} +}, +"typeVersion": 1.8 +}, +{ +"id": "93e253b1-da7d-4193-b899-a38e6fd9f4e4", +"name": "Analyze Content And Generate Instagram Caption", +"type": "@n8n/n8n-nodes-langchain.openAi", +"position": [ +280, +240 +], +"parameters": { +"modelId": { +"__rl": true, +"mode": "list", +"value": "gpt-4o-mini", +"cachedResultName": "GPT-4O-MINI" +}, +"options": {}, +"messages": { +"values": [ +{ +"content": "=\nSummarize the following content description into a short, engaging Instagram caption under 150 words. The caption should focus on the content of the image, not the app. Keep it appealing to social media users, and highlight the visual details of the image. Include hashtags relevant to 3D modeling and design, such as #Blender3D, #3DArt, #DigitalArt, #3DModeling, and #ArtCommunity. Ensure the tone is friendly and inviting.\n\n\nContent description to summarize:\n{{ $json.content }}\n\nMake sure to craft the caption around the content's features, such as the color contrast, reflective surface, and artistic nature of the image.\n\n" +} +] +} +}, +"credentials": { +"openAiApi": { +"id": "1TwEayhZUT90fq8N", +"name": "OpenAi account" +} +}, +"typeVersion": 1.8 +}, +{ +"id": "9af1dc59-1d9e-4900-8f80-1eba946c4057", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-20, +20 +], +"parameters": { +"color": 4, +"width": 860, +"height": 600, +"content": "## Analyze Post Content\n** We are analyzing the image\n** We are generating a instagram caption by content\n** Then we are generating the image" +}, +"typeVersion": 1 +}, +{ +"id": "2259f6df-dca9-4a7e-babb-e63375f7207f", +"name": "Prepare data on Instagram", +"type": "n8n-nodes-base.facebookGraphApi", +"position": [ +980, +260 +], +"parameters": { +"edge": "media", +"node": "={{ $('Instagram params').item.json.instagram_business_account_id }}", +"options": { +"queryParameters": { +"parameter": [ +{ +"name": "image_url", +"value": "={{ $json.output[0] }}" +}, +{ +"name": "caption", +"value": "={{ $('Analyze Content And Generate Instagram Caption').item.json.message.content }}" +} +] +} +}, +"graphApiVersion": "v20.0", +"httpRequestMethod": "POST" +}, +"credentials": { +"facebookGraphApi": { +"id": "ZFxxxLfZ25M7Va6r", +"name": "Facebook Graph account" +} +}, +"typeVersion": 1 +}, +{ +"id": "bcbb6058-1966-4bb5-915a-1e65b9131117", +"name": "Check Status Of Media Before Uploaded", +"type": "n8n-nodes-base.facebookGraphApi", +"position": [ +1200, +260 +], +"parameters": { +"node": "={{ $json.id }}", +"options": { +"fields": { +"field": [ +{ +"name": "id" +}, +{ +"name": "status" +}, +{ +"name": "status_code" +} +] +} +}, +"graphApiVersion": "v20.0" +}, +"credentials": { +"facebookGraphApi": { +"id": "ZFxxxLfZ25M7Va6r", +"name": "Facebook Graph account" +} +}, +"typeVersion": 1 +}, +{ +"id": "518d87ff-7808-4c06-b137-4e97d8f2ca28", +"name": "Publish Media on Instagram", +"type": "n8n-nodes-base.facebookGraphApi", +"position": [ +1600, +100 +], +"parameters": { +"edge": "media_publish", +"node": "={{ $('Instagram params').item.json.instagram_business_account_id }}", +"options": { +"queryParameters": { +"parameter": [ +{ +"name": "creation_id", +"value": "={{ $json.id }}" +} +] +} +}, +"graphApiVersion": "v20.0", +"httpRequestMethod": "POST" +}, +"credentials": { +"facebookGraphApi": { +"id": "ZFxxxLfZ25M7Va6r", +"name": "Facebook Graph account" +} +}, +"typeVersion": 1 +}, +{ +"id": "a033d12b-524f-40e8-9208-5300bbc823d3", +"name": "Check status of post ", +"type": "n8n-nodes-base.facebookGraphApi", +"position": [ +1800, +260 +], +"parameters": { +"node": "={{ $('Check Status Of Media Before Uploaded').item.json.id }}", +"options": { +"fields": { +"field": [ +{ +"name": "id" +}, +{ +"name": "status" +}, +{ +"name": "status_code" +} +] +} +}, +"graphApiVersion": "v20.0" +}, +"credentials": { +"facebookGraphApi": { +"id": "ZFxxxLfZ25M7Va6r", +"name": "Facebook Graph account" +} +}, +"typeVersion": 1 +}, +{ +"id": "f136e907-2938-4175-b51f-4201fbe3477d", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +880, +20 +], +"parameters": { +"color": 5, +"width": 1580, +"height": 600, +"content": "## Publish On Instagram And Send Message When Published via Telegram\n" +}, +"typeVersion": 1 +}, +{ +"id": "8145986c-5453-43ac-8d5c-c50a84a62136", +"name": "Sticky Note10", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1800, +100 +], +"parameters": { +"color": 5, +"width": 260, +"height": 500, +"content": "## For More About Api\n** [Facebook Scraper Api Guide](https://rapidapi.com/social-api1-instagram/api/instagram-scraper-api2/playground/apiendpoint_a45552b2-9850-4da9-b5cb-bbdd3ac2199d)" +}, +"typeVersion": 1 +}, +{ +"id": "02416fbb-4250-4278-af23-1f9189787123", +"name": "filter the image content-2", +"type": "n8n-nodes-base.code", +"position": [ +-1480, +180 +], +"parameters": { +"jsCode": "const filteredData = $input.first().json.data.items.filter(item=> !item.is_video)\nreturn filteredData.map((item)=>{\n return {\n id: item.id,\n prompt: item.caption.text,\n content_code: item.code,\n thumbnail_url: item.thumbnail_url,\n tag: $input.first().json.data.additional_data.name\n }\n}) \n\n" +}, +"typeVersion": 2 +}, +{ +"id": "2d1ea53d-1d32-4b86-8944-ce2ad4a69847", +"name": "Sticky Note11", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-2820, +160 +], +"parameters": { +"color": 5, +"width": 180, +"height": 300, +"content": "## Guide \n** [Guide](https://replicate.com) of getting of Replicate Token " +}, +"typeVersion": 1 +}, +{ +"id": "c8b933af-356e-49ae-92d3-42eaf4ee3e9f", +"name": "Replicate params", +"type": "n8n-nodes-base.set", +"position": [ +-2780, +300 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "1e380c14-e908-4eeb-90e0-957a422829d0", +"name": "replicate_token", +"type": "string", +"value": "" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "2c73cc9c-d436-459b-9b3c-bd870810b9b4", +"name": "Generate image on flux", +"type": "n8n-nodes-base.httpRequest", +"position": [ +680, +260 +], +"parameters": { +"url": "https://api.replicate.com/v1/models/black-forest-labs/flux-schnell/predictions", +"method": "POST", +"options": {}, +"jsonBody": "={\n \"input\": {\n \"prompt\": \"A highly detailed 3D isometric model of {{$('Analyze Image and give the content').item.json.content .replace(/\\\\n/g, ' ') \n.replace(/\\\\t/g, ' ') \n.replace(/\\s+/g, ' ')\n.trim(); }} rendered in a stylized miniature toy aesthetic. Materials: Matte plastic/painted metal/weathered stone texture with no self-shadowing. Lighting: - Completely shadowless rendering - Ultra bright and perfectly even illumination from all angles - Pure ambient lighting without directional shadows - Flat, consistent lighting across all surfaces - No ambient occlusion. Style specifications: - Clean, defined edges and surfaces - Slightly exaggerated proportions - Miniature/toy-like scale - Subtle wear and texturing - Rich color palette with muted tones - Isometric 3/4 view angle - Crisp details and micro-elements. Technical details: - 4K resolution - PBR materials without shadows - No depth of field - High-quality anti-aliasing - Perfect uniform lighting. Environment: Pure white background with zero shadows or gradients. Post-processing: High key lighting, maximum brightness, shadow removal.\",\n \"output_format\": \"jpg\",\n \"output_quality\": 100,\n \"go_fast\":false\n }\n}\n", +"sendBody": true, +"sendHeaders": true, +"specifyBody": "=json", +"bodyParameters": { +"parameters": [ +{} +] +}, +"headerParameters": { +"parameters": [ +{ +"name": "Authorization", +"value": "=Bearer {{ $('Replicate params').item.json.replicate_token}}" +}, +{ +"name": "Prefer", +"value": "wait" +} +] +} +}, +"typeVersion": 4.2 +}, +{ +"id": "6f9e7dc6-1287-4235-8631-198d729f367f", +"name": "Sticky Note12", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1120, +-340 +], +"parameters": { +"color": 4, +"width": 1060, +"height": 320, +"content": "## For top_trends Table\n```\nCREATE TABLE top_trends (\n id SERIAL PRIMARY KEY,\n isposted BOOLEAN DEFAULT false,\n createdat TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,\n updatedat TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,\n deletedat TIMESTAMP WITHOUT TIME ZONE,\n prompt TEXT NOT NULL,\n thumbnail_url TEXT,\n code TEXT,\n tag TEXT\n);\n```" +}, +"typeVersion": 1 +}, +{ +"id": "b19951bb-6346-44a7-a4c8-1bd0806c6019", +"name": "Sticky Note13", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-660, +-120 +], +"parameters": { +"color": 3, +"width": 160, +"height": 120, +"content": "## Warning\n** Don't forgot the create top_trends table" +}, +"typeVersion": 1 +}, +{ +"id": "3de6b8e5-c5e0-4999-871a-c349cb9b3ac0", +"name": "Sticky Note14", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-3180, +-940 +], +"parameters": { +"width": 620, +"height": 840, +"content": "\n## Automated Instagram Content Creation from Trending Posts\n\nThis workflow automates the process of discovering and recreating trending content on Instagram:\n\n1. Content Discovery:\n - Scrapes top trending posts from specific hashtags (#blender3d, #isometric)\n - Filters for image-only content (excludes videos)\n - Checks database to avoid duplicate content\n\n2. AI-Powered Content Generation:\n - Analyzes trending images using GPT-4 Vision\n - Generates detailed descriptions of visual elements\n - Creates engaging Instagram captions with relevant hashtags\n - Uses Flux AI to generate similar but unique images\n\n3. Publishing & Monitoring:\n - Automatically posts content to Instagram Business Account\n - Monitors post status and publishing process\n - Sends status updates via Telegram\n\nPerfect for content creators and businesses looking to maintain an active Instagram presence with AI-generated content inspired by current trends. The workflow runs on schedule and handles everything from content discovery to publication automatically.\n\nNote: Requires Instagram Business Account, Telegram Bot, OpenAI, and Replicate API credentials." +}, +"typeVersion": 1 +}, +{ +"id": "dfd0d182-177c-4336-8950-4792ea739123", +"name": "Sticky Note15", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-2120, +480 +], +"parameters": { +"color": 7, +"width": 180, +"height": 120, +"content": "##Warning\n** Dont forgot the subscribe [Instagram Scraper Api](https://rapidapi.com/social-api1-instagram/api/instagram-scraper-api2/playground/apiendpoint_a45552b2-9850-4da9-b5cb-bbdd3ac2199d)" +}, +"typeVersion": 1 +}, +{ +"id": "03330941-3c6e-4152-8c51-f1d53f4424bc", +"name": "Sticky Note16", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-2120, +640 +], +"parameters": { +"width": 180, +"height": 180, +"content": "## Warning\n** You can check the [rate limit](https://rapidapi.com/social-api1-instagram/api/instagram-scraper-api2) of the Instagram Scraper Api on Rapid Api\n** Free version is monthly 500 request\n" +}, +"typeVersion": 1 +} +], +"active": false, +"pinData": {}, +"settings": { +"timezone": "Europe/Istanbul", +"callerPolicy": "workflowsFromSameOwner", +"executionOrder": "v1" +}, +"versionId": "cc50f9e8-373b-433a-af43-824a264e762a", +"connections": { +"Telegram": { +"main": [ +[] +] +}, +"Loop Over Items": { +"main": [ +[], +[ +{ +"node": "Check Data on Database Is Exist", +"type": "main", +"index": 0 +} +] +] +}, +"Telegram Params": { +"main": [ +[ +{ +"node": "Rapid Api params", +"type": "main", +"index": 0 +} +] +] +}, +"If Data is Exist": { +"main": [ +[ +{ +"node": "Loop Over Items", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "insert data on db", +"type": "main", +"index": 0 +} +] +] +}, +"Instagram params": { +"main": [ +[ +{ +"node": "Telegram Params", +"type": "main", +"index": 0 +} +] +] +}, +"Rapid Api params": { +"main": [ +[ +{ +"node": "get top trends on instagram #isometric", +"type": "main", +"index": 0 +}, +{ +"node": "get top trends on instagram #blender3d", +"type": "main", +"index": 0 +} +] +] +}, +"Replicate params": { +"main": [ +[ +{ +"node": "Instagram params", +"type": "main", +"index": 0 +} +] +] +}, +"Schedule Trigger1": { +"main": [ +[ +{ +"node": "Replicate params", +"type": "main", +"index": 0 +} +] +] +}, +"insert data on db": { +"main": [ +[ +{ +"node": "Analyze Image and give the content", +"type": "main", +"index": 0 +} +] +] +}, +"Check status of post ": { +"main": [ +[ +{ +"node": "If media status is finished1", +"type": "main", +"index": 0 +} +] +] +}, +"Generate image on flux": { +"main": [ +[ +{ +"node": "Prepare data on Instagram", +"type": "main", +"index": 0 +} +] +] +}, +"merge the array content": { +"main": [ +[ +{ +"node": "Loop Over Items", +"type": "main", +"index": 0 +} +] +] +}, +"filter the image content": { +"main": [ +[ +{ +"node": "merge the array content", +"type": "main", +"index": 1 +} +] +] +}, +"Prepare data on Instagram": { +"main": [ +[ +{ +"node": "Check Status Of Media Before Uploaded", +"type": "main", +"index": 0 +} +] +] +}, +"Publish Media on Instagram": { +"main": [ +[ +{ +"node": "Check status of post ", +"type": "main", +"index": 0 +} +] +] +}, +"filter the image content-2": { +"main": [ +[ +{ +"node": "merge the array content", +"type": "main", +"index": 0 +} +] +] +}, +"If media status is finished": { +"main": [ +[ +{ +"node": "Publish Media on Instagram", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Telegram", +"type": "main", +"index": 0 +} +] +] +}, +"If media status is finished1": { +"main": [ +[ +{ +"node": "Telegram1", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Telegram2", +"type": "main", +"index": 0 +} +] +] +}, +"Check Data on Database Is Exist": { +"main": [ +[ +{ +"node": "If Data is Exist", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "send error message to telegram", +"type": "main", +"index": 0 +} +] +] +}, +"Analyze Image and give the content": { +"main": [ +[ +{ +"node": "Analyze Content And Generate Instagram Caption", +"type": "main", +"index": 0 +} +] +] +}, +"Check Status Of Media Before Uploaded": { +"main": [ +[ +{ +"node": "If media status is finished", +"type": "main", +"index": 0 +} +] +] +}, +"get top trends on instagram #isometric": { +"main": [ +[ +{ +"node": "filter the image content", +"type": "main", +"index": 0 +} +] +] +}, +"get top trends on instagram #blender3d": { +"main": [ +[ +{ +"node": "filter the image content-2", +"type": "main", +"index": 0 +} +] +] +}, +"Analyze Content And Generate Instagram Caption": { +"main": [ +[ +{ +"node": "Generate image on flux", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Generate SEO Seed Keywords Using AI.txt b/Generate SEO Seed Keywords Using AI.txt new file mode 100644 index 0000000..e9005c2 --- /dev/null +++ b/Generate SEO Seed Keywords Using AI.txt @@ -0,0 +1,338 @@ +{ +"meta": { +"instanceId": "257476b1ef58bf3cb6a46e65fac7ee34a53a5e1a8492d5c6e4da5f87c9b82833", +"templateId": "2473" +}, +"nodes": [ +{ +"id": "1205b121-8aaa-4e41-874b-4e81aad6374e", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +120, +600 +], +"parameters": { +"color": 4, +"width": 462.4041757955455, +"height": 315.6388466176832, +"content": "## Generate SEO Seed Keywords Using AI\n\nThis flow uses an AI node to generate Seed Keywords to focus SEO efforts on based on your ideal customer profile\n\n**Outputs:** \n- List of 20 Seed Keywords\n\n\n**Pre-requisites / Dependencies:**\n- You know your ideal customer profile (ICP)\n- An AI API account (either OpenAI or Anthropic recommended)" +}, +"typeVersion": 1 +}, +{ +"id": "d2654d75-2b64-4ec3-b583-57d2b6b7b195", +"name": "Sticky Note13", +"type": "n8n-nodes-base.stickyNote", +"disabled": true, +"position": [ +640, +920 +], +"parameters": { +"color": 7, +"width": 287.0816455493243, +"height": 330.47923074942287, +"content": "**Generate draft seed KW based on ICP**\n\n" +}, +"typeVersion": 1 +}, +{ +"id": "d248a58e-3705-4b6f-99cb-e9187e56781c", +"name": "Anthropic Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic", +"position": [ +680, +1120 +], +"parameters": { +"options": {} +}, +"typeVersion": 1.2 +}, +{ +"id": "71517d83-59f5-441a-8a75-c35f4e06a8a2", +"name": "Split Out", +"type": "n8n-nodes-base.splitOut", +"position": [ +980, +980 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "output.answer" +}, +"typeVersion": 1 +}, +{ +"id": "1c68eff5-6478-4eba-9abe-3ccea2a17a5c", +"name": "Sticky Note12", +"type": "n8n-nodes-base.stickyNote", +"disabled": true, +"position": [ +120, +920 +], +"parameters": { +"color": 7, +"width": 492.16246201447336, +"height": 213.62075341687063, +"content": "**Get data from airtable and format** " +}, +"typeVersion": 1 +}, +{ +"id": "53dcc524-ef3d-40b8-b79d-976517dce4e7", +"name": "Sticky Note17", +"type": "n8n-nodes-base.stickyNote", +"disabled": true, +"position": [ +960, +920 +], +"parameters": { +"color": 7, +"width": 348.42891651921957, +"height": 213.62075341687063, +"content": "**Add data to database**" +}, +"typeVersion": 1 +}, +{ +"id": "570495fe-3f1d-44ae-bea0-9fa4b2ce15ef", +"name": "Sticky Note11", +"type": "n8n-nodes-base.stickyNote", +"position": [ +640, +820 +], +"parameters": { +"color": 6, +"width": 393.46745700785266, +"height": 80, +"content": "**Costs to run**\nApprox. $0.02-0.05 for a run using Claude Sonnet 3.5" +}, +"typeVersion": 1 +}, +{ +"id": "6e5e84c5-409f-4f37-931a-21a44aff7c5e", +"name": "Set Ideal Customer Profile (ICP)", +"type": "n8n-nodes-base.set", +"position": [ +160, +980 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "973e949e-1afd-4378-8482-d2168532eff6", +"name": "product", +"type": "string", +"value": "=**Replace this with a string detailing your intended product (if you have one)**" +}, +{ +"id": "ce9c0a8f-6157-4b46-8b77-133545dc71bd", +"name": "pain points", +"type": "string", +"value": "=**Replace this with a string list of customer pain points**" +}, +{ +"id": "5abc858a-c412-4acf-acb9-488e4d992d2f", +"name": "goals", +"type": "string", +"value": "=**Replace this with a string list of your customers key goals/objectives**" +}, +{ +"id": "fbdd1ef7-c1b9-48eb-b73e-a383f12b5ba1", +"name": "current solutions", +"type": "string", +"value": "=**Replace this with a string detailing how your ideal customer currently solves their pain ppoints**" +}, +{ +"id": "2e5c8f48-266e-486c-956f-51f1449f6288", +"name": "expertise level", +"type": "string", +"value": "=**Replace this with a string detailing customer level of expertise**" +} +] +} +}, +"notesInFlow": true, +"typeVersion": 3.4 +}, +{ +"id": "bd5781f4-6f35-45d3-8182-12ea6712eddf", +"name": "Aggregate for AI node", +"type": "n8n-nodes-base.aggregate", +"position": [ +380, +980 +], +"parameters": { +"options": {}, +"aggregate": "aggregateAllItemData" +}, +"notesInFlow": true, +"typeVersion": 1 +}, +{ +"id": "244943bf-e4dd-40fc-9a43-7a5cd0da1c5b", +"name": "Sticky Note14", +"type": "n8n-nodes-base.stickyNote", +"position": [ +640, +1260 +], +"parameters": { +"color": 3, +"width": 284.87764467541297, +"height": 80, +"content": "**REQUIRED**\nConnect to your own AI API above" +}, +"typeVersion": 1 +}, +{ +"id": "73c8f47a-4fdb-40c8-9062-890ef1265ab0", +"name": "Sticky Note16", +"type": "n8n-nodes-base.stickyNote", +"position": [ +120, +1140 +], +"parameters": { +"color": 3, +"width": 284.87764467541297, +"height": 80, +"content": "**REQUIRED**\nSet your Ideal Customer Profile before proceeding" +}, +"typeVersion": 1 +}, +{ +"id": "a5b93e6d-44ab-4b6f-b86a-25dc621b52b0", +"name": "AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +660, +980 +], +"parameters": { +"text": "=User:\nHere are some important rules for you to follow:\n\n1. Analyze the ICP information carefully.\n2. Generate 15-20 seed keywords that are relevant to the ICP's needs, challenges, goals, and search behavior.\n3. Ensure the keywords are broad enough to be considered \"\"head\"\" terms, but specific enough to target the ICP effectively.\n4. Consider various aspects of the ICP's journey, including awareness, consideration, and decision stages.\n5. Include a mix of product-related, problem-related, and solution-related terms.\n6. Think beyond just the product itself - consider industry trends, related technologies, and broader business concepts that would interest the ICP.\n7. Avoid overly generic terms that might attract irrelevant traffic.\n8. Aim for a mix of keyword difficulties, including both competitive and less competitive terms.\n9. Include keywords that cover different search intents: informational, navigational, commercial, and transactional.\n10. Consider related tools or platforms that the ICP might use, and include relevant integration-related keywords.\n11. If applicable, include some location-specific keywords based on the ICP's geographic information.\n12. Incorporate industry-specific terminology or jargon that the ICP would likely use in their searches.\n13. Consider emerging trends or pain points in the ICP's industry that they might be searching for solutions to.\n13. Format the keywords in lowercase, without punctuation. Trim any leading or trailing white space.\n\n\nYour output should be an array of strings, each representing a seed keyword:\n\n['b2b lead generation', 'startup marketing strategies', 'saas sales funnel', ...]\n\n\nHere is the Ideal Customer Profile (ICP) information:\n\n{{ $json.data[0].product }}\n\n\nNow:\nBased on the provided ICP, generate an array of 15-20 seed keywords that will form the foundation of a comprehensive SEO strategy for this B2B SaaS company. These keywords should reflect a deep understanding of the ICP's needs, challenges, and search behavior, while also considering broader industry trends and related concepts.\n\nFirst, write out your ideas in {thoughts: } JSON as part of your analysis, then answer inside the {answer: } key in the JSON. ", +"agent": "conversationalAgent", +"options": { +"systemMessage": "=System: You are an expert SEO strategist tasked with generating 15-20 key head search terms (seed keywords) for a B2B SaaS company. Your goal is to create a comprehensive list of keywords that will attract and engage the ideal customer profile (ICP) described." +}, +"promptType": "define" +}, +"typeVersion": 1.6 +}, +{ +"id": "ca3c0bd5-7ef0-4e2b-9b5e-071773c32c85", +"name": "Connect to your own database", +"type": "n8n-nodes-base.noOp", +"position": [ +1140, +980 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "94639a81-5e46-482a-851a-5443bfe9863c", +"name": "Sticky Note15", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1120, +1140 +], +"parameters": { +"color": 3, +"width": 284.87764467541297, +"height": 80, +"content": "**REQUIRED**\nConnect to your own database / GSheet / Airtable base to output these" +}, +"typeVersion": 1 +}, +{ +"id": "16498e92-c0d5-44f4-b993-c9c8930955bc", +"name": "When clicking ‘Test workflow’", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +-60, +980 +], +"parameters": {}, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"AI Agent": { +"main": [ +[ +{ +"node": "Split Out", +"type": "main", +"index": 0 +} +] +] +}, +"Split Out": { +"main": [ +[ +{ +"node": "Connect to your own database", +"type": "main", +"index": 0 +} +] +] +}, +"Anthropic Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Aggregate for AI node": { +"main": [ +[ +{ +"node": "AI Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Set Ideal Customer Profile (ICP)": { +"main": [ +[ +{ +"node": "Aggregate for AI node", +"type": "main", +"index": 0 +} +] +] +}, +"When clicking ‘Test workflow’": { +"main": [ +[ +{ +"node": "Set Ideal Customer Profile (ICP)", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Generate SQL queries from schema only - AI-powered.txt b/Generate SQL queries from schema only - AI-powered.txt new file mode 100644 index 0000000..7c4bfeb --- /dev/null +++ b/Generate SQL queries from schema only - AI-powered.txt @@ -0,0 +1,758 @@ +{ +"id": "P307QnrxpA1ddsM5", +"meta": { +"instanceId": "fb924c73af8f703905bc09c9ee8076f48c17b596ed05b18c0ff86915ef8a7c4a", +"templateCredsSetupCompleted": true +}, +"name": "Generate SQL queries from schema only - AI-powered", +"tags": [], +"nodes": [ +{ +"id": "b7c3ca47-11b3-4378-81fa-68b2f56b295e", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +1460, +440 +], +"parameters": { +"model": "gpt-4o", +"options": { +"temperature": 0.2 +} +}, +"credentials": { +"openAiApi": { +"id": "rveqdSfp7pCRON1T", +"name": "Ted's Tech Talks OpenAi" +} +}, +"typeVersion": 1 +}, +{ +"id": "977c3a82-440b-4d44-9042-47a673bcb52c", +"name": "Window Buffer Memory", +"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow", +"position": [ +1640, +440 +], +"parameters": { +"contextWindowLength": 10 +}, +"typeVersion": 1.2 +}, +{ +"id": "c6e9c0e2-d238-4f0b-a4c8-2271f2c8b31b", +"name": "No Operation, do nothing", +"type": "n8n-nodes-base.noOp", +"position": [ +2340, +520 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "4c141ae8-d2d1-45c7-bb5d-f33841d3cee6", +"name": "List all tables in a database", +"type": "n8n-nodes-base.mySql", +"position": [ +520, +-35 +], +"parameters": { +"query": "SHOW TABLES;", +"options": {}, +"operation": "executeQuery" +}, +"credentials": { +"mySql": { +"id": "ICakJ1LRuVl4dRTs", +"name": "db4free TTT account" +} +}, +"typeVersion": 2.4 +}, +{ +"id": "54fb3362-041b-4e4f-bfea-f0bc788d8dfd", +"name": "Extract database schema", +"type": "n8n-nodes-base.mySql", +"position": [ +700, +-35 +], +"parameters": { +"query": "DESCRIBE {{ $json.Tables_in_tttytdb2023 }};", +"options": {}, +"operation": "executeQuery" +}, +"credentials": { +"mySql": { +"id": "ICakJ1LRuVl4dRTs", +"name": "db4free TTT account" +} +}, +"typeVersion": 2.4 +}, +{ +"id": "d55e841d-11ed-4ce2-8c8e-840bd807ff2c", +"name": "Add table name to output", +"type": "n8n-nodes-base.set", +"position": [ +880, +-35 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "764176d6-3c89-404d-9c71-301e8a406a68", +"name": "table", +"type": "string", +"value": "={{ $('List all tables in a database').item.json.Tables_in_tttytdb2023 }}" +} +] +}, +"includeOtherFields": true +}, +"typeVersion": 3.4 +}, +{ +"id": "ca8d30d6-c1f1-4e89-8cd5-ea3648dc3b0c", +"name": "Convert data to binary", +"type": "n8n-nodes-base.convertToFile", +"position": [ +1060, +-35 +], +"parameters": { +"options": {}, +"operation": "toJson" +}, +"typeVersion": 1.1 +}, +{ +"id": "2d89f901-d4e7-4fea-bd69-20b518280bbc", +"name": "Save file locally", +"type": "n8n-nodes-base.readWriteFile", +"position": [ +1220, +-35 +], +"parameters": { +"options": {}, +"fileName": "./chinook_mysql.json", +"operation": "write" +}, +"typeVersion": 1 +}, +{ +"id": "04511c4f-44fa-4c23-87af-54d959e6cb2c", +"name": "Extract data from file", +"type": "n8n-nodes-base.extractFromFile", +"position": [ +920, +420 +], +"parameters": { +"options": {}, +"operation": "fromJson" +}, +"typeVersion": 1 +}, +{ +"id": "96f129c0-d1d4-4cbf-a24d-0b0cea18a229", +"name": "Chat Trigger", +"type": "@n8n/n8n-nodes-langchain.chatTrigger", +"position": [ +440, +420 +], +"webhookId": "c308dec7-655c-4b79-832e-991bd8ea891f", +"parameters": { +"options": {} +}, +"typeVersion": 1.1 +}, +{ +"id": "4d993ed9-3bbe-4bc3-9e5b-c3d738b0e714", +"name": "AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +1480, +300 +], +"parameters": { +"text": "=Here is the database schema: {{ $json.schema }}\nHere is the user request: {{ $('Chat Trigger').item.json.chatInput }}", +"agent": "conversationalAgent", +"options": { +"humanMessage": "TOOLS\n------\nAssistant can ask the user to use tools to look up information that may be helpful in answering the users original question. The tools the human can use are:\n\n{tools}\n\n{format_instructions}\n\nUSER'S INPUT\n--------------------\nHere is the user's input (remember to respond with a markdown code snippet of a json blob with a single action, and NOTHING else):\n\n{{input}}", +"systemMessage": "Assistant is a large language model trained by OpenAI.\n\nAssistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.\n\nAssistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.\n\nOverall, Assistant is a powerful system that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist.\n\nHelp user to work with the MySQL database.\n\nPlease wrap any sql commands into triple quotes. You don't have a tool to run SQL, so the user will do that instead of you." +}, +"promptType": "define" +}, +"typeVersion": 1.6 +}, +{ +"id": "f5749b31-b28a-4341-b57f-94ee422d2873", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +320, +-280 +], +"parameters": { +"color": 3, +"width": 1065.0949045120822, +"height": 466.4256045427794, +"content": "## Run this part only once\nThis section:\n* loads a list of all tables from the database hosted on [db4free](https://db4free.net/signup.php) \n* extracts the database schema for each table and adds the table name\n* converts the schema into a binary JSON format\n* saves the schema `./chinook_mysql.json` file locally\n\n***Now you can use chat to \"talk\" to your data!*** 🎉" +}, +"typeVersion": 1 +}, +{ +"id": "6606abc9-1dcb-4dba-b7ef-e221f892eed8", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1040, +-255 +], +"parameters": { +"color": 6, +"width": 312.47220527158765, +"height": 174.60585869504342, +"content": "## Pre-workflow setup \nConnect to a free MySQL server and import your database. Follow Step 1 and 2 in this [tutorial](https://blog.n8n.io/compare-databases/) for more.\n\n*The Chinook data used in this workflow is available on [GitHub](https://github.com/msimanga/chinook/tree/master/mysql).* " +}, +"typeVersion": 1 +}, +{ +"id": "c8ac730a-04ee-499d-b845-1149967d6aa2", +"name": "When clicking \"Test workflow\"", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +360, +-35 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "6f0b167c-e012-43e1-9892-ded05be47cf8", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +324.32561050665913, +209.72072645338642 +], +"parameters": { +"color": 6, +"width": 1062.678698911262, +"height": 489.29614613074125, +"content": "## On every chat message:\n\n* The workflow gets the data from the local schema file and extracts it as a JSON object. This way, we achieve two important improvements:\n * faster processing time as we don't need to fetch the schema for each table from a slow remote database\n * the Agent will know database structure without seeing the actual data\n* DB schema is then converted into a long string, JSON fields from the Chat Trigger are added before they are entered into the Agent node.\n" +}, +"typeVersion": 1 +}, +{ +"id": "3a79350c-aec1-4ad4-a2e0-679957fa420b", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1400, +-15.552780029374958 +], +"parameters": { +"color": 6, +"width": 445.66588600071304, +"height": 714.7896619176862, +"content": "### LangChain AI Agent's system prompt is modified.\nIt uses only the database schema to generate SQL queries. The agent creates these queries but does not execute them. Instead, it passes them to subsequent nodes.\n\n**Example:**\n\"Can you show me the list of all German customers?\" \n\nQueries are generated only when necessary; for some requests, a query may not be needed. This is because certain questions can be answered directly without SQL execution.\n\n**Example:**\n\"Can you list me all tables?\"" +}, +"typeVersion": 1 +}, +{ +"id": "0cd425db-2a8e-4f48-b749-9a082e948395", +"name": "Combine schema data and chat input", +"type": "n8n-nodes-base.set", +"position": [ +1140, +420 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "42abd24e-419a-47d6-bc8b-7146dd0b8314", +"name": "sessionId", +"type": "string", +"value": "={{ $('Chat Trigger').first().json.sessionId }}" +}, +{ +"id": "39244192-a1a6-42fe-bc75-a6fba1f264df", +"name": "action", +"type": "string", +"value": "={{ $('Chat Trigger').first().json.action }}" +}, +{ +"id": "f78c57d9-df13-43c7-89a7-5387e528107e", +"name": "chatinput", +"type": "string", +"value": "={{ $('Chat Trigger').first().json.chatInput }}" +}, +{ +"id": "e42b39eb-dfbd-48d9-94ed-d658bdd41454", +"name": "schema", +"type": "string", +"value": "={{ $json.data }}" +} +] +} +}, +"executeOnce": true, +"typeVersion": 3.4 +}, +{ +"id": "e4045e33-bb87-488d-8ccf-b4a94339a841", +"name": "Load the schema from the local file", +"type": "n8n-nodes-base.readWriteFile", +"position": [ +680, +420 +], +"parameters": { +"options": {}, +"fileSelector": "./chinook_mysql.json" +}, +"typeVersion": 1 +}, +{ +"id": "367ebe95-0b87-44f6-8392-33fe65446c24", +"name": "Extract SQL query", +"type": "n8n-nodes-base.set", +"position": [ +1900, +340 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "ebbe194a-4b8b-44c9-ac19-03cf69d353bf", +"name": "query", +"type": "string", +"value": "={{ ($json.output.match(/SELECT[\\s\\S]*?;/i) || [])[0] || \"\" }}" +} +] +}, +"includeOtherFields": true +}, +"typeVersion": 3.4 +}, +{ +"id": "b856fe78-2435-4075-97f8-ecbeecf3e780", +"name": "Check if query exists", +"type": "n8n-nodes-base.if", +"position": [ +2060, +340 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "2963d04d-9d79-49f9-b52a-dc8732aca781", +"operator": { +"type": "string", +"operation": "notEmpty", +"singleValue": true +}, +"leftValue": "={{ $json.query }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "87162d31-2f6c-4f4a-af28-c65cbadd8ed5", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1874, +220.45316744685329 +], +"parameters": { +"color": 3, +"width": 317.8901548206743, +"height": 278.8174358200552, +"content": "## SQL query extraction\nCheck if the agent's response contains an SQL query. If it does, we extract the query using a regular expression." +}, +"typeVersion": 1 +}, +{ +"id": "b3e77333-eaa9-4d23-a78c-8a19ae074739", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1860, +-16.43746604251737 +], +"parameters": { +"color": 6, +"width": 882.7611828369563, +"height": 715.7029266156915, +"content": "" +}, +"typeVersion": 1 +}, +{ +"id": "269ea79d-5f17-4764-aebb-bba31b43d8bb", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1580, +580 +], +"parameters": { +"color": 3, +"width": 257.46308756569573, +"height": 108.03673727584527, +"content": "The AI Agent remembers the schema, questions, and final answers, but not data values, since queries run externally. The agent can't access database content. " +}, +"typeVersion": 1 +}, +{ +"id": "2fd1175c-4110-48be-b6bf-2251c678bc04", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2420, +0 +], +"parameters": { +"color": 3, +"width": 308.8514666587585, +"height": 123.43139661532095, +"content": "- The SQL node accesses the database and executes the query. The results are then formatted for readability.\n- Both the chat response and the query result are displayed in the chat window." +}, +"typeVersion": 1 +}, +{ +"id": "61ae7f7c-1424-4ecb-8a12-78cd98e94d45", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2480, +600 +], +"parameters": { +"color": 3, +"width": 250.40895053328057, +"height": 89.90186716520257, +"content": "When the agent responds without an SQL query, you receive an immediate answer with no additional processing." +}, +"typeVersion": 1 +}, +{ +"id": "cbb6d1e1-0a75-4b3a-89cd-6bd545b8d414", +"name": "Format query results", +"type": "n8n-nodes-base.set", +"position": [ +2420, +140 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "f944d21f-6aac-4842-8926-4108d6cad4bf", +"name": "sqloutput", +"type": "string", +"value": "={{ Object.keys($jmespath($input.all(),'[].json')[0]).join(' | ') }} \n{{ ($jmespath($input.all(),'[].json')).map(obj => Object.values(obj).join(' | ')).join('\\n') }}" +} +] +} +}, +"executeOnce": true, +"typeVersion": 3.4 +}, +{ +"id": "d958de24-84ef-4928-a7f3-32cada09a0eb", +"name": "Run SQL query", +"type": "n8n-nodes-base.mySql", +"position": [ +2260, +140 +], +"parameters": { +"query": "{{ $json.query }}", +"options": {}, +"operation": "executeQuery" +}, +"credentials": { +"mySql": { +"id": "ICakJ1LRuVl4dRTs", +"name": "db4free TTT account" +} +}, +"typeVersion": 2.4 +}, +{ +"id": "99a6dc03-1035-4866-81e4-11dc66bf98ec", +"name": "Prepare final output", +"type": "n8n-nodes-base.set", +"position": [ +2560, +420 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "aa55e186-1535-4923-aee4-e088ca69575b", +"name": "output", +"type": "string", +"value": "={{ $json.output }}\n\nSQL result:\n```markdown\n{{ $json.sqloutput }}\n```" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "9380c2f6-15d9-43e4-80a2-3019bcf5ae04", +"name": "Combine query result and chat answer", +"type": "n8n-nodes-base.merge", +"position": [ +2340, +340 +], +"parameters": { +"mode": "combine", +"options": {}, +"combineBy": "combineByPosition" +}, +"typeVersion": 3 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "15049b13-91cb-46bd-a7a0-ad648b6f667a", +"connections": { +"AI Agent": { +"main": [ +[ +{ +"node": "Extract SQL query", +"type": "main", +"index": 0 +} +] +] +}, +"Chat Trigger": { +"main": [ +[ +{ +"node": "Load the schema from the local file", +"type": "main", +"index": 0 +} +] +] +}, +"Run SQL query": { +"main": [ +[ +{ +"node": "Format query results", +"type": "main", +"index": 0 +} +] +] +}, +"Extract SQL query": { +"main": [ +[ +{ +"node": "Check if query exists", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Format query results": { +"main": [ +[ +{ +"node": "Combine query result and chat answer", +"type": "main", +"index": 0 +} +] +] +}, +"Window Buffer Memory": { +"ai_memory": [ +[ +{ +"node": "AI Agent", +"type": "ai_memory", +"index": 0 +} +] +] +}, +"Check if query exists": { +"main": [ +[ +{ +"node": "Run SQL query", +"type": "main", +"index": 0 +}, +{ +"node": "Combine query result and chat answer", +"type": "main", +"index": 1 +} +], +[ +{ +"node": "No Operation, do nothing", +"type": "main", +"index": 0 +} +] +] +}, +"Convert data to binary": { +"main": [ +[ +{ +"node": "Save file locally", +"type": "main", +"index": 0 +} +] +] +}, +"Extract data from file": { +"main": [ +[ +{ +"node": "Combine schema data and chat input", +"type": "main", +"index": 0 +} +] +] +}, +"Extract database schema": { +"main": [ +[ +{ +"node": "Add table name to output", +"type": "main", +"index": 0 +} +] +] +}, +"Add table name to output": { +"main": [ +[ +{ +"node": "Convert data to binary", +"type": "main", +"index": 0 +} +] +] +}, +"List all tables in a database": { +"main": [ +[ +{ +"node": "Extract database schema", +"type": "main", +"index": 0 +} +] +] +}, +"When clicking \"Test workflow\"": { +"main": [ +[ +{ +"node": "List all tables in a database", +"type": "main", +"index": 0 +} +] +] +}, +"Combine schema data and chat input": { +"main": [ +[ +{ +"node": "AI Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Load the schema from the local file": { +"main": [ +[ +{ +"node": "Extract data from file", +"type": "main", +"index": 0 +} +] +] +}, +"Combine query result and chat answer": { +"main": [ +[ +{ +"node": "Prepare final output", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Generate Text-to-Speech Using Elevenlabs via API.txt b/Generate Text-to-Speech Using Elevenlabs via API.txt new file mode 100644 index 0000000..9f3ecb4 --- /dev/null +++ b/Generate Text-to-Speech Using Elevenlabs via API.txt @@ -0,0 +1,186 @@ +{ +"nodes": [ +{ +"id": "73b64763-5e18-4ff1-bb52-ba25a08d3c3a", +"name": "If params correct", +"type": "n8n-nodes-base.if", +"position": [ +500, +200 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "2e968b41-88f7-4b28-9837-af50ae130979", +"operator": { +"type": "string", +"operation": "exists", +"singleValue": true +}, +"leftValue": "voice_id", +"rightValue": "" +}, +{ +"id": "ad961bc9-6db8-4cac-8c63-30930e8beca7", +"operator": { +"type": "string", +"operation": "exists", +"singleValue": true +}, +"leftValue": "text", +"rightValue": "" +} +] +} +}, +"typeVersion": 2 +}, +{ +"id": "39079dec-54c5-458e-afa1-56ee5723f3a3", +"name": "Respond to Webhook", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +960, +180 +], +"parameters": { +"options": {}, +"respondWith": "binary" +}, +"typeVersion": 1.1 +}, +{ +"id": "b6a344f4-28ac-41a7-8e6a-a2782a5d1c68", +"name": "Webhook", +"type": "n8n-nodes-base.webhook", +"position": [ +300, +200 +], +"webhookId": "5acc6769-6c0f-42a8-a69c-b05e437e18a9", +"parameters": { +"path": "generate-voice", +"options": {}, +"httpMethod": "POST", +"responseMode": "responseNode" +}, +"typeVersion": 2 +}, +{ +"id": "a25dec72-152b-4457-a18f-9cbbd31840ec", +"name": "Generate voice", +"type": "n8n-nodes-base.httpRequest", +"position": [ +740, +180 +], +"parameters": { +"url": "=https://api.elevenlabs.io/v1/text-to-speech/{{ $json.body.voice_id }}", +"method": "POST", +"options": {}, +"jsonBody": "={\n \"text\": \"{{ $json.body.text }}\"\n} ", +"sendBody": true, +"sendHeaders": true, +"specifyBody": "json", +"authentication": "genericCredentialType", +"genericAuthType": "httpCustomAuth", +"headerParameters": { +"parameters": [ +{ +"name": "Content-Type", +"value": "application/json" +} +] +} +}, +"credentials": { +"httpCustomAuth": { +"id": "nhkU37chaiBU6X3j", +"name": "Custom Auth account" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "e862955e-76d9-4a24-9501-0d5eb8fbe778", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +280, +-360 +], +"parameters": { +"width": 806.0818150700699, +"height": 495.17470523089514, +"content": "## Generate Text-to-Speech Using Elevenlabs via API\nThis workflow provides an API endpoint to generate speech from text using [Elevenlabs.io](https://elevenlabs.io/), a popular text-to-speech service.\n\n### Step 1: Configure Custom Credentials in n8n\nTo set up your credentials in n8n, create a new custom authentication entry with the following JSON structure:\n```json\n{\n \"headers\": {\n \"xi-api-key\": \"your-elevenlabs-api-key\"\n }\n}\n```\nReplace `\"your-elevenlabs-api-key\"` with your actual Elevenlabs API key.\n\n### Step 2: Send a POST Request to the Webhook\nSend a POST request to the workflow's webhook endpoint with these two parameters:\n- `voice_id`: The ID of the voice from Elevenlabs that you want to use.\n- `text`: The text you want to convert to speech.\n\nThis workflow has been a significant time-saver in my video production tasks. I hope it proves just as useful to you!\n\nHappy automating! \nThe n8Ninja" +}, +"typeVersion": 1 +}, +{ +"id": "275ca523-8b43-4723-9dc4-f5dc1832fcd1", +"name": "Error", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +740, +360 +], +"parameters": { +"options": {}, +"respondWith": "json", +"responseBody": "{\n \"error\": \"Invalid inputs.\"\n}" +}, +"typeVersion": 1.1 +} +], +"pinData": {}, +"connections": { +"Webhook": { +"main": [ +[ +{ +"node": "If params correct", +"type": "main", +"index": 0 +} +] +] +}, +"Generate voice": { +"main": [ +[ +{ +"node": "Respond to Webhook", +"type": "main", +"index": 0 +} +] +] +}, +"If params correct": { +"main": [ +[ +{ +"node": "Generate voice", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Error", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Generate audio from text using OpenAI and Webhook _ Text to Speech Workflow.txt b/Generate audio from text using OpenAI and Webhook _ Text to Speech Workflow.txt new file mode 100644 index 0000000..9736cbb --- /dev/null +++ b/Generate audio from text using OpenAI and Webhook _ Text to Speech Workflow.txt @@ -0,0 +1,125 @@ +{ +"id": "OVSyGmI6YFviPu8Q", +"meta": { +"instanceId": "fb261afc5089eae952e09babdadd9983000b3d863639802f6ded8c5be2e40067", +"templateCredsSetupCompleted": true +}, +"name": "Generate audio from text using OpenAI - text-to-speech Workflow", +"tags": [], +"nodes": [ +{ +"id": "c40966a4-1709-4998-ae95-b067ce3496c9", +"name": "Respond to Webhook", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +1320, +200 +], +"parameters": { +"options": {}, +"respondWith": "binary" +}, +"typeVersion": 1.1 +}, +{ +"id": "c4e57bb6-79a4-4b26-a179-73e30d681521", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +280, +-140 +], +"parameters": { +"width": 501.55, +"height": 493.060000000001, +"content": "This `Webhook` node triggers the workflow when it receives a POST request.\n\n### 1. Test Mode:\n* Use the test webhook URL\n* Click the `Test workflow` button on the canvas. (In test mode, the webhook only works for one call after you click this button)\n\n### 1. Production Mode:\n* The workflow must be active for a **Production URL** to run successfully.\n* You can activate the workflow using the toggle in the top-right of the editor.\n* Note that unlike test URL calls, production URL calls aren't shown on the canvas (only in the executions list)." +}, +"typeVersion": 1 +}, +{ +"id": "1364a4b6-2651-4b38-b335-c36783a25f12", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +825, +60 +], +"parameters": { +"color": 4, +"width": 388.35000000000025, +"height": 292.71000000000043, +"content": "### Configure the OpenAI node with your API key:\nIf you haven't connected your OpenAI credentials in n8n yet, log in to your OpenAI account to get your API Key. Then, open the OpenAI node, click `Create New Credentials` and connect with the **OpenAI API**.\n" +}, +"typeVersion": 1 +}, +{ +"id": "ba755814-75e6-4e16-b3a6-50cf4fc06350", +"name": "Webhook", +"type": "n8n-nodes-base.webhook", +"position": [ +480, +200 +], +"webhookId": "28feeb38-ef2d-4a2e-bd7c-25a524068e25", +"parameters": { +"path": "generate_audio", +"options": {}, +"httpMethod": "POST", +"responseMode": "responseNode" +}, +"typeVersion": 2 +}, +{ +"id": "ac46df50-cb1f-484c-8edf-8131192ba464", +"name": "OpenAI", +"type": "@n8n/n8n-nodes-langchain.openAi", +"position": [ +960, +200 +], +"parameters": { +"input": "={{ $json.body.text_to_convert }}", +"voice": "fable", +"options": {}, +"resource": "audio" +}, +"credentials": { +"openAiApi": { +"id": "2Cije3KX7OIVwn9B", +"name": "n8n OpenAI" +} +}, +"typeVersion": 1.3 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "84f1b893-e1a3-40c3-83b0-7cd637b353c4", +"connections": { +"OpenAI": { +"main": [ +[ +{ +"node": "Respond to Webhook", +"type": "main", +"index": 0 +} +] +] +}, +"Webhook": { +"main": [ +[ +{ +"node": "OpenAI", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Generating Image Embeddings via Textual Summarisation.txt b/Generating Image Embeddings via Textual Summarisation.txt new file mode 100644 index 0000000..6338534 --- /dev/null +++ b/Generating Image Embeddings via Textual Summarisation.txt @@ -0,0 +1,526 @@ +{ +"meta": { +"instanceId": "26ba763460b97c249b82942b23b6384876dfeb9327513332e743c5f6219c2b8e" +}, +"nodes": [ +{ +"id": "141638a4-b340-473f-a800-be7dbdcff131", +"name": "When clicking \"Test workflow\"", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +695, +380 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "6ccdaca5-f620-4afa-bed6-92f3a450687d", +"name": "Google Drive", +"type": "n8n-nodes-base.googleDrive", +"position": [ +875, +380 +], +"parameters": { +"fileId": { +"__rl": true, +"mode": "list", +"value": "0B43u2YYOTJR2cC1BRkptZ3N4QTk4NEtxRko5cjhKUUFyemw0", +"cachedResultUrl": "https://drive.google.com/file/d/0B43u2YYOTJR2cC1BRkptZ3N4QTk4NEtxRko5cjhKUUFyemw0/view?usp=drivesdk&resourcekey=0-UJ8EfTMMBRNVyBb6KhN2Tg", +"cachedResultName": "0B0A0255.jpeg" +}, +"options": {}, +"operation": "download" +}, +"credentials": { +"googleDriveOAuth2Api": { +"id": "yOwz41gMQclOadgu", +"name": "Google Drive account" +} +}, +"typeVersion": 3 +}, +{ +"id": "b0c2f7a4-a336-4705-aeda-411f2518aaef", +"name": "Get Color Information", +"type": "n8n-nodes-base.editImage", +"position": [ +1200, +200 +], +"parameters": { +"operation": "information" +}, +"typeVersion": 1 +}, +{ +"id": "3e42b3f1-6900-4622-8c0d-2d9a27a7e1c9", +"name": "Resize Image", +"type": "n8n-nodes-base.editImage", +"position": [ +1200, +580 +], +"parameters": { +"width": 512, +"height": 512, +"options": {}, +"operation": "resize", +"resizeOption": "onlyIfLarger" +}, +"typeVersion": 1 +}, +{ +"id": "00425bb2-289e-4a09-8fcb-52319281483c", +"name": "Default Data Loader", +"type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader", +"position": [ +2300, +380 +], +"parameters": { +"options": { +"metadata": { +"metadataValues": [ +{ +"name": "source", +"value": "={{ $('Document for Embedding').item.json.metadata.source }}" +}, +{ +"name": "format", +"value": "={{ $('Document for Embedding').item.json.metadata.format }}" +}, +{ +"name": "backgroundColor", +"value": "={{ $('Document for Embedding').item.json.metadata.backgroundColor }}" +} +] +} +} +}, +"typeVersion": 1 +}, +{ +"id": "06dbdf39-9d72-460e-a29c-1ae4e9f3552a", +"name": "Recursive Character Text Splitter", +"type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter", +"position": [ +2300, +500 +], +"parameters": { +"options": {} +}, +"typeVersion": 1 +}, +{ +"id": "139cac42-c006-4c9d-8298-ade845e137a7", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1140, +100 +], +"parameters": { +"color": 7, +"width": 372, +"height": 288, +"content": "### Get Color Channels\n[Source: https://www.pinecone.io/learn/series/image-search/color-histograms/](https://www.pinecone.io/learn/series/image-search/color-histograms/)" +}, +"typeVersion": 1 +}, +{ +"id": "9b8584ae-067c-4515-b194-32986ba3bf8b", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1140, +418 +], +"parameters": { +"color": 7, +"width": 376.4067897296865, +"height": 335.30166772984643, +"content": "### Generate Image Keywords\n[Source: https://www.pinecone.io/learn/series/image-search/bag-of-visual-words/](https://www.pinecone.io/learn/series/image-search/bag-of-visual-words/)\n\nNote, OpenAI Image models work best when image is resized to 512x512." +}, +"typeVersion": 1 +}, +{ +"id": "7f2c27d7-9947-42fa-aafb-78f4f95ac433", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +240, +540 +], +"parameters": { +"color": 3, +"width": 359.1981770749933, +"height": 98.40143173756314, +"content": "⚠️ **Multimodal embedding is not designed analyze medical images for diagnostic features or disease patterns.** Please do not use Multimodal embedding for medical purposes." +}, +"typeVersion": 1 +}, +{ +"id": "cb6b4a82-db5f-41f0-94dc-6cfabe0905eb", +"name": "Combine Image Analysis", +"type": "n8n-nodes-base.merge", +"position": [ +1700, +260 +], +"parameters": { +"mode": "combine", +"options": {}, +"combinationMode": "mergeByPosition" +}, +"typeVersion": 2.1 +}, +{ +"id": "1ba33665-3ebb-4b23-989d-eec53dfd225a", +"name": "Document for Embedding", +"type": "n8n-nodes-base.set", +"position": [ +1860, +257 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "8204b731-24e2-4993-9e6d-4cea80393580", +"name": "data", +"type": "string", +"value": "=## keywords\\n\n{{ $json.content }}\\n\n## color information:\\n\n{{ JSON.stringify($json[\"Channel Statistics\"]) }}" +}, +{ +"id": "ca49cccf-ea4e-4362-bf49-ac836c8758d3", +"name": "metadata", +"type": "object", +"value": "={ \"format\": \"{{ $json.format }}\", \"backgroundColor\": \"{{ $json[\"Background Color\"] }}\", \"source\": \"{{ $binary.data.fileName }}\" } " +} +] +} +}, +"typeVersion": 3.3 +}, +{ +"id": "5d01a2fd-0190-48fc-b588-d5872c5cd793", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +640, +250.0169327052916 +], +"parameters": { +"color": 7, +"width": 418.6907913057789, +"height": 316.7698949693208, +"content": "## 1. Get the Source Image\nIn this demo, we just need an image file. We'll pull an image from google drive but you can use all input trigger or source you prefer." +}, +"typeVersion": 1 +}, +{ +"id": "4c9825f3-6a2b-4fd2-bdb1-e49f8d947e7a", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1098.439755647174, +-145.1609149026466 +], +"parameters": { +"color": 7, +"width": 462.52060804115854, +"height": 938.3723985625845, +"content": "## 2. Image Embedding Methods\n[Read more about working with images in n8n](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.editimage)\n\nThere are a [myriad of image embedding techniques](https://www.pinecone.io/learn/series/image-search/) some which involve specialised models and some which do a simplified image-to-text representation.\nIn this demo, we'll use the simplified text representation methods: collecting color channel information and using Multimodal LLMs to produce keywords for the image. Together, these will form the document we'll embed to represent our image for search." +}, +"typeVersion": 1 +}, +{ +"id": "e4035987-16c0-4d03-9e20-5f2042a6a020", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1600, +120 +], +"parameters": { +"color": 7, +"width": 418.6907913057789, +"height": 343.6004071339855, +"content": "## 3. Generate Embedding Doc\nIt is important to define your metadata for later filtering and retrieval purposes.\n\n" +}, +"typeVersion": 1 +}, +{ +"id": "91fe4c5c-c063-48e2-b248-801c11880c69", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2060, +-11.068945113406585 +], +"parameters": { +"color": 7, +"width": 532.5269726975372, +"height": 665.9365418117011, +"content": "## 3. Store in Vector Store\n[Read more about vector stores](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.vectorstoreinmemory)\n\nOnce our document is ready, we can just insert into any vector store to make it ready for searching. When searching, be sure to defined the same vector store index used here!\nNote: Metadata is defined in the document loader which must be mapped manually.\n\n" +}, +"typeVersion": 1 +}, +{ +"id": "6e8ffa06-ddec-463a-b8d6-581ad7095398", +"name": "Embeddings OpenAI1", +"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi", +"position": [ +2680, +547 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "3dea73b2-6aa1-4158-945e-a5d6bea65244", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2620, +200 +], +"parameters": { +"color": 7, +"width": 400.96585774172854, +"height": 512.739000439197, +"content": "## 4. Try it out!\n[Read more about vector stores](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.vectorstoreinmemory)\n\nHere's a quick test to use a simple text prompt to search for the image. Next step would be to implement image-to-image search by using the \"Embedding Doc\" to search rather to store in the vector database.\n\n" +}, +"typeVersion": 1 +}, +{ +"id": "f6a543d4-df3b-456c-8f85-4dca29029b55", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +240, +140 +], +"parameters": { +"width": 359.6648027457353, +"height": 384.6280362222034, +"content": "## Try It Out!\n### This workflow does the following:\n* Downloads a selected image from Google Drive.\n* Extracts colour channel information from the image.\n* Generates semantic keywords of the iamge using OpenAI vision model.\n* Combines extracted and generated data to create an embedding document for the image.\n* Inserts this document into a vector store to allow for vector search on the original image. \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": "1b1e8568-3779-4ee1-b520-517246d9bf86", +"name": "Get Image Keywords", +"type": "@n8n/n8n-nodes-langchain.openAi", +"position": [ +1360, +580 +], +"parameters": { +"text": "Extract all possible semantic keywords which describe the image. Be comprehensive and be sure to identify subjects (if applicable) such as biological and non-biological objects, lightning, mood, tone, color, special effects, camera and/or techniques used if known. Respond with a comma-separated list.", +"options": { +"detail": "high" +}, +"resource": "image", +"inputType": "base64", +"operation": "analyze" +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1.3 +}, +{ +"id": "724acae9-75d2-4421-b5a3-b920f7bda825", +"name": "In-Memory Vector Store", +"type": "@n8n/n8n-nodes-langchain.vectorStoreInMemory", +"position": [ +2180, +200 +], +"parameters": { +"mode": "insert", +"memoryKey": "image_embeddings" +}, +"typeVersion": 1 +}, +{ +"id": "52afd512-0d55-4ae3-9377-4cb324c571a8", +"name": "Embeddings OpenAI", +"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi", +"position": [ +2180, +420 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "c769f279-22ef-4cb1-aef3-9089bb92a0a4", +"name": "Search for Image", +"type": "@n8n/n8n-nodes-langchain.vectorStoreInMemory", +"position": [ +2680, +387 +], +"parameters": { +"mode": "load", +"prompt": "student having fun", +"memoryKey": "image_embeddings" +}, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"Google Drive": { +"main": [ +[ +{ +"node": "Get Color Information", +"type": "main", +"index": 0 +}, +{ +"node": "Resize Image", +"type": "main", +"index": 0 +} +] +] +}, +"Resize Image": { +"main": [ +[ +{ +"node": "Get Image Keywords", +"type": "main", +"index": 0 +} +] +] +}, +"Embeddings OpenAI": { +"ai_embedding": [ +[ +{ +"node": "In-Memory Vector Store", +"type": "ai_embedding", +"index": 0 +} +] +] +}, +"Embeddings OpenAI1": { +"ai_embedding": [ +[ +{ +"node": "Search for Image", +"type": "ai_embedding", +"index": 0 +} +] +] +}, +"Get Image Keywords": { +"main": [ +[ +{ +"node": "Combine Image Analysis", +"type": "main", +"index": 1 +} +] +] +}, +"Default Data Loader": { +"ai_document": [ +[ +{ +"node": "In-Memory Vector Store", +"type": "ai_document", +"index": 0 +} +] +] +}, +"Get Color Information": { +"main": [ +[ +{ +"node": "Combine Image Analysis", +"type": "main", +"index": 0 +} +] +] +}, +"Combine Image Analysis": { +"main": [ +[ +{ +"node": "Document for Embedding", +"type": "main", +"index": 0 +} +] +] +}, +"Document for Embedding": { +"main": [ +[ +{ +"node": "In-Memory Vector Store", +"type": "main", +"index": 0 +} +] +] +}, +"When clicking \"Test workflow\"": { +"main": [ +[ +{ +"node": "Google Drive", +"type": "main", +"index": 0 +} +] +] +}, +"Recursive Character Text Splitter": { +"ai_textSplitter": [ +[ +{ +"node": "Default Data Loader", +"type": "ai_textSplitter", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Get Airtable data via AI and Obsidian Notes.txt b/Get Airtable data via AI and Obsidian Notes.txt new file mode 100644 index 0000000..a12fe29 --- /dev/null +++ b/Get Airtable data via AI and Obsidian Notes.txt @@ -0,0 +1,202 @@ +{ +"id": "aZSJ2BZQhNduZZ8w", +"meta": { +"instanceId": "d47f3738b860eed937a1b18d7345fa2c65cf4b4957554e29477cb064a7039870", +"templateCredsSetupCompleted": true +}, +"name": "Get Airtable data in Obsidian Notes", +"tags": [ +{ +"id": "zalLN3OHeRqcq4di", +"name": "Obsidian", +"createdAt": "2024-12-01T19:07:59.925Z", +"updatedAt": "2024-12-01T19:07:59.925Z" +} +], +"nodes": [ +{ +"id": "584cfe61-7f1b-4deb-ab4b-45a5ffd20daf", +"name": "Airtable", +"type": "n8n-nodes-base.airtableTool", +"position": [ +540, +340 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appP3ocJy1rXIo6ko", +"cachedResultUrl": "https://airtable.com/appP3ocJy1rXIo6ko", +"cachedResultName": "table" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblywtlpPtGQMTJRm", +"cachedResultUrl": "https://airtable.com/appP3ocJy1rXIo6ko/tblywtlpPtGQMTJRm", +"cachedResultName": "Dummy" +}, +"options": {}, +"operation": "search" +}, +"credentials": { +"airtableTokenApi": { +"id": "yiZ7ZC1md4geZovu", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "8a100c92-7971-464b-b3c0-18272f0a0bef", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +220, +340 +], +"parameters": { +"model": "gpt-4o-mini", +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "q8L9oWVM7QyzYEE5", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "98887b9b-2eae-4a2e-af2b-d40c1786c5a2", +"name": "AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +280, +200 +], +"parameters": { +"text": "={{ $json.body.content }}", +"options": {}, +"promptType": "define" +}, +"typeVersion": 1.6 +}, +{ +"id": "91296976-3d78-4a9e-9f4c-a4136abcca4e", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-160, +-260 +], +"parameters": { +"color": 7, +"width": 497.9113826976365, +"height": 389.9939760040372, +"content": "[![YouTube Video](https://img.youtube.com/vi/2PIdeTgsENo/0.jpg)](https://www.youtube.com/watch?v=2PIdeTgsENo)" +}, +"typeVersion": 1 +}, +{ +"id": "7adae874-d388-4265-aff8-28a1970bd0fb", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +360, +-240 +], +"parameters": { +"width": 563.3824678865192, +"height": 368.0048034646952, +"content": "## Get Airtable Data in Obsidian with AI Agent\n<-- Watch the video to see it in action!\n\n**How to Set Up:**\n- Install the [Post Webhook Plugin](https://github.com/Masterb1234/obsidian-post-webhook/) in Obsidian.\n- Insert the n8n Webhook URL into the Post Webhook plugin settings.\n- Configure Your Airtable Node to match your workflow needs.\n\n\n**How to Use:**\n- Highlight text containing a question about your Airtable data.\n- Open the Obsidian Command Palette (Ctrl+P) and choose 'Send Selection to [Your Webhook]'.\n- Click, wait for the AI Agent to process your request, and see the result appear below your selected text." +}, +"typeVersion": 1 +}, +{ +"id": "52c40581-656d-45b5-b366-d67cf2474312", +"name": "Respond to Obsidian", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +700, +200 +], +"parameters": { +"options": {}, +"respondWith": "text", +"responseBody": "={{ $json.output }}" +}, +"typeVersion": 1.1 +}, +{ +"id": "f2bf502e-5e6f-4e71-8c4f-27ec2dc5ab67", +"name": "Webhook Set Up in Obsidian", +"type": "n8n-nodes-base.webhook", +"position": [ +-40, +200 +], +"webhookId": "59fc8248-d3f7-4dbc-bdf3-39d59e427160", +"parameters": { +"path": "59fc8248-d3f7-4dbc-bdf3-39d59e427160", +"options": {}, +"httpMethod": "POST", +"responseMode": "responseNode" +}, +"typeVersion": 2 +} +], +"active": true, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "dab99881-2d04-4113-9a4e-2f942fdf1c24", +"connections": { +"AI Agent": { +"main": [ +[ +{ +"node": "Respond to Obsidian", +"type": "main", +"index": 0 +} +] +] +}, +"Airtable": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Webhook Set Up in Obsidian": { +"main": [ +[ +{ +"node": "AI Agent", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/🐋DeepSeek V3 Chat & R1 Reasoning Quick Start.txt b/🐋DeepSeek V3 Chat & R1 Reasoning Quick Start.txt new file mode 100644 index 0000000..418fe20 --- /dev/null +++ b/🐋DeepSeek V3 Chat & R1 Reasoning Quick Start.txt @@ -0,0 +1,349 @@ +{ +"id": "IyhH1KHtXidKNSIA", +"meta": { +"instanceId": "31e69f7f4a77bf465b805824e303232f0227212ae922d12133a0f96ffeab4fef" +}, +"name": "🐋DeepSeek V3 Chat & R1 Reasoning Quick Start", +"tags": [], +"nodes": [ +{ +"id": "54c59cae-fbd0-4f0d-b633-6304e6c66d89", +"name": "When chat message received", +"type": "@n8n/n8n-nodes-langchain.chatTrigger", +"position": [ +-840, +-740 +], +"webhookId": "b740bd14-1b9e-4b1b-abd2-1ecf1184d53a", +"parameters": { +"options": {} +}, +"typeVersion": 1.1 +}, +{ +"id": "ef85680e-569f-4e74-a1b4-aae9923a0dcb", +"name": "AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"onError": "continueErrorOutput", +"position": [ +-320, +40 +], +"parameters": { +"agent": "conversationalAgent", +"options": { +"systemMessage": "You are a helpful assistant." +} +}, +"retryOnFail": true, +"typeVersion": 1.7, +"alwaysOutputData": true +}, +{ +"id": "07a8c74c-768e-4b38-854f-251f2fe5b7bf", +"name": "DeepSeek", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +-360, +220 +], +"parameters": { +"model": "=deepseek-reasoner", +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "MSl7SdcvZe0SqCYI", +"name": "deepseek" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "a6d58a8c-2d16-4c91-adde-acac98868150", +"name": "Window Buffer Memory", +"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow", +"position": [ +-220, +220 +], +"parameters": {}, +"typeVersion": 1.3 +}, +{ +"id": "401a5932-9f3e-4b17-a531-3a19a6a7788a", +"name": "Basic LLM Chain2", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +-320, +-800 +], +"parameters": { +"messages": { +"messageValues": [ +{ +"message": "You are a helpful assistant." +} +] +} +}, +"typeVersion": 1.5 +}, +{ +"id": "215dda87-faf7-4206-bbc3-b6a6b1eb98de", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-440, +-460 +], +"parameters": { +"color": 5, +"width": 420, +"height": 340, +"content": "## DeepSeek using HTTP Request\n### DeepSeek Reasoner R1\nhttps://api-docs.deepseek.com/\nRaw Body" +}, +"typeVersion": 1 +}, +{ +"id": "6457c0f7-ad02-4ad3-a4a0-9a7a6e8f0f7f", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-440, +-900 +], +"parameters": { +"color": 4, +"width": 580, +"height": 400, +"content": "## DeepSeek with Ollama Local Model" +}, +"typeVersion": 1 +}, +{ +"id": "2ac8b41f-b27d-4074-abcc-430a8f5928e8", +"name": "Ollama DeepSeek", +"type": "@n8n/n8n-nodes-langchain.lmChatOllama", +"position": [ +-320, +-640 +], +"parameters": { +"model": "deepseek-r1:14b", +"options": { +"format": "default", +"numCtx": 16384, +"temperature": 0.6 +} +}, +"credentials": { +"ollamaApi": { +"id": "7aPaLgwpfdMWFYm9", +"name": "Ollama account 127.0.0.1" +} +}, +"typeVersion": 1 +}, +{ +"id": "37a94fc0-eff3-4226-8633-fb170e5dcff2", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-440, +-80 +], +"parameters": { +"color": 3, +"width": 600, +"height": 460, +"content": "## DeepSeek Conversational Agent w/Memory\n" +}, +"typeVersion": 1 +}, +{ +"id": "52b484bb-1693-4188-ba55-643c40f10dfc", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +20, +-460 +], +"parameters": { +"color": 6, +"width": 420, +"height": 340, +"content": "## DeepSeek using HTTP Request\n### DeepSeek Chat V3\nhttps://api-docs.deepseek.com/\nJSON Body" +}, +"typeVersion": 1 +}, +{ +"id": "ec46acef-60f6-4d34-b636-3654125f5897", +"name": "DeepSeek JSON Body", +"type": "n8n-nodes-base.httpRequest", +"position": [ +160, +-320 +], +"parameters": { +"url": "https://api.deepseek.com/chat/completions", +"method": "POST", +"options": {}, +"jsonBody": "={\n \"model\": \"deepseek-chat\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"{{ $json.chatInput }}\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Hello!\"\n }\n ],\n \"stream\": false\n}", +"sendBody": true, +"specifyBody": "json", +"authentication": "genericCredentialType", +"genericAuthType": "httpHeaderAuth" +}, +"credentials": { +"httpHeaderAuth": { +"id": "9CsntxjSlce6yWbN", +"name": "deepseek" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "e5295120-57f9-4e02-8b73-f00e4d6baa48", +"name": "DeepSeek Raw Body", +"type": "n8n-nodes-base.httpRequest", +"position": [ +-300, +-320 +], +"parameters": { +"url": "https://api.deepseek.com/chat/completions", +"body": "={\n \"model\": \"deepseek-reasoner\",\n \"messages\": [\n {\"role\": \"user\", \"content\": \"{{ $json.chatInput.trim() }}\"}\n ],\n \"stream\": false\n }", +"method": "POST", +"options": {}, +"sendBody": true, +"contentType": "raw", +"authentication": "genericCredentialType", +"rawContentType": "application/json", +"genericAuthType": "httpHeaderAuth" +}, +"credentials": { +"httpHeaderAuth": { +"id": "9CsntxjSlce6yWbN", +"name": "deepseek" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "571dc713-ce54-4330-8bdd-94e057ecd223", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1060, +-460 +], +"parameters": { +"color": 7, +"width": 580, +"height": 840, +"content": "# Your First DeepSeek API Call\n\nThe DeepSeek API uses an API format compatible with OpenAI. By modifying the configuration, you can use the OpenAI SDK or softwares compatible with the OpenAI API to access the DeepSeek API.\n\nhttps://api-docs.deepseek.com/\n\n## Configuration Parameters\n\n| Parameter | Value |\n|-----------|--------|\n| base_url | https://api.deepseek.com |\n| api_key | https://platform.deepseek.com/api_keys |\n\n\n\n## Important Notes\n\n- To be compatible with OpenAI, you can also use `https://api.deepseek.com/v1` as the base_url. Note that the v1 here has NO relationship with the model's version.\n\n- The deepseek-chat model has been upgraded to DeepSeek-V3. The API remains unchanged. You can invoke DeepSeek-V3 by specifying `model='deepseek-chat'`.\n\n- deepseek-reasoner is the latest reasoning model, DeepSeek-R1, released by DeepSeek. You can invoke DeepSeek-R1 by specifying `model='deepseek-reasoner'`." +}, +"typeVersion": 1 +}, +{ +"id": "f0ac3f32-218e-4488-b67f-7b7f7e8be130", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1060, +-900 +], +"parameters": { +"color": 2, +"width": 580, +"height": 400, +"content": "## Four Examples for Connecting to DeepSeek\nhttps://api-docs.deepseek.com/\nhttps://platform.deepseek.com/api_keys" +}, +"typeVersion": 1 +}, +{ +"id": "91642d68-ab5d-4f61-abaf-8cb7cb991c29", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-180, +-640 +], +"parameters": { +"color": 7, +"width": 300, +"height": 120, +"content": "### Ollama Local\nhttps://ollama.com/\nhttps://ollama.com/library/deepseek-r1" +}, +"typeVersion": 1 +} +], +"active": false, +"pinData": { +"When chat message received": [ +{ +"json": { +"action": "sendMessage", +"chatInput": "provide 10 sentences that end in the word apple.", +"sessionId": "68cb82d504c14f5eb80bdf2478bd39bb" +} +} +] +}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "e354040e-7898-4ff9-91a2-b6d36030dac8", +"connections": { +"AI Agent": { +"main": [ +[] +] +}, +"DeepSeek": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Ollama DeepSeek": { +"ai_languageModel": [ +[ +{ +"node": "Basic LLM Chain2", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Window Buffer Memory": { +"ai_memory": [ +[ +{ +"node": "AI Agent", +"type": "ai_memory", +"index": 0 +} +] +] +}, +"When chat message received": { +"main": [ +[ +{ +"node": "Basic LLM Chain2", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/🐋🤖 DeepSeek AI Agent + Telegram + LONG TERM Memory 🧠.txt b/🐋🤖 DeepSeek AI Agent + Telegram + LONG TERM Memory 🧠.txt new file mode 100644 index 0000000..f17886d --- /dev/null +++ b/🐋🤖 DeepSeek AI Agent + Telegram + LONG TERM Memory 🧠.txt @@ -0,0 +1,710 @@ +{ +"id": "rtsvydad1MOCryia", +"meta": { +"instanceId": "31e69f7f4a77bf465b805824e303232f0227212ae922d12133a0f96ffeab4fef" +}, +"name": "🐋🤖 DeepSeek AI Agent + Telegram + LONG TERM Memory 🧠", +"tags": [], +"nodes": [ +{ +"id": "23b50c07-39a8-4166-ab13-9683b3ee25e6", +"name": "Check User & Chat ID", +"type": "n8n-nodes-base.if", +"position": [ +-80, +160 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "5fe3c0d8-bd61-4943-b152-9e6315134520", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $('Listen for Telegram Events').item.json.body.message.from.first_name }}", +"rightValue": "={{ $json.first_name }}" +}, +{ +"id": "98a0ea91-0567-459c-bbce-06abc14a49ce", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $('Listen for Telegram Events').item.json.body.message.from.last_name }}", +"rightValue": "={{ $json.last_name }}" +}, +{ +"id": "18a96c1f-f2a0-4a2a-b789-606763df4423", +"operator": { +"type": "number", +"operation": "equals" +}, +"leftValue": "={{ $('Listen for Telegram Events').item.json.body.message.from.id }}", +"rightValue": "={{ $json.id }}" +} +] +}, +"looseTypeValidation": "=" +}, +"typeVersion": 2.2 +}, +{ +"id": "ecbc13fe-305d-4cdd-b35c-3e119e8e8b5d", +"name": "Error message", +"type": "n8n-nodes-base.telegram", +"position": [ +160, +440 +], +"parameters": { +"text": "=Unable to process your message.", +"chatId": "={{ $json.body.message.chat.id }}", +"additionalFields": { +"appendAttribution": false +} +}, +"credentials": { +"telegramApi": { +"id": "pAIFhguJlkO3c7aQ", +"name": "Telegram account" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "be722bc7-0b22-4892-967c-fdd398a7b129", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-540, +-20 +], +"parameters": { +"color": 6, +"width": 949, +"height": 652, +"content": "# Receive Telegram Message with Webhook" +}, +"typeVersion": 1 +}, +{ +"id": "a3866585-bfee-4025-a8f4-f06fde16171a", +"name": "Listen for Telegram Events", +"type": "n8n-nodes-base.webhook", +"position": [ +-480, +160 +], +"webhookId": "097f36f3-1574-44f9-815f-58387e3b20bf", +"parameters": { +"path": "wbot", +"options": { +"binaryPropertyName": "data" +}, +"httpMethod": "POST" +}, +"typeVersion": 2 +}, +{ +"id": "f70571d5-3680-4616-90fa-3358b0883368", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1380, +-20 +], +"parameters": { +"color": 7, +"width": 800, +"height": 860, +"content": "# How to set up a Telegram Bot WebHook\n\n## WebHook Setup Process\n\n**Basic Concept**\nA WebHook allows your Telegram bot to automatically receive updates instead of manually polling the Bot API.\n\n**Setup Method**\nTo set a WebHook, make a GET request using this URL format:\n```\nhttps://api.telegram.org/bot{my_bot_token}/setWebhook?url={url_to_send_updates_to}\n```\nWhere:\n- `my_bot_token`: Your bot token from BotFather\n- `url_to_send_updates_to`: Your HTTPS endpoint that handles bot updates\n\n\n**Verification**\nTo verify the WebHook setup, use:\n```\nhttps://api.telegram.org/bot{my_bot_token}/getWebhookInfo\n```\n\nA successful response looks like:\n```json\n{\n \"ok\": true,\n \"result\": {\n \"url\": \"https://www.example.com/my-telegram-bot/\",\n \"has_custom_certificate\": false,\n \"pending_update_count\": 0,\n \"max_connections\": 40\n }\n}\n```\n\n\nThis method provides a simple and efficient way to handle Telegram bot updates automatically through webhooks rather than manual polling." +}, +"typeVersion": 1 +}, +{ +"id": "2b6149d5-ffd6-46ef-9840-149508251a77", +"name": "Validation", +"type": "n8n-nodes-base.set", +"position": [ +-260, +160 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "0cea6da1-652a-4c1e-94c3-30608ced90f8", +"name": "first_name", +"type": "string", +"value": "FirstName" +}, +{ +"id": "b90280c6-3e36-49ca-9e7e-e15c42d256cc", +"name": "last_name", +"type": "string", +"value": "LastName" +}, +{ +"id": "f6d86283-16ca-447e-8427-7d3d190babc0", +"name": "id", +"type": "number", +"value": 12345667891 +} +] +}, +"includeOtherFields": true +}, +"typeVersion": 3.4 +}, +{ +"id": "41c965ea-b67d-4d6b-82e4-0e57f5fc13bb", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-320, +100 +], +"parameters": { +"color": 7, +"width": 420, +"height": 260, +"content": "## Validate Telegram User\n" +}, +"typeVersion": 1 +}, +{ +"id": "164f5e91-1958-4dc5-b38c-db1cec0579d4", +"name": "Message Router", +"type": "n8n-nodes-base.switch", +"position": [ +160, +160 +], +"parameters": { +"rules": { +"values": [ +{ +"outputKey": "audio", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"operator": { +"type": "object", +"operation": "exists", +"singleValue": true +}, +"leftValue": "={{ $json.body.message.voice }}", +"rightValue": "" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "text", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "342f0883-d959-44a2-b80d-379e39c76218", +"operator": { +"type": "string", +"operation": "exists", +"singleValue": true +}, +"leftValue": "={{ $json.body.message.text }}", +"rightValue": "" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "image", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "ded3a600-f861-413a-8892-3fc5ea935ecb", +"operator": { +"type": "array", +"operation": "exists", +"singleValue": true +}, +"leftValue": "={{ $json.body.message.photo }}", +"rightValue": "" +} +] +}, +"renameOutput": true +} +] +}, +"options": { +"fallbackOutput": "extra" +} +}, +"typeVersion": 3.2 +}, +{ +"id": "7947173d-39fa-4d4b-9b1e-60de809a9950", +"name": "AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"onError": "continueErrorOutput", +"position": [ +860, +340 +], +"parameters": { +"text": "={{ $('Message Router').item.json.body.message.text }}", +"options": { +"systemMessage": "=## ROLE \nYou are a friendly, attentive, and helpful AI assistant. Your primary goal is to assist the user while maintaining a personalized and engaging interaction. The current user's first name is **{{ $json.body.message.from.first_name }}**.\n\n---\n\n## RULES \n\n1. **Memory Management**: \n - When the user sends a new message, evaluate whether it contains noteworthy or personal information (e.g., preferences, habits, goals, or important events). \n - If such information is identified, use the **Save Memory** tool to store this data in memory. \n - Always send a meaningful response back to the user, even if your primary action was saving information. This response should not reveal that information was stored but should acknowledge or engage with the user’s input naturally.\n\n2. **Context Awareness**: \n - Use stored memories to provide contextually relevant and personalized responses. \n - Always consider the **date and time** when a memory was collected to ensure your responses are up-to-date and accurate.\n\n3. **User-Centric Responses**: \n - Tailor your responses based on the user's preferences and past interactions. \n - Be proactive in recalling relevant details from memory when appropriate but avoid overwhelming the user with unnecessary information.\n\n4. **Privacy and Sensitivity**: \n - Handle all user data with care and sensitivity. Avoid making assumptions or sharing stored information unless it directly enhances the conversation or task at hand.\n\n5. **Fallback Responses**: \n - **IMPORTANT** If no specific task or question arises from the user’s message (e.g., when only saving information), respond in a way that keeps the conversation flowing naturally. For example:\n - Acknowledge their input: “Thanks for sharing that!” \n - Provide a friendly follow-up: “Is there anything else I can help you with today?”\n - DO NOT tell Jokes as a fall back response.\n\n---\n\n## TOOLS \n\n### Save Memory \n- Use this tool to store summarized, concise, and meaningful information about the user. \n- Extract key details from user messages that could enhance future interactions (e.g., likes/dislikes, important dates, hobbies). \n- Ensure that the summary is clear and devoid of unnecessary details.\n\n---\n\n## MEMORIES \n\n### Recent Noteworthy Memories \nHere are the most recent memories collected from the user, including their date and time of collection: \n\n**{{ $('Retrieve Long Term Memories').item.json.content }}**\n\n### Guidelines for Using Memories: \n- Prioritize recent memories but do not disregard older ones if they remain relevant. \n- Cross-reference memories to maintain consistency in your responses. For example, if a user shares conflicting preferences over time, clarify or adapt accordingly.\n\n---\n\n## ADDITIONAL INSTRUCTIONS \n\n- Think critically before responding to ensure your answers are thoughtful and accurate. \n- Strive to build trust with the user by being consistent, reliable, and personable in your interactions. \n- Avoid robotic or overly formal language; aim for a conversational tone that aligns with being \"friendly and helpful.\" \n" +}, +"promptType": "define" +}, +"typeVersion": 1.7, +"alwaysOutputData": true +}, +{ +"id": "6111c771-d8af-4586-8829-213d86dc4f47", +"name": "Merge", +"type": "n8n-nodes-base.merge", +"position": [ +860, +100 +], +"parameters": { +"mode": "combine", +"options": {}, +"combineBy": "combineAll" +}, +"typeVersion": 3 +}, +{ +"id": "94a01b4f-549d-4e49-88e0-143c90dd200e", +"name": "Window Buffer Memory", +"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow", +"position": [ +920, +780 +], +"parameters": { +"sessionKey": "={{ $json.id }}", +"sessionIdType": "customKey", +"contextWindowLength": 50 +}, +"typeVersion": 1.3 +}, +{ +"id": "d1182e11-025e-4885-abb1-b76a9b617b84", +"name": "When chat message received", +"type": "@n8n/n8n-nodes-langchain.chatTrigger", +"disabled": true, +"position": [ +-480, +420 +], +"webhookId": "701ddc24-2637-466e-9789-5d47145333a8", +"parameters": { +"options": {} +}, +"typeVersion": 1.1 +}, +{ +"id": "97d4cdcd-b016-44aa-882c-eb2ec38968eb", +"name": "Sticky Note10", +"type": "n8n-nodes-base.stickyNote", +"position": [ +440, +-20 +], +"parameters": { +"color": 5, +"width": 1033, +"height": 1029, +"content": "# Process Text Message" +}, +"typeVersion": 1 +}, +{ +"id": "73156ecc-af5f-4e3d-82c6-4668db52b511", +"name": "Telegram Response", +"type": "n8n-nodes-base.telegram", +"position": [ +1240, +160 +], +"parameters": { +"text": "={{ $json.output }}", +"chatId": "={{ $('Listen for Telegram Events').item.json.body.message.chat.id }}", +"additionalFields": { +"parse_mode": "HTML", +"appendAttribution": false +} +}, +"credentials": { +"telegramApi": { +"id": "pAIFhguJlkO3c7aQ", +"name": "Telegram account" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "5f342299-40fe-44cf-9b58-8a9d3bfac1df", +"name": "Save Long Term Memories", +"type": "n8n-nodes-base.googleDocsTool", +"position": [ +1260, +780 +], +"parameters": { +"actionsUi": { +"actionFields": [ +{ +"text": "= Memory: {{ $fromAI('memory') }} - Date: {{ $now }} ", +"action": "insert" +} +] +}, +"operation": "update", +"documentURL": "[Google Doc ID]", +"descriptionType": "manual", +"toolDescription": "Save memories" +}, +"credentials": { +"googleDocsOAuth2Api": { +"id": "YWEHuG28zOt532MQ", +"name": "Google Docs account" +} +}, +"typeVersion": 2 +}, +{ +"id": "aba001a8-68f9-4870-9cd0-60a4c59ecd5b", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +460, +220 +], +"parameters": { +"color": 4, +"width": 300, +"height": 340, +"content": "## Retrieve Long Term Memories\nGoogle Docs" +}, +"typeVersion": 1 +}, +{ +"id": "e5ec71ec-9527-4ccd-87c3-3aa2f09192e8", +"name": "Retrieve Long Term Memories", +"type": "n8n-nodes-base.googleDocs", +"position": [ +560, +360 +], +"parameters": { +"operation": "get", +"documentURL": "[Google Doc ID]" +}, +"credentials": { +"googleDocsOAuth2Api": { +"id": "YWEHuG28zOt532MQ", +"name": "Google Docs account" +} +}, +"typeVersion": 2, +"alwaysOutputData": true +}, +{ +"id": "4764383a-3c4b-4e64-b391-5dc9fb4b9de6", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +820, +660 +], +"parameters": { +"width": 280, +"height": 320, +"content": "## Save To Current Chat Memory (Optional)" +}, +"typeVersion": 1 +}, +{ +"id": "e11995b8-e061-4b40-b4b6-9ec03c7e5a06", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1160, +660 +], +"parameters": { +"color": 4, +"width": 280, +"height": 320, +"content": "## Save Long Term Memories\nGoogle Docs" +}, +"typeVersion": 1 +}, +{ +"id": "1b53aef2-ca99-409b-bd10-3fc1fd87f540", +"name": "Response Error message", +"type": "n8n-nodes-base.telegram", +"position": [ +1240, +360 +], +"parameters": { +"text": "=Unable to process your message.", +"chatId": "={{ $('Listen for Telegram Events').item.json.body.message.chat.id }}", +"additionalFields": { +"appendAttribution": false +} +}, +"credentials": { +"telegramApi": { +"id": "pAIFhguJlkO3c7aQ", +"name": "Telegram account" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "e5d79084-d7f1-44fd-a1db-73cc76a148ec", +"name": "Sticky Note12", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-60, +660 +], +"parameters": { +"color": 7, +"width": 820, +"height": 600, +"content": "# DeepSeek API Call\n\nThe DeepSeek API uses an API format compatible with OpenAI. By modifying the configuration, you can use the OpenAI SDK or softwares compatible with the OpenAI API to access the DeepSeek API.\n\nhttps://api-docs.deepseek.com/\n\n## Configuration Parameters\n\n| Parameter | Value |\n|-----------|--------|\n| base_url | https://api.deepseek.com |\n| api_key | https://platform.deepseek.com/api_keys |\n\n\n\n## Important Notes\n\n- To be compatible with OpenAI, you can also use `https://api.deepseek.com/v1` as the base_url. Note that the v1 here has NO relationship with the model's version.\n\n- The deepseek-chat model has been upgraded to DeepSeek-V3. The API remains unchanged. You can invoke DeepSeek-V3 by specifying `model='deepseek-chat'`.\n\n- deepseek-reasoner is the latest reasoning model, DeepSeek-R1, released by DeepSeek. You can invoke DeepSeek-R1 by specifying `model='deepseek-reasoner'`." +}, +"typeVersion": 1 +}, +{ +"id": "af14e803-44a5-4b0e-a675-b1e860bf6d29", +"name": "DeepSeek-R1 Reasoning", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +440, +880 +], +"parameters": { +"model": "=deepseek-reasoner", +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "MSl7SdcvZe0SqCYI", +"name": "deepseek" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "e8be6a32-ba4c-4895-b34b-c5e7d0ded5e8", +"name": "DeepSeek-V3 Chat", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +600, +880 +], +"parameters": { +"model": "=deepseek-chat", +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "MSl7SdcvZe0SqCYI", +"name": "deepseek" +} +}, +"typeVersion": 1.1 +} +], +"active": false, +"pinData": {}, +"settings": { +"timezone": "America/Vancouver", +"callerPolicy": "workflowsFromSameOwner", +"executionOrder": "v1" +}, +"versionId": "2e669c98-e6ad-42f0-a642-de05e372937e", +"connections": { +"Merge": { +"main": [ +[ +{ +"node": "AI Agent", +"type": "main", +"index": 0 +} +] +] +}, +"AI Agent": { +"main": [ +[ +{ +"node": "Telegram Response", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Response Error message", +"type": "main", +"index": 0 +} +] +] +}, +"Validation": { +"main": [ +[ +{ +"node": "Check User & Chat ID", +"type": "main", +"index": 0 +} +] +] +}, +"Message Router": { +"main": [ +[], +[ +{ +"node": "Merge", +"type": "main", +"index": 0 +}, +{ +"node": "Retrieve Long Term Memories", +"type": "main", +"index": 0 +} +], +[], +[ +{ +"node": "Error message", +"type": "main", +"index": 0 +} +] +] +}, +"DeepSeek-V3 Chat": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Check User & Chat ID": { +"main": [ +[ +{ +"node": "Message Router", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Error message", +"type": "main", +"index": 0 +} +] +] +}, +"Window Buffer Memory": { +"ai_memory": [ +[] +] +}, +"Save Long Term Memories": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Listen for Telegram Events": { +"main": [ +[ +{ +"node": "Validation", +"type": "main", +"index": 0 +} +] +] +}, +"When chat message received": { +"main": [ +[] +] +}, +"Retrieve Long Term Memories": { +"main": [ +[ +{ +"node": "Merge", +"type": "main", +"index": 1 +} +] +] +} +} +} \ No newline at end of file