From 9f037c87c90a4ee4afce72d1b348b799558d62cb Mon Sep 17 00:00:00 2001 From: enescingoz Date: Thu, 8 May 2025 19:36:42 +0100 Subject: [PATCH] n8n automations part 1 --- ...To Chat With Files In Supabase Storage.txt | 915 ++++ ...Google calendar assistant using OpenAI.txt | 319 ++ ...d meetings with Airtable and Fireflies.txt | 549 +++ ...gent for realtime insights on meetings.txt | 580 +++ ...to chat with Airtable and analyze data.txt | 1397 ++++++ ...nt to chat with Supabase_PostgreSQL DB.txt | 261 ++ ...onsole Data, using OpenAI and Postgres.txt | 827 ++++ ...th Ollama for current weather and wiki.txt | 235 + ...r CV Analysis and Candidate Evaluation.txt | 670 +++ ...damental Stock Analysis - Q&A Workflow.txt | 439 ++ AI Customer feedback sentiment analysis.txt | 330 ++ ...tion with Dynamic Prompts and Airtable.txt | 1623 +++++++ ...ction with Dynamic Prompts and Baserow.txt | 1300 ++++++ ...sis and Personalized Training Insights.txt | 354 ++ ...oogle Sheets and OpenAI _ the EASY way.txt | 257 ++ ...social media post captions in Airtable.txt | 1119 +++++ ...er, OpenAI, Google Gemini & ElevenLabs.txt | 423 ++ ...I for Customer Service and Restaurants.txt | 638 +++ AI Youtube Trend Finder Based On Niche.txt | 488 +++ AI agent chat.txt | 131 + ..._inbox. Manychat + Open AI integration.txt | 272 ++ AI agent that can scrape webpages.txt | 556 +++ ...a source (using the n8n workflow tool).txt | 277 ++ AI chatbot that can search the web.txt | 195 + AI web researcher for sales.txt | 747 ++++ ... Inquiry Automation with ERPNext & n8n.txt | 733 ++++ ...ated Summary Block for WordPress Posts.txt | 1034 +++++ ...te Shortlisting Automation for ERPNext.txt | 1078 +++++ ...dren_s Arabic Storytelling on Telegram.txt | 431 ++ ...h Storytelling on Telegram with OpenAI.txt | 401 ++ ...Business_ Summarize & Respond with RAG.txt | 851 ++++ ...enAI, Google Sheets, Jina AI and Slack.txt | 1024 +++++ ...low For Stock Earnings Report Analysis.txt | 521 +++ AI-Powered Social Media Amplifier.txt | 1115 +++++ AI-powered WooCommerce Support-Agent.txt | 1087 +++++ ...sponder and response approval (Yes_No).txt | 504 +++ ...rce (using the n8n workflow retriever).txt | 174 + ...st episode and enhance using Wikipedia.txt | 463 ++ ALL_unique_nodes.txt | 0 API Schema Extractor.txt | 3777 +++++++++++++++++ ...ng Next Steps using Transcripts and AI.txt | 762 ++++ ...feedback messages to a table in Notion.txt | 179 + ...Presented at AI Developers #14 meetup).txt | 927 ++++ ...ith with LangChain nodes and new tools.txt | 260 ++ ... Face with AI and store them in Notion.txt | 470 ++ ...Suspicious Email Contents with ChatGPT.txt | 828 ++++ ...ous Email Contents with ChatGPT Vision.txt | 600 +++ ...dback and send a message on Mattermost.txt | 128 + ...nd and send it to a Mattermost channel.txt | 126 + ... with Chrome extension, N8N and OpenAI.txt | 131 + ...Assistant with Telegram Voice and Text.txt | 476 +++ ...lp when the AI doesn_t know the answer.txt | 368 ++ Ask questions about a PDF using AI.txt | 408 ++ ... Publish Blog Posts From Google Sheets.txt | 1622 +++++++ Auto Categorise Outlook Emails with AI.txt | 1271 ++++++ ...ize blog posts in wordpress using A.I..txt | 214 + ... YouTube Video Summarization & Analysis.txt | 326 ++ ...reators Leaderboard - Find Popular Workflows.txt | 1179 +++++ ...t for Top n8n Creators Leaderboard Reporting.txt | 1301 ++++++ ...LONG TERM Memory + Note Storage + Telegram.txt | 538 +++ 60 files changed, 40209 insertions(+) create mode 100644 AI Agent To Chat With Files In Supabase Storage.txt create mode 100644 AI Agent _ Google calendar assistant using OpenAI.txt create mode 100644 AI Agent for project management and meetings with Airtable and Fireflies.txt create mode 100644 AI Agent for realtime insights on meetings.txt create mode 100644 AI Agent to chat with Airtable and analyze data.txt create mode 100644 AI Agent to chat with Supabase_PostgreSQL DB.txt create mode 100644 AI Agent to chat with you Search Console Data, using OpenAI and Postgres.txt create mode 100644 AI Agent with Ollama for current weather and wiki.txt create mode 100644 AI Automated HR Workflow for CV Analysis and Candidate Evaluation.txt create mode 100644 AI Crew to Automate Fundamental Stock Analysis - Q&A Workflow.txt create mode 100644 AI Customer feedback sentiment analysis.txt create mode 100644 AI Data Extraction with Dynamic Prompts and Airtable.txt create mode 100644 AI Data Extraction with Dynamic Prompts and Baserow.txt create mode 100644 AI Fitness Coach Strava Data Analysis and Personalized Training Insights.txt create mode 100644 AI Powered Web Scraping with Jina, Google Sheets and OpenAI _ the EASY way.txt create mode 100644 AI Social Media Caption Creator creates social media post captions in Airtable.txt create mode 100644 AI Voice Chat using Webhook, Memory Manager, OpenAI, Google Gemini & ElevenLabs.txt create mode 100644 AI Voice Chatbot with ElevenLabs & OpenAI for Customer Service and Restaurants.txt create mode 100644 AI Youtube Trend Finder Based On Niche.txt create mode 100644 AI agent chat.txt create mode 100644 AI agent for Instagram DM_inbox. Manychat + Open AI integration.txt create mode 100644 AI agent that can scrape webpages.txt create mode 100644 AI chat with any data source (using the n8n workflow tool).txt create mode 100644 AI chatbot that can search the web.txt create mode 100644 AI web researcher for sales.txt create mode 100644 AI-Driven Lead Management and Inquiry Automation with ERPNext & n8n.txt create mode 100644 AI-Generated Summary Block for WordPress Posts.txt create mode 100644 AI-Powered Candidate Shortlisting Automation for ERPNext.txt create mode 100644 AI-Powered Children_s Arabic Storytelling on Telegram.txt create mode 100644 AI-Powered Children_s English Storytelling on Telegram with OpenAI.txt create mode 100644 AI-Powered Email Automation for Business_ Summarize & Respond with RAG.txt create mode 100644 AI-Powered Information Monitoring with OpenAI, Google Sheets, Jina AI and Slack.txt create mode 100644 AI-Powered RAG Workflow For Stock Earnings Report Analysis.txt create mode 100644 AI-Powered Social Media Amplifier.txt create mode 100644 AI-powered WooCommerce Support-Agent.txt create mode 100644 AI-powered email processing autoresponder and response approval (Yes_No).txt create mode 100644 AI_ Ask questions about any data source (using the n8n workflow retriever).txt create mode 100644 AI_ Summarize podcast episode and enhance using Wikipedia.txt create mode 100644 ALL_unique_nodes.txt create mode 100644 API Schema Extractor.txt create mode 100644 Actioning Your Meeting Next Steps using Transcripts and AI.txt create mode 100644 Add positive feedback messages to a table in Notion.txt create mode 100644 Advanced AI Demo (Presented at AI Developers #14 meetup).txt create mode 100644 Agentic Telegram AI bot with with LangChain nodes and new tools.txt create mode 100644 Analyse papers from Hugging Face with AI and store them in Notion.txt create mode 100644 Analyze & Sort Suspicious Email Contents with ChatGPT.txt create mode 100644 Analyze Suspicious Email Contents with ChatGPT Vision.txt create mode 100644 Analyze feedback and send a message on Mattermost.txt create mode 100644 Analyze feedback using AWS Comprehend and send it to a Mattermost channel.txt create mode 100644 Analyze tradingview.com charts with Chrome extension, N8N and OpenAI.txt create mode 100644 Angie, Personal AI Assistant with Telegram Voice and Text.txt create mode 100644 Ask a human for help when the AI doesn_t know the answer.txt create mode 100644 Ask questions about a PDF using AI.txt create mode 100644 Author and Publish Blog Posts From Google Sheets.txt create mode 100644 Auto Categorise Outlook Emails with AI.txt create mode 100644 Auto-Categorize blog posts in wordpress using A.I..txt create mode 100644 ⚡AI-Powered YouTube Video Summarization & Analysis.txt create mode 100644 🔥📈🤖 AI Agent for n8n Creators Leaderboard - Find Popular Workflows.txt create mode 100644 🤖🧑_💻 AI Agent for Top n8n Creators Leaderboard Reporting.txt create mode 100644 🤖🧠 AI Agent Chatbot + LONG TERM Memory + Note Storage + Telegram.txt diff --git a/AI Agent To Chat With Files In Supabase Storage.txt b/AI Agent To Chat With Files In Supabase Storage.txt new file mode 100644 index 0000000..f42b9ea --- /dev/null +++ b/AI Agent To Chat With Files In Supabase Storage.txt @@ -0,0 +1,915 @@ +{ +"meta": { +"instanceId": "6a2a7715680b8313f7cb4676321c5baa46680adfb913072f089f2766f42e43bd" +}, +"nodes": [ +{ +"id": "f577f6bd-b1a4-48ec-9329-7bccc3fc1463", +"name": "Get All files", +"type": "n8n-nodes-base.httpRequest", +"position": [ +400, +-100 +], +"parameters": { +"url": "=https://yqtvdcvjboenlblgcivl.supabase.co/storage/v1/object/list/private", +"method": "POST", +"options": {}, +"jsonBody": "={\n \"prefix\": \"\",\n \"limit\": 100,\n \"offset\": 0,\n \"sortBy\": {\n \"column\": \"name\",\n \"order\": \"asc\"\n }\n}", +"sendBody": true, +"specifyBody": "json", +"authentication": "predefinedCredentialType", +"nodeCredentialType": "supabaseApi" +}, +"credentials": { +"supabaseApi": { +"id": "t8AQJzvZvrOMDLec", +"name": "Supabase account My Airtable Gen" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "10693bc8-560d-4cf6-8bd0-2fe3f4d863d1", +"name": "Default Data Loader", +"type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader", +"position": [ +1780, +100 +], +"parameters": { +"options": { +"metadata": { +"metadataValues": [ +{ +"name": "=file_id", +"value": "={{ $json.id }}" +} +] +} +}, +"jsonData": "={{ $('Merge').item.json.data ?? $('Merge').item.json.text }}", +"jsonMode": "expressionData" +}, +"typeVersion": 1 +}, +{ +"id": "49428060-e707-4269-8344-77b301f56f7c", +"name": "Recursive Character Text Splitter", +"type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter", +"position": [ +1780, +280 +], +"parameters": { +"options": {}, +"chunkSize": 500, +"chunkOverlap": 200 +}, +"typeVersion": 1 +}, +{ +"id": "08742063-e235-4874-a128-b352786b19ce", +"name": "Extract Document PDF", +"type": "n8n-nodes-base.extractFromFile", +"position": [ +1240, +0 +], +"parameters": { +"options": {}, +"operation": "pdf" +}, +"typeVersion": 1, +"alwaysOutputData": false +}, +{ +"id": "21f19360-d7ce-4106-ae5a-aa0f15b7c4aa", +"name": "Embeddings OpenAI", +"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi", +"position": [ +1600, +80 +], +"parameters": { +"model": "text-embedding-3-small", +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "fLfRtaXbR0EVD0pl", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "4147409f-8686-418f-b979-04f8c8e7fe42", +"name": "Create File record2", +"type": "n8n-nodes-base.supabase", +"position": [ +1540, +-100 +], +"parameters": { +"tableId": "files", +"fieldsUi": { +"fieldValues": [ +{ +"fieldId": "name", +"fieldValue": "={{ $('Loop Over Items').item.json.name }}" +}, +{ +"fieldId": "storage_id", +"fieldValue": "={{ $('Loop Over Items').item.json.id }}" +} +] +} +}, +"credentials": { +"supabaseApi": { +"id": "t8AQJzvZvrOMDLec", +"name": "Supabase account My Airtable Gen" +} +}, +"typeVersion": 1 +}, +{ +"id": "016f1afe-172b-4609-b451-8d67609214d3", +"name": "If", +"type": "n8n-nodes-base.if", +"position": [ +720, +-100 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "9b14e306-a04d-40f7-bc5b-b8eda8d8f7f2", +"operator": { +"type": "boolean", +"operation": "true", +"singleValue": true +}, +"leftValue": "={{ \n !$('Aggregate').item.json.data || \n !Array.isArray($('Aggregate').item.json.data) || \n !$('Aggregate').item.json.data.some(item => \n item.storage_id === $('Loop Over Items').item.json.id \n ) \n}}", +"rightValue": "" +}, +{ +"id": "c3c0af88-9aea-4539-8948-1b69e601c27c", +"operator": { +"type": "string", +"operation": "notEquals" +}, +"leftValue": "={{ $json.name }}", +"rightValue": ".emptyFolderPlaceholder" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "75e8a7db-8c4a-4ad8-b902-062cbc93e1eb", +"name": "Get All Files", +"type": "n8n-nodes-base.supabase", +"position": [ +20, +-100 +], +"parameters": { +"tableId": "files", +"operation": "getAll" +}, +"credentials": { +"supabaseApi": { +"id": "t8AQJzvZvrOMDLec", +"name": "Supabase account My Airtable Gen" +} +}, +"typeVersion": 1, +"alwaysOutputData": true +}, +{ +"id": "b22a3bab-f615-4d8a-8832-ce25b1a385fe", +"name": "Download", +"type": "n8n-nodes-base.httpRequest", +"position": [ +900, +-100 +], +"parameters": { +"url": "=https://yqtvdcvjboenlblgcivl.supabase.co/storage/v1/object/private/{{ $json.name }}", +"options": {}, +"authentication": "predefinedCredentialType", +"nodeCredentialType": "supabaseApi" +}, +"credentials": { +"supabaseApi": { +"id": "t8AQJzvZvrOMDLec", +"name": "Supabase account My Airtable Gen" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "50d1fede-4bd0-4cd4-b74a-7d689fe211cc", +"name": "Loop Over Items", +"type": "n8n-nodes-base.splitInBatches", +"position": [ +560, +-100 +], +"parameters": { +"options": {}, +"batchSize": "=1" +}, +"typeVersion": 3 +}, +{ +"id": "f9c23b5e-0b40-4886-b54f-59fb46132d3f", +"name": "When clicking ‘Test workflow’", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +-160, +-100 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "0a0ec290-2c3d-40ba-8d03-6abf75202e73", +"name": "Aggregate", +"type": "n8n-nodes-base.aggregate", +"position": [ +220, +-100 +], +"parameters": { +"options": {}, +"aggregate": "aggregateAllItemData" +}, +"typeVersion": 1, +"alwaysOutputData": true +}, +{ +"id": "32b3e2e1-2d25-4dd1-93e8-3f693beb7b6f", +"name": "When chat message received", +"type": "@n8n/n8n-nodes-langchain.chatTrigger", +"position": [ +800, +-1020 +], +"webhookId": "3c40d311-7996-4ed4-b2fa-c73bea5f4cf5", +"parameters": { +"options": {} +}, +"typeVersion": 1.1 +}, +{ +"id": "79073b5c-a4ad-45a6-bbfa-e900a05bfde3", +"name": "OpenAI Chat Model1", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +940, +-820 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "zJhr5piyEwVnWtaI", +"name": "OpenAi club" +} +}, +"typeVersion": 1 +}, +{ +"id": "f8663483-76d5-4fc8-ad07-7eec815ff7a6", +"name": "Embeddings OpenAI2", +"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi", +"position": [ +1020, +-540 +], +"parameters": { +"model": "text-embedding-3-small", +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "SphXAX7rlwRLkiox", +"name": "Test club key" +} +}, +"typeVersion": 1 +}, +{ +"id": "a1458799-d379-46de-93e6-a5ba0c665163", +"name": "OpenAI Chat Model2", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +1300, +-680 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "SphXAX7rlwRLkiox", +"name": "Test club key" +} +}, +"typeVersion": 1 +}, +{ +"id": "d6eeda2f-c984-406d-a625-726840308413", +"name": "Vector Store Tool1", +"type": "@n8n/n8n-nodes-langchain.toolVectorStore", +"position": [ +1100, +-820 +], +"parameters": { +"name": "knowledge_base", +"topK": 8, +"description": "Retrieve data about user request" +}, +"typeVersion": 1 +}, +{ +"id": "e1d9a348-7d44-4ad1-adbd-2c9a31e06876", +"name": "Switch", +"type": "n8n-nodes-base.switch", +"position": [ +1060, +-100 +], +"parameters": { +"rules": { +"values": [ +{ +"outputKey": "txt", +"conditions": { +"options": { +"version": 1, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"operator": { +"type": "boolean", +"operation": "true", +"singleValue": true +}, +"leftValue": "={{$binary.data?.fileExtension == undefined }}", +"rightValue": "txt" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "pdf", +"conditions": { +"options": { +"version": 1, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "bf04cbec-dd86-4607-988f-4c96b6fd4b58", +"operator": { +"type": "string", +"operation": "equals" +}, +"leftValue": "={{$binary.data.fileExtension }}", +"rightValue": "pdf" +} +] +}, +"renameOutput": true +} +] +}, +"options": {} +}, +"typeVersion": 3.1 +}, +{ +"id": "d38afb92-87ae-4e2a-a712-ec24b1efd105", +"name": "Insert into Supabase Vectorstore", +"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase", +"position": [ +1700, +-100 +], +"parameters": { +"mode": "insert", +"options": { +"queryName": "match_documents" +}, +"tableName": { +"__rl": true, +"mode": "list", +"value": "documents", +"cachedResultName": "documents" +} +}, +"credentials": { +"supabaseApi": { +"id": "t8AQJzvZvrOMDLec", +"name": "Supabase account My Airtable Gen" +} +}, +"typeVersion": 1 +}, +{ +"id": "1a903b2e-cab0-4798-b820-ec08d6a71ddd", +"name": "Merge", +"type": "n8n-nodes-base.merge", +"position": [ +1380, +-100 +], +"parameters": {}, +"typeVersion": 3 +}, +{ +"id": "3afd552e-4995-493e-9cd5-ef496dfe359f", +"name": "AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +1020, +-1020 +], +"parameters": { +"options": {} +}, +"typeVersion": 1.7 +}, +{ +"id": "d9688acc-311b-42fd-afa8-2c0e493be34b", +"name": "Supabase Vector Store", +"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase", +"position": [ +1020, +-660 +], +"parameters": { +"options": { +"metadata": { +"metadataValues": [ +{ +"name": "file_id", +"value": "300b0128-0955-4058-b0d3-a9aefe728432" +} +] +} +}, +"tableName": { +"__rl": true, +"mode": "list", +"value": "documents", +"cachedResultName": "documents" +} +}, +"credentials": { +"supabaseApi": { +"id": "t8AQJzvZvrOMDLec", +"name": "Supabase account My Airtable Gen" +} +}, +"typeVersion": 1 +}, +{ +"id": "66df007c-0418-4551-950e-32e7d79840bd", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +340, +-220 +], +"parameters": { +"height": 89.3775420487804, +"content": "### Replace Storage name, database ID and credentials." +}, +"typeVersion": 1 +}, +{ +"id": "b164b520-20dd-44a4-aa3b-647391786b20", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-20, +-220 +], +"parameters": { +"height": 80, +"content": "### Replace credentials." +}, +"typeVersion": 1 +}, +{ +"id": "8688c219-5af4-4e54-9fd1-91851829445b", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1540, +-220 +], +"parameters": { +"height": 80, +"content": "### Replace credentials." +}, +"typeVersion": 1 +}, +{ +"id": "45c6ece4-f849-4496-8149-31385f5e36a4", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +840, +-220 +], +"parameters": { +"height": 89.3775420487804, +"content": "### Replace Storage name, database ID and credentials." +}, +"typeVersion": 1 +}, +{ +"id": "2ca07cb0-b5f4-4761-b954-faf2131872d9", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1500, +220 +], +"parameters": { +"height": 80, +"content": "### Replace credentials." +}, +"typeVersion": 1 +}, +{ +"id": "8d682dae-6f88-42f0-a717-affffd37d882", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1140, +-520 +], +"parameters": { +"height": 80, +"content": "### Replace credentials." +}, +"typeVersion": 1 +}, +{ +"id": "796b5dca-d60e-43a9-afe8-194244643557", +"name": "Sticky Note9", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-520, +-940 +], +"parameters": { +"color": 7, +"width": 330.5152611046425, +"height": 239.5888196628349, +"content": "### ... or watch set up video [10 min]\n[![Youtube Thumbnail](https://res.cloudinary.com/de9jgixzm/image/upload/v1739773273/Youtube%20Thumbs/Chat%20With%20FIles.png)](https://www.youtube.com/watch?v=glWUkdZe_3w)\n" +}, +"typeVersion": 1 +}, +{ +"id": "eba121de-a3f7-4ba5-8396-f7d64e648322", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-820, +-1460 +], +"parameters": { +"color": 7, +"width": 636.2128494576581, +"height": 497.1532689930921, +"content": "![5min Logo](https://res.cloudinary.com/de9jgixzm/image/upload/v1739773200/Skool%20Assets/ejm3hqnvhgwpnu2fv92s.png)\n## AI Agent To Chat With Files In Supabase Storage\n**Made by [Mark Shcherbakov](https://www.linkedin.com/in/marklowcoding/) from community [5minAI](https://www.skool.com/5minai-2861)**\n\nManually retrieving and analyzing specific information from large document repositories is time-consuming and inefficient. This workflow automates the process by vectorizing documents and enabling AI-powered interactions, making it easy to query and retrieve context-based information from uploaded files.\n\nThe workflow integrates Supabase with an AI-powered chatbot to process, store, and query text and PDF files. The steps include:\n- Fetching and comparing files to avoid duplicate processing.\n- Handling file downloads and extracting content based on the file type.\n- Converting documents into vectorized data for contextual information retrieval.\n- Storing and querying vectorized data from a Supabase vector store.\n\n" +}, +"typeVersion": 1 +}, +{ +"id": "df054036-d6b9-4f53-86cb-85ad96f07d0e", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-820, +-940 +], +"parameters": { +"color": 7, +"width": 280.2462120317618, +"height": 545.9087885077763, +"content": "### Set up steps\n\n1. **Fetch File List from Supabase**:\n - Use Supabase to retrieve the stored file list from a specified bucket.\n - Add logic to manage empty folder placeholders returned by Supabase, avoiding incorrect processing.\n\n2. **Compare and Filter Files**:\n - Aggregate the files retrieved from storage and compare them to the existing list in the Supabase `files` table.\n - Exclude duplicates and skip placeholder files to ensure only unprocessed files are handled.\n\n3. **Handle File Downloads**:\n - Download new files using detailed storage configurations for public/private access.\n - Adjust the storage settings and GET requests to match your Supabase setup.\n\n4. **File Type Processing**:\n - Use a Switch node to target specific file types (e.g., PDFs or text files).\n - Employ relevant tools to process the content:\n - For PDFs, extract embedded content.\n - For text files, directly process the text data.\n\n5. **Content Chunking**:\n - Break large text data into smaller chunks using the Text Splitter node.\n - Define chunk size (default: 500 tokens) and overlap to retain necessary context across chunks.\n\n6. **Vector Embedding Creation**:\n - Generate vectorized embeddings for the processed content using OpenAI's embedding tools.\n - Ensure metadata, such as file ID, is included for easy data retrieval.\n\n7. **Store Vectorized Data**:\n - Save the vectorized information into a dedicated Supabase vector store.\n - Use the default schema and table provided by Supabase for seamless setup.\n\n8. **AI Chatbot Integration**:\n - Add a chatbot node to handle user input and retrieve relevant document chunks.\n - Use metadata like file ID for targeted queries, especially when multiple documents are involved." +}, +"typeVersion": 1 +}, +{ +"id": "450a1e49-4be9-451a-9d05-2860e29c3695", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +540, +-1160 +], +"parameters": { +"color": 5, +"width": 951.7421645394404, +"height": 809.7437181509877, +"content": "## Scenario 2 - AI agent" +}, +"typeVersion": 1 +}, +{ +"id": "c3814c5d-8881-4598-897e-268019bee1bc", +"name": "Sticky Note10", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-260, +-280 +], +"parameters": { +"color": 5, +"width": 2304.723519246249, +"height": 739.2522526116408, +"content": "## Scenario 1 - Flow for adding new files from Supabase storage" +}, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"If": { +"main": [ +[ +{ +"node": "Download", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Loop Over Items", +"type": "main", +"index": 0 +} +] +] +}, +"Merge": { +"main": [ +[ +{ +"node": "Create File record2", +"type": "main", +"index": 0 +} +] +] +}, +"Switch": { +"main": [ +[ +{ +"node": "Merge", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Extract Document PDF", +"type": "main", +"index": 0 +} +] +] +}, +"Download": { +"main": [ +[ +{ +"node": "Switch", +"type": "main", +"index": 0 +} +] +] +}, +"Aggregate": { +"main": [ +[ +{ +"node": "Get All files", +"type": "main", +"index": 0 +} +] +] +}, +"Get All Files": { +"main": [ +[ +{ +"node": "Aggregate", +"type": "main", +"index": 0 +} +] +] +}, +"Get All files": { +"main": [ +[ +{ +"node": "Loop Over Items", +"type": "main", +"index": 0 +} +] +] +}, +"Loop Over Items": { +"main": [ +null, +[ +{ +"node": "If", +"type": "main", +"index": 0 +} +] +] +}, +"Embeddings OpenAI": { +"ai_embedding": [ +[ +{ +"node": "Insert into Supabase Vectorstore", +"type": "ai_embedding", +"index": 0 +} +] +] +}, +"Embeddings OpenAI2": { +"ai_embedding": [ +[ +{ +"node": "Supabase Vector Store", +"type": "ai_embedding", +"index": 0 +} +] +] +}, +"OpenAI Chat Model1": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"OpenAI Chat Model2": { +"ai_languageModel": [ +[ +{ +"node": "Vector Store Tool1", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Vector Store Tool1": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Create File record2": { +"main": [ +[ +{ +"node": "Insert into Supabase Vectorstore", +"type": "main", +"index": 0 +} +] +] +}, +"Default Data Loader": { +"ai_document": [ +[ +{ +"node": "Insert into Supabase Vectorstore", +"type": "ai_document", +"index": 0 +} +] +] +}, +"Extract Document PDF": { +"main": [ +[ +{ +"node": "Merge", +"type": "main", +"index": 1 +} +] +] +}, +"Supabase Vector Store": { +"ai_vectorStore": [ +[ +{ +"node": "Vector Store Tool1", +"type": "ai_vectorStore", +"index": 0 +} +] +] +}, +"When chat message received": { +"main": [ +[ +{ +"node": "AI Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Insert into Supabase Vectorstore": { +"main": [ +[ +{ +"node": "Loop Over Items", +"type": "main", +"index": 0 +} +] +] +}, +"Recursive Character Text Splitter": { +"ai_textSplitter": [ +[ +{ +"node": "Default Data Loader", +"type": "ai_textSplitter", +"index": 0 +} +] +] +}, +"When clicking ‘Test workflow’": { +"main": [ +[ +{ +"node": "Get All Files", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/AI Agent _ Google calendar assistant using OpenAI.txt b/AI Agent _ Google calendar assistant using OpenAI.txt new file mode 100644 index 0000000..a00ab7b --- /dev/null +++ b/AI Agent _ Google calendar assistant using OpenAI.txt @@ -0,0 +1,319 @@ +{ +"id": "ITH6r6UYtlCyUcpj", +"meta": { +"instanceId": "b9faf72fe0d7c3be94b3ebff0778790b50b135c336412d28fd4fca2cbbf8d1f5" +}, +"name": "AI Agent : Google calendar assistant using OpenAI", +"tags": [], +"nodes": [ +{ +"id": "2e670a54-f789-4c8b-abba-ae35c458f5ed", +"name": "When chat message received", +"type": "@n8n/n8n-nodes-langchain.chatTrigger", +"position": [ +-280, +0 +], +"webhookId": "5308edc9-738b-4aae-a789-214e2392579a", +"parameters": { +"options": {} +}, +"typeVersion": 1.1 +}, +{ +"id": "96bf895f-a18c-4a4c-bc26-3ec5d2372de5", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +160, +820 +], +"parameters": { +"model": "gpt-4o", +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "", +"name": "OpenAi" +} +}, +"typeVersion": 1 +}, +{ +"id": "270176df-9c2d-4f1a-b017-9349cb249341", +"name": "Window Buffer Memory", +"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow", +"position": [ +580, +820 +], +"parameters": {}, +"typeVersion": 1.3 +}, +{ +"id": "5cdece35-bd69-4c77-b240-963df8781d64", +"name": "Google Calendar - Get Events", +"type": "n8n-nodes-base.googleCalendarTool", +"position": [ +960, +800 +], +"parameters": { +"options": { +"timeMax": "={{ $fromAI('end_date') }}", +"timeMin": "={{ $fromAI('start_date') }}" +}, +"calendar": { +"__rl": true, +"mode": "list", +"value": "", +"cachedResultName": "" +}, +"operation": "getAll", +"descriptionType": "manual", +"toolDescription": "Use this tool when you’re asked to retrieve events data." +}, +"credentials": { +"googleCalendarOAuth2Api": { +"id": "", +"name": "Google Calendar account" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "634e6472-099c-4f0e-b9eb-67956c4881b8", +"name": "Google Calendar - Create events", +"type": "n8n-nodes-base.googleCalendarTool", +"position": [ +1380, +800 +], +"parameters": { +"end": "={{ $fromAI('end_date') }} ", +"start": "={{ $fromAI('start_date') }} ", +"calendar": { +"__rl": true, +"mode": "list", +"value": "", +"cachedResultName": "" +}, +"descriptionType": "manual", +"toolDescription": "Use this Google Calendar tool when you are asked to create an event.", +"additionalFields": { +"summary": "={{ $fromAI('event_title') }} ", +"attendees": [], +"description": "={{ $fromAI('event_description') }} " +}, +"useDefaultReminders": false +}, +"credentials": { +"googleCalendarOAuth2Api": { +"id": "", +"name": "Google Calendar account" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "5c93e130-29d5-489b-84ea-3e31f5849b3a", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-380, +-380 +], +"parameters": { +"color": 7, +"width": 320, +"height": 560, +"content": "## Chat trigger - When a message is received\n\nThis node is the **entry point of the workflow**. \nIt triggers the workflow whenever a message is sent to the **chat interface**.\n\nOptions with n8n:\n- **Embed the chat interface** anywhere you want.\n- Use a **webhook node** instead of this node to connect with interfaces like **[Streamlit](https://docs.streamlit.io/develop/tutorials/llms/build-conversational-apps)** or **[OpenWebUI](https://docs.openwebui.com/)**.\n- Use nodes for communication platforms (**Slack**, **Teams**, **Discord**, etc.) if you know how to configure them.\n" +}, +"typeVersion": 1 +}, +{ +"id": "a1e850b4-d0fe-417c-8e1e-13fb4cdbb0a8", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +60, +-380 +], +"parameters": { +"color": 7, +"width": 1520, +"height": 560, +"content": "## Tools Agent - Calendar AI Agent\n\nThis **node** configures the **AI agent** for interaction with Google Calendar. \nIt includes the following features:\n\n- A **prompt source**: This is the user message derived from the chat input of the preceding node (`When chat message is received`).\n- A **system message**: This defines the system prompt to guide the AI agent's behavior. It incorporates the variable `{{ DateTime.local().toFormat('cccc d LLLL yyyy') }`, allowing the AI agent to determine the current date and interact with Google Calendar accordingly. For example, the agent can understand a request like \"Create an event called 'n8n workflow review' for next Tuesday.\"\n\n\nn8n nodes come with built-in **guardrails**, ensuring that if the user requests tasks outside the AI agent's setup, it may not function as intended. (Feel free to test it!)\n" +}, +"typeVersion": 1 +}, +{ +"id": "9b259245-5fd5-4798-973e-bc6aa15da20f", +"name": "Calendar AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +580, +0 +], +"parameters": { +"text": "={{ $json.chatInput }}", +"options": { +"systemMessage": "=You are a Google Calendar assistant.\nYour primary goal is to assist the user in managing their calendar effectively using two tools: Event Creation and Event Retrieval. Always base your responses on the current date: \n{{ DateTime.local().toFormat('cccc d LLLL yyyy') }}.\nGeneral Guidelines:\nIf the user's initial message is vague (e.g., \"hello\" or a generic greeting) or does not specify a request, explain your capabilities clearly:\nExample: \"Hello! I can help you manage your Google Calendar. You can ask me to create an event or retrieve event data. What would you like me to do?\"\nIf the user specifies a request in their first message, begin preparing to use the appropriate tool:\nFor event creation, gather necessary details like start date, end date, title, and description.\nFor event retrieval, ask for the date range or time period they want to query.\nTool: Event Creation\nWhen asked to create an event:\n\nRequest the start and end dates/times from the user.\nDate format: YYYY-MM-DD HH:mm:ss\nCollect the following information:\nstart_date: Exact start date and time of the event.\nend_date: Exact end date and time of the event.\nevent_title: Event title in uppercase. Suggest one if not provided.\nevent_description: Generate a brief description and present it for confirmation.\nTool: Event Retrieval\nWhen asked to retrieve events:\n\nAsk for the date range or period they are interested in. Examples:\nFor \"last week,\" retrieve events from Monday of the previous week to Friday of the same week.\nFor \"today,\" use the current date.\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.\nKey Behaviors:\nClarity: Provide a clear and helpful introduction when the user's request is unclear.\nValidation: Confirm details with the user before finalizing actions.\nAdaptation: Handle varying levels of detail in requests (e.g., \"Add a meeting for next Monday morning\" or \"Retrieve my events for this weekend\").\nProactivity: Offer suggestions to fill in missing details or clarify ambiguous inputs.\nLanguage Matching: Ensure all interactions, including event titles, descriptions, and messages, are in the user's language to provide a seamless experience." +}, +"promptType": "define" +}, +"typeVersion": 1.7 +}, +{ +"id": "b902a7d0-c2ca-4ab9-9f2a-047b9ccb1678", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +60, +240 +], +"parameters": { +"color": 5, +"width": 320, +"height": 720, +"content": "## OpenAI chat model\n\nThis node specifies the chat model used by the agent. \nIn the template, the **default LLM is gpt-4o** for its high relevance.\n\nOther options:\n- You can **try gpt-4o-mini**, which is more cost-effective.\n- You can also choose **other LLM providers besides OpenAI**, but make sure the LLM you select **supports tool-calling**.\n" +}, +"typeVersion": 1 +}, +{ +"id": "c67e1e1b-ef9a-4fec-a860-4ec6b7439df6", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +460, +240 +], +"parameters": { +"color": 5, +"width": 320, +"height": 720, +"content": "## Window buffer memory\n\nThis node manages the **memory** of the agent, specifically the **context window length** for chat history. \nThe default is set to 5 messages.\n\nNote: \nThe **memory** is **temporary**. If you want to **store conversations with the agent**, you should use other nodes like **Postgres chat memory**. \nThis can be easily set up with services like **[Supabase](https://supabase.com/)**.\n" +}, +"typeVersion": 1 +}, +{ +"id": "bf719d53-e21b-4bd5-9443-c24d008f732b", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +860, +240 +], +"parameters": { +"color": 5, +"width": 320, +"height": 720, +"content": "## Google Calendar - Get Events\n\nThis sub-node is a tool used by the AI agent. \nIts purpose is to **retrieve events based on the user input**. \nFor example: *\"Can you give me the events from last week about internal process ?\"*\n\nThe AI agent is designed to **use this tool only** when it has a **date range**. \nIf the user hasn’t provided a date range, the **AI agent will ask the user** for it.\n\nThe **variables** `{{ $fromAI('start_date') }}` and `{{ $fromAI('end_date') }}` are **dynamically filled by the AI**.\n" +}, +"typeVersion": 1 +}, +{ +"id": "e94eb1f8-df42-414b-9bec-9e6991a5a832", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1260, +240 +], +"parameters": { +"color": 5, +"width": 320, +"height": 720, +"content": "## Google Calendar - Create Events\n\nThis sub-node is a tool used by the AI agent. \nIts purpose is to **create events based on the user input**. \nFor example: \"Can you create an event 'Quarter revenue meeting' on [date] from [hour] to [hour] ?\"\n\nThe AI agent is designed to **use this tool only** when it has a **date range**. \nIf the user hasn’t provided a **date range**, the AI agent will **ask the user** for it. \nThe variables `{{ $fromAI('start_date') }}` and `{{ $fromAI('end_date') }}` are dynamically filled by the AI.\n\nBefore creating the event, the AI agent will **confirm with the user** if the **title** and **description** of the event are correct. \nThe variables used for this are:\n- `{{ $fromAI('event_title') }}`\n- `{{ $fromAI('event_description') }}`\n" +}, +"typeVersion": 1 +}, +{ +"id": "707c011c-c822-4922-8ef7-c4368947d179", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +860, +1000 +], +"parameters": { +"color": 4, +"width": 720, +"height": 380, +"content": "## Having fun with it ? Here’s how to level up this AI agent ! \n\nThis workflow demonstrates **how easily you can set up an AI agent to call tools** for you using **n8n**. \nThe tasks here are **useful but very basic**. \n\nIf you want to **enhance the tool-calling capabilities**, consider the following:\n\n- Explore the **\"options\"** in the Google Calendar nodes to see additional features you can use. \n For example, let the AI agent add attendees to events it creates.\n\n- Implement the AI agent with your **teammates and link it to each calendar**. \n Use a `{{ $fromAI('') }}` variable for the calendar field and refine the prompts to suit your needs.\n\n- Add **more actions** for the AI agent to perform with the **Google Calendar API**, expanding its functionality.\n" +}, +"typeVersion": 1 +} +], +"active": false, +"pinData": {}, +"settings": { +"timezone": "Europe/Paris", +"callerPolicy": "workflowsFromSameOwner", +"executionOrder": "v1" +}, +"versionId": "25b51038-e103-4be6-bcd1-64df4b90d4c6", +"connections": { +"Calendar AI Agent": { +"main": [ +[] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Calendar AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Window Buffer Memory": { +"ai_memory": [ +[ +{ +"node": "Calendar AI Agent", +"type": "ai_memory", +"index": 0 +} +] +] +}, +"When chat message received": { +"main": [ +[ +{ +"node": "Calendar AI Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Google Calendar - Get Events": { +"ai_tool": [ +[ +{ +"node": "Calendar AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Google Calendar - Create events": { +"ai_tool": [ +[ +{ +"node": "Calendar AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/AI Agent for project management and meetings with Airtable and Fireflies.txt b/AI Agent for project management and meetings with Airtable and Fireflies.txt new file mode 100644 index 0000000..b9b2c02 --- /dev/null +++ b/AI Agent for project management and meetings with Airtable and Fireflies.txt @@ -0,0 +1,549 @@ +{ +"nodes": [ +{ +"id": "38972c5c-09f4-4120-a468-731e720914e1", +"name": "AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +900, +-240 +], +"parameters": { +"text": "=Title: {{ $json.data.transcript.title }}\n\nParticipants: {{ $json.data.transcript.participants }}\n\nTranscript: {{ JSON.stringify($json.data.transcript.sentences) }}\n\nBullet gist:{{ $json.data.transcript.summary.bullet_gist }}", +"agent": "openAiFunctionsAgent", +"options": { +"systemMessage": "=You get my calls' transcripts from Firefiles.\nThere can be meetings about projects. You can understand if it's about a project if meeting's title contains \"project\". If so - you need to:\n1. Analyze transcript, use tool \"Create Tasks\" to create tasks for me in my AirTable base.\n2. You need to use tool \"Notify Client About Tasks\" to nofity client about his tasks.\n3. If transcript contains info there's a call needed - you'll use \"Create Event\" tool to create call on Google Meet\nCurrent date: {{ $now }}" +}, +"promptType": "define" +}, +"typeVersion": 1.7 +}, +{ +"id": "db5c1bfa-b979-4749-84c8-8cd7d777748c", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +880, +40 +], +"parameters": { +"model": "gpt-4o", +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "9RivS2BmSh1DDBFm", +"name": "OpenAi account 3" +} +}, +"typeVersion": 1 +}, +{ +"id": "334873ba-ec5c-42b3-b8d0-def79d07c0aa", +"name": "Create Tasks", +"type": "@n8n/n8n-nodes-langchain.toolWorkflow", +"position": [ +1040, +40 +], +"parameters": { +"name": "create_task", +"schemaType": "manual", +"workflowId": { +"__rl": true, +"mode": "list", +"value": "Jo0BiizccacaChkH", +"cachedResultName": "Firefiles AI Agent" +}, +"description": "=Use this tool to create a task. \nFor task creation use only action items for me [YOUR NAME HERE], don't use action items for other participants.", +"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"items\": {\n \"type\": \"array\",\n \"description\": \"An array of tasks\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\",\n \"description\": \"The name of the task\"\n },\n \"description\": {\n \"type\": \"string\",\n \"description\": \"A detailed description of the task\"\n },\n \"due_date\": {\n \"type\": \"string\",\n \"description\": \"Due Date\"\n },\n \"priority\": {\n \"type\": \"string\",\n \"description\": \"Priority. . Please capitalize first letter\"\n },\n \"project_name\": {\n \"type\": \"string\",\n \"description\": \"Name of the project. Word 'Project' shouldn't be included\"\n }\n },\n \"required\": [\n \"name\",\n \"description\",\n \"due_date\",\n \"priority\"\n ],\n \"additionalProperties\": false\n }\n }\n },\n \"required\": [\n \"items\"\n ],\n \"additionalProperties\": false\n}", +"specifyInputSchema": true +}, +"typeVersion": 1.3 +}, +{ +"id": "7fd03a80-71e9-4c47-9870-7a3ad4916149", +"name": "Notify Client About Tasks", +"type": "n8n-nodes-base.gmailTool", +"position": [ +1180, +40 +], +"webhookId": "519d9406-10ef-4ae1-a747-d278002cac9e", +"parameters": { +"sendTo": "={{ $fromAI(\"participant_email\",\"participant email \",\"string\") }}", +"message": "=Summary:\n{{ $json.data.transcript.summary.bullet_gist }}\n\nAction Items:\n{{ $fromAI(\"participant_action_items\",\"participant action items \",\"string\") }}", +"options": { +"appendAttribution": false +}, +"subject": "Meeting Summary", +"emailType": "text", +"descriptionType": "manual", +"toolDescription": "=Use the tool to notify a participant of the meeting with meeting summary and his tasks.\nIMPORTANT: \n1. Please notify participants except for me. My email: [YOUR EMAIL HERE]\n2. When working with tasks - please send only the participant's tasks." +}, +"credentials": { +"gmailOAuth2": { +"id": "LhdnHxP8WcSDEHw3", +"name": "Gmail account 3" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "094a0e52-a4fa-4078-9b96-80568acb9c51", +"name": "Execute Workflow Trigger", +"type": "n8n-nodes-base.executeWorkflowTrigger", +"position": [ +460, +420 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "e59e5a29-4509-45cc-9130-181ea432553c", +"name": "Split Out", +"type": "n8n-nodes-base.splitOut", +"position": [ +680, +420 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "query.items" +}, +"typeVersion": 1 +}, +{ +"id": "dc664650-f74e-4574-95a0-dd4a9bf181a1", +"name": "Create Task", +"type": "n8n-nodes-base.airtable", +"position": [ +900, +420 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appndgSF4faN4jPXi", +"cachedResultUrl": "https://airtable.com/appndgSF4faN4jPXi", +"cachedResultName": "Philipp's Base" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblaCSndQsSF3gq7Z", +"cachedResultUrl": "https://airtable.com/appndgSF4faN4jPXi/tblaCSndQsSF3gq7Z", +"cachedResultName": "Tasks" +}, +"columns": { +"value": { +"Name": "={{ $json.name }}", +"Project": "={{ [$json.project_name] }}", +"Due Date": "={{ $json.due_date }}", +"Priority": "={{ $json.priority }}", +"Description": "={{ $json.description }}" +}, +"schema": [ +{ +"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": false, +"readOnly": false, +"required": false, +"displayName": "Description", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Priority", +"type": "options", +"display": true, +"options": [ +{ +"name": "Low", +"value": "Low" +}, +{ +"name": "Medium", +"value": "Medium" +}, +{ +"name": "Urgent", +"value": "Urgent" +}, +{ +"name": "low", +"value": "low" +}, +{ +"name": "medium", +"value": "medium" +}, +{ +"name": "urgent", +"value": "urgent" +} +], +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Priority", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Due Date", +"type": "dateTime", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Due Date", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Project", +"type": "array", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Project", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [] +}, +"options": { +"typecast": true +}, +"operation": "create" +}, +"credentials": { +"airtableTokenApi": { +"id": "XT7hvl1w201jtBhx", +"name": "Philipp Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "6d6f9094-b0b3-495e-ade8-d80c03e727b0", +"name": "Create Event", +"type": "n8n-nodes-base.googleCalendarTool", +"position": [ +1340, +40 +], +"parameters": { +"end": "={{ $fromAI(\"end_date_time\",\"Date and time of meeting end\",\"string\") }}", +"start": "={{ $fromAI(\"start_date_time\",\"Date and time of meeting start\",\"string\") }}", +"calendar": { +"__rl": true, +"mode": "list", +"value": "philipp@lowcoding.dev", +"cachedResultName": "philipp@lowcoding.dev" +}, +"descriptionType": "manual", +"toolDescription": "=Use tool to create Google Calendar Event. Use this tool only when transcript contains information that call should be scheduled.", +"additionalFields": { +"summary": "={{ $fromAI(\"meeting_name\",\"Meeting name\",\"string\") }}", +"attendees": [ +"={{ $fromAI(\"email\",\"client email\",\"string\") }}" +], +"conferenceDataUi": { +"conferenceDataValues": { +"conferenceSolution": "hangoutsMeet" +} +} +} +}, +"credentials": { +"googleCalendarOAuth2Api": { +"id": "E5Ufn31vrZLKzh4n", +"name": "Google Calendar account" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "2406fc01-fd28-403c-9378-473e8748e0dd", +"name": "Webhook", +"type": "n8n-nodes-base.webhook", +"position": [ +480, +-240 +], +"webhookId": "df852a9f-5ea3-43f2-bd49-d045aba5e9c9", +"parameters": { +"path": "df852a9f-5ea3-43f2-bd49-d045aba5e9c9", +"options": {}, +"httpMethod": "POST" +}, +"typeVersion": 2 +}, +{ +"id": "fe28fa98-4946-4379-970e-6df1a79e2a1e", +"name": "Get Meeting Content", +"type": "n8n-nodes-base.httpRequest", +"position": [ +700, +-240 +], +"parameters": { +"url": "https://api.fireflies.ai/graphql", +"method": "POST", +"options": {}, +"jsonBody": "={\n \"query\": \"query Transcript($transcriptId: String!) { transcript(id: $transcriptId) { title participants speakers { id name } sentences { speaker_name text } summary { bullet_gist } } }\",\n \"variables\": {\n \"transcriptId\": \"{{ $json.meetingId }}\"\n }\n}", +"sendBody": true, +"sendHeaders": true, +"specifyBody": "json", +"headerParameters": { +"parameters": [ +{ +"name": "Authorization", +"value": "Bearer [YOUR API KEY HERE]" +} +] +} +}, +"typeVersion": 4.2 +}, +{ +"id": "5eadd00a-9095-4bf3-80ed-e7bc5c49390d", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +620, +-360 +], +"parameters": { +"color": 4, +"height": 80, +"content": "### Replace API key for Fireflies\n" +}, +"typeVersion": 1 +}, +{ +"id": "93cee18c-2215-4a63-af7b-ddf45729f5e4", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1180, +200 +], +"parameters": { +"color": 4, +"height": 80, +"content": "### Replace connections for Airtable and Google\n" +}, +"typeVersion": 1 +}, +{ +"id": "4d792723-4507-486f-9dc7-62bf1b927edd", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +380, +340 +], +"parameters": { +"width": 820, +"height": 280, +"content": "### Scenario 2 - Create Tasks tool" +}, +"typeVersion": 1 +}, +{ +"id": "c5520210-86db-4639-9f8c-ac9055407232", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +380, +-460 +], +"parameters": { +"width": 1100, +"height": 760, +"content": "### Scenario 1 - AI agent" +}, +"typeVersion": 1 +}, +{ +"id": "48d47e44-b7bf-49b3-814b-6969ce97108d", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +800, +180 +], +"parameters": { +"color": 4, +"height": 80, +"content": "### Replace OpenAI connection\n" +}, +"typeVersion": 1 +}, +{ +"id": "afe4bffa-8937-4c31-8513-0acc6b8858ce", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-360, +60 +], +"parameters": { +"color": 7, +"width": 280, +"height": 566, +"content": "### Set up steps\n\n#### Preparation\n1. **Create Accounts**:\n - [N8N](https://n8n.partnerlinks.io/2hr10zpkki6a): For workflow automation.\n - [Airtable](https://airtable.com/): For database hosting and management.\n - [Fireflies](https://fireflies.ai/): For recording meetings.\n\n#### N8N Workflow\n\n1. **Configure the Webhook**: \n - Set up a webhook to capture meeting completion events and integrate it with Fireflies.\n\n2. **Retrieve Meeting Content**: \n - Use GraphQL API requests to extract meeting details and transcripts, ensuring appropriate authentication through Bearer tokens.\n\n3. **AI Processing Setup**: \n - Define system messages for AI tasks and configure connections to the AI chat model (e.g., OpenAI's GPT) to process transcripts.\n\n4. **Task Creation Logic**: \n - Create structured tasks based on AI output, ensuring necessary details are captured and records are created in Airtable.\n\n5. **Client Notifications**: \n - Use an email node to notify clients about their tasks, ensuring communications are client-specific.\n\n6. **Scheduling Follow-Up Calls**: \n - Set up Google Calendar events if follow-up meetings are required, populating details from the original meeting context.\n\n7. **Final Testing**: \n - Conduct tests to ensure each part of the workflow is functional and seamless, making adjustments as needed based on feedback." +}, +"typeVersion": 1 +}, +{ +"id": "cbb81fa7-4a97-4a7e-82ce-05250b2c82cf", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-360, +-460 +], +"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 for project management and meetings with Airtable and Fireflies\n**Made by [Philipp Bekher](https://www.linkedin.com/in/philipp-bekher-5437171a4/) from community [5minAI](https://www.skool.com/5minai-2861)**\n\nManaging action items from meetings can often lead to missed tasks and poor follow-up. This automation alleviates that issue by automatically generating tasks from meeting transcripts, keeping everyone informed about their responsibilities and streamlining communication.\n\nThe workflow leverages n8n to create a Smart Agent that listens for completed meeting transcripts, processes them using AI, and generates tasks in Airtable. Key functionalities include:\n- Capturing completed meeting events through webhooks.\n- Extracting relevant meeting details such as transcripts and participants using API calls.\n- Generating structured tasks from meeting discussions and sending notifications to clients.\n\n" +}, +"typeVersion": 1 +}, +{ +"id": "6d367721-875d-4d43-bd55-9801796a0e9f", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-60, +60 +], +"parameters": { +"color": 7, +"width": 330.5152611046425, +"height": 239.5888196628349, +"content": "### ... or watch set up video [10 min]\n[![Youtube Link](https://cflobdhpqwnoisuctsoc.supabase.co/storage/v1/object/public/my_storage/Video%2011%20-%20Fireflies%20Agent%20Blur.png)](https://www.youtube.com/watch?v=0TyX7G00x3A)\n" +}, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"Webhook": { +"main": [ +[ +{ +"node": "Get Meeting Content", +"type": "main", +"index": 0 +} +] +] +}, +"AI Agent": { +"main": [ +[] +] +}, +"Split Out": { +"main": [ +[ +{ +"node": "Create Task", +"type": "main", +"index": 0 +} +] +] +}, +"Create Event": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Create Tasks": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Get Meeting Content": { +"main": [ +[ +{ +"node": "AI Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Execute Workflow Trigger": { +"main": [ +[ +{ +"node": "Split Out", +"type": "main", +"index": 0 +} +] +] +}, +"Notify Client About Tasks": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/AI Agent for realtime insights on meetings.txt b/AI Agent for realtime insights on meetings.txt new file mode 100644 index 0000000..4d84b32 --- /dev/null +++ b/AI Agent for realtime insights on meetings.txt @@ -0,0 +1,580 @@ +{ +"nodes": [ +{ +"id": "d44489b8-8cb7-4776-8c16-a8bb01e52171", +"name": "OpenAI1", +"type": "@n8n/n8n-nodes-langchain.openAi", +"position": [ +300, +-300 +], +"parameters": { +"text": "={{ \n JSON.parse($('Insert Transcription Part').item.json.dialog)\n .filter(item => item.date_updated && new Date(item.date_updated) >= new Date($('Insert Transcription Part').item.json.date_updated))\n .sort((a, b) => a.order - b.order)\n .map(item => `${item.words}\\n${item.speaker}`)\n .join('\\n\\n')\n}}", +"memory": "threadId", +"prompt": "define", +"options": {}, +"resource": "assistant", +"threadId": "={{ $json.thread_id }}", +"assistantId": { +"__rl": true, +"mode": "list", +"value": "asst_D5t6bNnNpenmfC7PmvywMqyR", +"cachedResultName": "5minAI - Realtime Agent" +} +}, +"credentials": { +"openAiApi": { +"id": "SphXAX7rlwRLkiox", +"name": "Test club key" +} +}, +"typeVersion": 1.6 +}, +{ +"id": "3425f1c1-ad68-495e-bb9a-95ea92e7cf23", +"name": "Insert Transcription Part", +"type": "n8n-nodes-base.postgres", +"position": [ +-120, +-300 +], +"parameters": { +"query": "UPDATE public.data\nSET output = jsonb_set(\n output,\n '{dialog}', \n (\n COALESCE(\n (output->'dialog')::jsonb, \n '[]'::jsonb -- Initialize as empty array if dialog does not exist\n ) || jsonb_build_object(\n 'order', (COALESCE(jsonb_array_length(output->'dialog'), 0) + 1), -- Calculate the next order\n 'words', '{{ $('Webhook2').item.json.body.data.transcript.words.map(word => word.text.replace(/'/g, \"''\")).join(\" \") }}',\n 'speaker', '{{ $('Webhook2').item.json.body.data.transcript.speaker }}',\n 'language', '{{ $('Webhook2').item.json.body.data.transcript.language }}',\n 'speaker_id', ('{{ $('Webhook2').item.json.body.data.transcript.speaker_id }}')::int,\n 'date_updated', to_jsonb('{{ $now }}'::text)\n )\n )\n)\nWHERE input->>'recall_bot_id' = $1\nReturning input->>'openai_thread_id' as thread_id;", +"options": { +"queryReplacement": "={{ $('Scenario 2 Start - Webhook').item.json.body.data.bot_id }}" +}, +"operation": "executeQuery" +}, +"credentials": { +"postgres": { +"id": "AO9cER6p8uX7V07T", +"name": "Postgres 5minai" +} +}, +"typeVersion": 2.5 +}, +{ +"id": "9bcc0605-fc35-4842-a3f4-30ef902f35c1", +"name": "Create Note", +"type": "n8n-nodes-base.postgresTool", +"position": [ +180, +-120 +], +"parameters": { +"query": "UPDATE public.data\nSET output = jsonb_set(\n output,\n '{notes}', \n (\n COALESCE(\n (output->'notes')::jsonb, \n '[]'::jsonb -- Initialize as empty array if dialog does not exist\n ) || jsonb_build_object(\n 'order', (COALESCE(jsonb_array_length(output->'notes'), 0) + 1), -- Calculate the next order\n 'text', '{{ $fromAI(\"note\",\"Text of note.\") }}'\n )\n )\n)\nWHERE input->>'recall_bot_id' = $1", +"options": { +"queryReplacement": "={{ $('Scenario 2 Start - Webhook').item.json.body.data.bot_id }}" +}, +"operation": "executeQuery", +"descriptionType": "manual", +"toolDescription": "Create note record." +}, +"credentials": { +"postgres": { +"id": "AO9cER6p8uX7V07T", +"name": "Postgres 5minai" +} +}, +"typeVersion": 2.5 +}, +{ +"id": "0831c139-ca4b-4b4c-aa7f-7495c4ca0110", +"name": "Create Recall bot", +"type": "n8n-nodes-base.httpRequest", +"position": [ +-60, +-980 +], +"parameters": { +"url": "https://us-west-2.recall.ai/api/v1/bot", +"method": "POST", +"options": {}, +"jsonBody": "={\n \"meeting_url\":\"{{ $json.meeting_url }}\",\n \"transcription_options\": {\n \"provider\": \"assembly_ai\"\n }\n,\n\"real_time_transcription\": {\n \"destination_url\": \"https://n8n.lowcoding.dev/webhook/d074ca1e-52f9-47af-8587-8c24d431f9cd\"\n },\n\"automatic_leave\": {\n \"silence_detection\": {\n \"timeout\": 300, \n \"activate_after\": 600\n },\n \"bot_detection\": {\n \"using_participant_events\": {\n \"timeout\": 600, \n \"activate_after\": 1200\n }\n },\n \"waiting_room_timeout\": 600,\n \"noone_joined_timeout\": 600,\n \"everyone_left_timeout\": 2,\n \"in_call_not_recording_timeout\": 600,\n \"recording_permission_denied_timeout\": 600\n}\n}", +"sendBody": true, +"specifyBody": "json", +"authentication": "genericCredentialType", +"genericAuthType": "httpHeaderAuth" +}, +"credentials": { +"httpHeaderAuth": { +"id": "lfHu7Kn7L7SH3LAF", +"name": "Recall" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "e1122b5b-3af5-4836-802c-40c3a0eb3c93", +"name": "Create OpenAI thread", +"type": "n8n-nodes-base.httpRequest", +"position": [ +140, +-980 +], +"parameters": { +"url": "https://api.openai.com/v1/threads", +"method": "POST", +"options": {}, +"sendHeaders": true, +"authentication": "predefinedCredentialType", +"headerParameters": { +"parameters": [ +{ +"name": "OpenAI-Beta", +"value": "assistants=v2" +} +] +}, +"nodeCredentialType": "openAiApi" +}, +"credentials": { +"openAiApi": { +"id": "SphXAX7rlwRLkiox", +"name": "Test club key" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "784c123d-adbb-4265-9485-2c88dd3091c2", +"name": "Create data record", +"type": "n8n-nodes-base.supabase", +"position": [ +320, +-980 +], +"parameters": { +"tableId": "data", +"fieldsUi": { +"fieldValues": [ +{ +"fieldId": "input", +"fieldValue": "={{ {\"openai_thread_id\": $('Create OpenAI thread').item.json.id, \"recall_bot_id\": $('Create Recall bot').item.json.id, \"meeting_url\":$('Webhook').item.json.body.meeting_url } }}" +}, +{ +"fieldId": "output", +"fieldValue": "={{ {\"dialog\":[]} }}" +} +] +} +}, +"credentials": { +"supabaseApi": { +"id": "iVKNf5qv3ZFhq0ZV", +"name": "Supabase 5minAI" +} +}, +"typeVersion": 1 +}, +{ +"id": "f455c7de-1e64-4a28-9eef-11d19c982813", +"name": "Sticky Note9", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-900, +-380 +], +"parameters": { +"color": 7, +"width": 330.5152611046425, +"height": 239.5888196628349, +"content": "### ... or watch set up video [10 min]\n[![Youtube Thumbnail](https://res.cloudinary.com/de9jgixzm/image/upload/v1739773273/Youtube%20Thumbs/Realtim%20AI%20Agent.png)](https://www.youtube.com/watch?v=rtaX6BMiTeo)\n" +}, +"typeVersion": 1 +}, +{ +"id": "ea90c110-18ad-4f4b-90ab-fcb88b92e709", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1200, +-1060 +], +"parameters": { +"color": 7, +"width": 636, +"height": 657, +"content": "![5min Logo](https://res.cloudinary.com/de9jgixzm/image/upload/v1739773200/Skool%20Assets/ejm3hqnvhgwpnu2fv92s.png)\n## AI Agent for realtime insights on meetings\n**Made by [Mark Shcherbakov](https://www.linkedin.com/in/marklowcoding/) from community [5minAI](https://www.skool.com/5minai)**\n\nTranscribing meetings manually can be tedious and prone to error. This workflow automates the transcription process in real-time, ensuring that key discussions and decisions are accurately captured and easily accessible for later review, thus enhancing productivity and clarity in communications.\n\nThe workflow employs an AI-powered assistant to join virtual meetings and capture discussions through real-time transcription. Key functionalities include:\n- Automatic joining of meetings on platforms like Zoom, Google Meet, and others with the ability to provide real-time transcription.\n- Integration with transcription APIs (e.g., AssemblyAI) to deliver seamless and accurate capture of dialogue.\n- Structuring and storing transcriptions efficiently in a database for easy retrieval and analysis.\n\n1. **Real-Time Transcription**: The assistant captures audio during meetings and transcribes it in real-time, allowing participants to focus on discussions.\n2. **Keyword Recognition**: Key phrases can trigger specific actions, such as noting important points or making prompts to the assistant.\n3. **Structured Data Management**: The assistant maintains a database of transcriptions linked to meeting details for organized storage and quick access later." +}, +"typeVersion": 1 +}, +{ +"id": "378c19bb-0e4a-43d3-9ba5-2a77ebfb5b83", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1200, +-380 +], +"parameters": { +"color": 7, +"width": 280, +"height": 626, +"content": "### Set up steps\n\n#### Preparation\n\n1. **Create Recall.ai API key**\n2. **Setup Supabase account and table**\n```\ncreate table\n public.data (\n id uuid not null default gen_random_uuid (),\n date_created timestamp with time zone not null default (now() at time zone 'utc'::text),\n input jsonb null,\n output jsonb null,\n constraint data_pkey primary key (id),\n ) tablespace pg_default;\n\n```\n3. **Create OpenAI API key**\n\n#### Development\n\n1. **Bot Creation**: \n - Use a node to create the bot that will join meetings. Provide the meeting URL and set transcription options within the API request.\n\n2. **Authentication**: \n - Configure authentication settings via a Bearer token for interacting with your transcription service.\n\n3. **Webhook Setup**: \n - Create a webhook to receive real-time transcription updates, ensuring timely data capture during meetings.\n\n4. **Join Meeting**: \n - Set the bot to join the specified meeting and actively listen to capture conversations.\n\n5. **Transcription Handling**: \n - Combine transcription fragments into cohesive sentences and manage dialog arrays for coherence.\n\n6. **Trigger Actions on Keywords**: \n - Set up keyword recognition that can initiate requests to the OpenAI API for additional interactions based on captured dialogue.\n\n7. **Output and Summary Generation**: \n - Produce insights and summary notes from the transcriptions that can be stored back into the database for future reference." +}, +"typeVersion": 1 +}, +{ +"id": "9a4ff741-ccfd-42e9-883e-43297a73e2c3", +"name": "Scenario 1 Start - Edit Fields", +"type": "n8n-nodes-base.set", +"position": [ +-260, +-980 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "4891fa6e-2dd5-4433-925c-5497ec82e8ab", +"name": "meeting_url", +"type": "string", +"value": "https://meet.google.com/iix-vrav-kuc" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "a4368763-b96e-45e7-884d-aa0cbae2d276", +"name": "Scenario 2 Start - Webhook", +"type": "n8n-nodes-base.webhook", +"position": [ +-320, +-300 +], +"webhookId": "7f176935-cb83-4147-ac14-48c8d747863a", +"parameters": { +"path": "d074ca1e-52f9-47af-8587-8c24d431f9cd", +"options": {}, +"httpMethod": "POST" +}, +"typeVersion": 2 +}, +{ +"id": "107b26af-d1d2-40c7-ad4f-7193d3ae9b70", +"name": "If Jimmy word", +"type": "n8n-nodes-base.if", +"position": [ +80, +-300 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "ba6c2ae5-d0f4-4242-9cf8-97cb84335a93", +"operator": { +"type": "string", +"operation": "contains" +}, +"leftValue": "={{ $('Scenario 2 Start - Webhook').item.json.body.data.transcript.words.map(word => word.text.replace(/'/g, \"''\")).join(\" \") }}", +"rightValue": "=Jimmy" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "49cf34f6-86cf-42cc-9da4-3efb37e6f565", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-380, +-1040 +], +"parameters": { +"width": 920, +"height": 400, +"content": "## Scenario 1\n\n" +}, +"typeVersion": 1 +}, +{ +"id": "34660f39-6ecc-4f2d-98e8-a2c529255e98", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-380, +-360 +], +"parameters": { +"width": 1020, +"height": 420, +"content": "## Scenario 2\n\n" +}, +"typeVersion": 1 +}, +{ +"id": "5027e72d-2b2c-40b4-921e-c4f40d85f251", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-200, +-120 +], +"parameters": { +"color": 3, +"width": 270, +"height": 80, +"content": "### Replace Supabase credentials" +}, +"typeVersion": 1 +}, +{ +"id": "dddea341-da40-4b6a-ae25-a8417e869cc9", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-100, +-780 +], +"parameters": { +"color": 3, +"width": 200, +"height": 80, +"content": "### Replace server location\n\n" +}, +"typeVersion": 1 +}, +{ +"id": "e8e76c2a-f949-400e-92b2-39da8034b471", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +340, +-100 +], +"parameters": { +"color": 4, +"width": 270, +"height": 80, +"content": "### Replace OpenAI credentials" +}, +"typeVersion": 1 +}, +{ +"id": "729a5f6e-5aea-4908-9a82-2a7d7bea1322", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +140, +-780 +], +"parameters": { +"color": 3, +"width": 290, +"height": 80, +"content": "### Replace credentials" +}, +"typeVersion": 1 +}, +{ +"id": "31178e90-62ce-4bf8-8381-dc8138088889", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-320, +-780 +], +"parameters": { +"color": 3, +"width": 200, +"height": 80, +"content": "### Replace meeting url\n\n" +}, +"typeVersion": 1 +} +], +"pinData": { +"Create Recall bot": [ +{ +"id": "ab35fa56-e42b-47c6-b716-eac8d12af601", +"join_at": null, +"metadata": {}, +"recording": null, +"video_url": null, +"recordings": [], +"meeting_url": { +"platform": "google_meet", +"meeting_id": "zst-ymag-zoa" +}, +"status_changes": [ +{ +"code": "ready", +"message": null, +"sub_code": null, +"created_at": "2024-11-01T11:29:32.364684Z" +} +], +"meeting_metadata": null, +"calendar_meetings": [], +"meeting_participants": [] +} +], +"Insert Transcription Part": [ +{ +"dialog": "[{\"order\": 1, \"words\": \"Wait.\", \"speaker\": \"Mark S.\", \"language\": null, \"speaker_id\": 100}, {\"order\": 2, \"words\": \"A bit.\", \"speaker\": \"Mark S.\", \"language\": null, \"speaker_id\": 100}, {\"order\": 3, \"words\": \"It's not even subtitles and it's not even a real. It's. A Google Meet.\", \"speaker\": \"Mark S.\", \"language\": null, \"speaker_id\": 100}, {\"order\": 4, \"words\": \"Same story. I wasn't prepared. I don't know what to tell you. Maybe my AI body can help me.\", \"speaker\": \"Mark S.\", \"language\": null, \"speaker_id\": 100}, {\"order\": 5, \"words\": \"What truth?\", \"speaker\": \"Mark S.\", \"language\": null, \"speaker_id\": 100}, {\"order\": 6, \"words\": \"You can get the same AI body in one day. Just drop AI in comment and I will. Send you a guide.\", \"speaker\": \"Mark S.\", \"language\": null, \"speaker_id\": 100}, {\"order\": 7, \"words\": \"As it works well.\", \"speaker\": \"Mark S.\", \"language\": \"null\", \"speaker_id\": 100}, {\"order\": 8, \"words\": \"As it works well.\", \"speaker\": \"Mark S.\", \"language\": \"null\", \"speaker_id\": 100}, {\"order\": 9, \"words\": \"As it works well.\", \"speaker\": \"Mark S.\", \"language\": \"null\", \"speaker_id\": 100}, {\"order\": 10, \"words\": \"Let's it works well.\", \"speaker\": \"Mark S.\", \"language\": \"null\", \"speaker_id\": 100}, {\"order\": 11, \"words\": \"Let's it works well.\", \"speaker\": \"Mark S.\", \"language\": \"null\", \"speaker_id\": 100}, {\"order\": 12, \"words\": \"Let's it works well.\", \"speaker\": \"Mark S.\", \"language\": \"null\", \"speaker_id\": 100, \"date_updated\": \"2024-11-22T08:41:24.164+01:00\"}, {\"order\": 13, \"words\": \"Let's it works well.\", \"speaker\": \"Mark S.\", \"language\": \"null\", \"speaker_id\": 100, \"date_updated\": \"2024-11-22T08:50:11.330+01:00\"}]", +"thread_id": "thread_0g7p3iE7MYmDPiUuPiZP5vfR", +"date_updated": "2024-11-22T08:37:55.751+01:00" +} +], +"Scenario 2 Start - Webhook": [ +{ +"body": { +"data": { +"bot_id": "0032c6e2-78e9-46e7-a2ef-41d7b853ef48", +"transcript": { +"words": [ +{ +"text": "Let's", +"end_time": 11.88, +"start_time": 11.68 +}, +{ +"text": "it", +"end_time": 12.12, +"start_time": 11.88 +}, +{ +"text": "works", +"end_time": 12.44, +"start_time": 12.12 +}, +{ +"text": "well.", +"end_time": 12.48, +"start_time": 12.44 +} +], +"source": "smart_annotator", +"speaker": "Mark S.", +"is_final": true, +"language": null, +"speaker_id": 100, +"original_transcript_id": 32 +}, +"recording_id": "ee1ad589-39fe-4ed5-b96f-cd14c63f3bc2" +}, +"event": "bot.transcription" +}, +"query": {}, +"params": {}, +"headers": { +"host": "n8n.lowcoding.dev", +"accept": "*/*", +"content-type": "application/json", +"content-length": "495", +"accept-encoding": "gzip", +"x-forwarded-for": "52.10.191.34", +"x-forwarded-host": "n8n.lowcoding.dev", +"x-forwarded-proto": "https" +}, +"webhookUrl": "https://n8n.lowcoding.dev/webhook/d074ca1e-52f9-47af-8587-8c24d431f9cd", +"executionMode": "production" +} +] +}, +"connections": { +"OpenAI1": { +"main": [ +[] +] +}, +"Create Note": { +"ai_tool": [ +[ +{ +"node": "OpenAI1", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"If Jimmy word": { +"main": [ +[ +{ +"node": "OpenAI1", +"type": "main", +"index": 0 +} +] +] +}, +"Create Recall bot": { +"main": [ +[ +{ +"node": "Create OpenAI thread", +"type": "main", +"index": 0 +} +], +[] +] +}, +"Create data record": { +"main": [ +[] +] +}, +"Create OpenAI thread": { +"main": [ +[ +{ +"node": "Create data record", +"type": "main", +"index": 0 +} +] +] +}, +"Insert Transcription Part": { +"main": [ +[ +{ +"node": "If Jimmy word", +"type": "main", +"index": 0 +} +] +] +}, +"Scenario 2 Start - Webhook": { +"main": [ +[ +{ +"node": "Insert Transcription Part", +"type": "main", +"index": 0 +} +] +] +}, +"Scenario 1 Start - Edit Fields": { +"main": [ +[ +{ +"node": "Create Recall bot", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/AI Agent to chat with Airtable and analyze data.txt b/AI Agent to chat with Airtable and analyze data.txt new file mode 100644 index 0000000..5a62105 --- /dev/null +++ b/AI Agent to chat with Airtable and analyze data.txt @@ -0,0 +1,1397 @@ +{ +"nodes": [ +{ +"id": "799d2e0c-29b9-494c-b11a-d79c7ed4a06d", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +920, +480 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "zJhr5piyEwVnWtaI", +"name": "OpenAi club" +} +}, +"typeVersion": 1 +}, +{ +"id": "6254ef4e-9699-404e-96a4-569326cce48d", +"name": "AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +1160, +200 +], +"parameters": { +"text": "={{ $('When chat message received').item.json.chatInput }}", +"agent": "openAiFunctionsAgent", +"options": { +"maxIterations": 10, +"systemMessage": "You are Airtable 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\nFeel free to ask questions before do actions - especially if you noticed some inconcistency in user requests that might be error/misspelling. \n\nIMPORTANT Always check right table and base ids before doing queries.\n\nIMPORTANT Use Code function to do aggregation functions that requires math like - count, sum, average and etc. Aggegation function could be recognized by words like \"how many\",\"count\",\"what number\" and etc.\nUse Code function to generate graph and images.\n\nIMPORTANT If search with filter failed - try to fetch records without filter\n\nIMPORTANT Ask yourself before answering - am I did everything is possible? Is the answer is right? Is the answer related to user request?\n\nIMPORTANT Always return in response name of Base and Table where records from. " +}, +"promptType": "define" +}, +"typeVersion": 1.6 +}, +{ +"id": "227a5427-c270-47dc-bc08-4bb321314926", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1740, +620 +], +"parameters": { +"height": 80, +"content": "### Replace Mapbox public key - in code" +}, +"typeVersion": 1 +}, +{ +"id": "667751f4-9815-45b7-8dd2-9a0821a7a5a7", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +840, +640 +], +"parameters": { +"height": 80, +"content": "### Replace OpenAI connection" +}, +"typeVersion": 1 +}, +{ +"id": "a9cdec25-4167-44a9-9d3c-fb04aac7bb32", +"name": "Window Buffer Memory", +"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow", +"position": [ +1080, +480 +], +"parameters": { +"sessionKey": "={{ $('When chat message received').item.json.sessionId }}", +"sessionIdType": "customKey" +}, +"typeVersion": 1.3 +}, +{ +"id": "dfab4eb2-ba30-4756-8a52-5d73de9fba53", +"name": "When chat message received", +"type": "@n8n/n8n-nodes-langchain.chatTrigger", +"position": [ +940, +200 +], +"webhookId": "abf9ab75-eaca-4b91-b3ba-c0f83d3daba4", +"parameters": { +"options": {} +}, +"typeVersion": 1.1 +}, +{ +"id": "259e3d13-ca92-4756-af69-34065dbe08f3", +"name": "Execute Workflow Trigger", +"type": "n8n-nodes-base.executeWorkflowTrigger", +"position": [ +760, +1340 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "5b80c2c8-7649-40f2-b9be-d090d8bd5ae9", +"name": "Response", +"type": "n8n-nodes-base.set", +"position": [ +2740, +1360 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "cfdbe2f5-921e-496d-87bd-9c57fdc22a7a", +"name": "response", +"type": "object", +"value": "={{$json}}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "761f5593-f85c-44cd-abbd-aeac78bc31f8", +"name": "Switch", +"type": "n8n-nodes-base.switch", +"position": [ +980, +1320 +], +"parameters": { +"rules": { +"values": [ +{ +"outputKey": "get_bases", +"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_bases" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "get_base_tables_schema", +"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": "get_base_tables_schema" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "search", +"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": "search" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "code", +"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": "code" +} +] +}, +"renameOutput": true +} +] +}, +"options": {} +}, +"typeVersion": 3.2 +}, +{ +"id": "d6252c5b-a820-4ded-b59b-ab2fb2e277c3", +"name": "Aggregate", +"type": "n8n-nodes-base.aggregate", +"position": [ +1780, +980 +], +"parameters": { +"options": {}, +"aggregate": "aggregateAllItemData" +}, +"typeVersion": 1 +}, +{ +"id": "1442ca2e-1793-4029-b398-61d6e6f1c346", +"name": "Aggregate1", +"type": "n8n-nodes-base.aggregate", +"position": [ +1780, +1140 +], +"parameters": { +"options": {}, +"aggregate": "aggregateAllItemData" +}, +"typeVersion": 1 +}, +{ +"id": "a81b4dcc-c999-43be-a0ea-e37f3c7c9f9d", +"name": "Merge", +"type": "n8n-nodes-base.merge", +"position": [ +1960, +1360 +], +"parameters": {}, +"typeVersion": 3 +}, +{ +"id": "8029213c-fd8a-4673-a2a0-11b90fd23971", +"name": "Aggregate2", +"type": "n8n-nodes-base.aggregate", +"position": [ +2260, +1360 +], +"parameters": { +"options": { +"mergeLists": true +}, +"fieldsToAggregate": { +"fieldToAggregate": [ +{ +"fieldToAggregate": "records" +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "f5f99038-9d19-49ed-9f50-3cd0270bf9ce", +"name": "If1", +"type": "n8n-nodes-base.if", +"position": [ +2120, +1720 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "fcb24127-53f9-4498-b0fd-463bd4966ac9", +"operator": { +"type": "string", +"operation": "notExists", +"singleValue": true +}, +"leftValue": "={{ $json.data[0].attachments[0].file_id }}", +"rightValue": "" +}, +{ +"id": "016ecba7-f6af-4881-a7d6-780dcb43223c", +"operator": { +"type": "string", +"operation": "notExists", +"singleValue": true +}, +"leftValue": "={{ $json.data[0].content.find(x=>x.type==\"image_file\").image_file.file_id }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "abc7ddae-9ca9-4cf6-89a4-a63da8c1e036", +"name": "Response1", +"type": "n8n-nodes-base.set", +"position": [ +2760, +1720 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "cfdbe2f5-921e-496d-87bd-9c57fdc22a7a", +"name": "response", +"type": "string", +"value": "={{ $json.data.url.replace('org/','org/dl/') }}" +} +] +}, +"includeOtherFields": true +}, +"typeVersion": 3.4 +}, +{ +"id": "6f40d50f-70e8-4b64-aa42-ae9262fb8381", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2080, +1520 +], +"parameters": { +"width": 160, +"height": 80, +"content": "### Replace Airtable connection" +}, +"typeVersion": 1 +}, +{ +"id": "de99a161-5ab3-4b54-bdf7-340d74aa5a93", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1740, +1600 +], +"parameters": { +"width": 160, +"height": 80, +"content": "### Replace OpenAI connection" +}, +"typeVersion": 1 +}, +{ +"id": "c1e030fd-4449-43ca-a4e7-a863f9487614", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1540, +860 +], +"parameters": { +"width": 160, +"height": 80, +"content": "### Replace Airtable connection" +}, +"typeVersion": 1 +}, +{ +"id": "4375d3a4-0b3b-4de6-9db7-42af4148af2b", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1360, +1900 +], +"parameters": { +"width": 1180, +"height": 80, +"content": "### Replace OpenAI connection" +}, +"typeVersion": 1 +}, +{ +"id": "138f813c-d0b0-4a2b-8833-69f1decc9253", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +700, +0 +], +"parameters": { +"color": 6, +"width": 1320, +"height": 780, +"content": "### Workflow 1" +}, +"typeVersion": 1 +}, +{ +"id": "ca87c7b7-ab34-4ff9-8d74-cef90e6f1e5e", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +700, +840 +], +"parameters": { +"color": 6, +"width": 2240, +"height": 1180, +"content": "### Workflow 2" +}, +"typeVersion": 1 +}, +{ +"id": "a5cdf41a-f2ca-4203-94ce-45795395ea92", +"name": "Sticky Note9", +"type": "n8n-nodes-base.stickyNote", +"position": [ +300, +680 +], +"parameters": { +"color": 7, +"width": 330.5152611046425, +"height": 239.5888196628349, +"content": "### ... or watch set up video [20 min]\n[![Youtube Thumbnail](https://cflobdhpqwnoisuctsoc.supabase.co/storage/v1/object/public/my_storage/Video%2012%20-%20Chat%20with%20Airtable%20Blur.png)](https://youtu.be/SotqsAZEhdc)\n" +}, +"typeVersion": 1 +}, +{ +"id": "697889c4-15e7-4099-89b8-f4e2e3a3abac", +"name": "Sticky Note10", +"type": "n8n-nodes-base.stickyNote", +"position": [ +0, +0 +], +"parameters": { +"color": 7, +"width": 636, +"height": 657, +"content": "![5min Logo](https://cflobdhpqwnoisuctsoc.supabase.co/storage/v1/object/public/my_storage/banner.png)\n## AI Agent to chat with Airtable and analyze data\n**Made by [Mark Shcherbakov](https://www.linkedin.com/in/marklowcoding/) from community [5minAI](https://www.skool.com/5minai)**\n\nEngaging with data stored in Airtable often requires manual navigation and time-consuming searches. This workflow allows users to interact conversationally with their datasets, retrieving essential information quickly while minimizing the need for complex queries.\n\nThis workflow enables an AI agent to facilitate chat interactions over Airtable data. The agent can:\n- Retrieve order records, product details, and other relevant data.\n- Execute mathematical functions to analyze data such as calculating averages and totals.\n- Optionally generate maps for geographic data visualization.\n\n1. **Dynamic Data Retrieval**: The agent uses user prompts to dynamically query the dataset.\n2. **Memory Management**: It retains context during conversations, allowing users to engage in a more natural dialogue.\n3. **Search and Filter Capabilities**: Users can perform tailored searches with specific parameters or filters to refine their results." +}, +"typeVersion": 1 +}, +{ +"id": "a9f7c4fd-c07a-4c7c-875d-74b27e3f1fbf", +"name": "Sticky Note11", +"type": "n8n-nodes-base.stickyNote", +"position": [ +0, +680 +], +"parameters": { +"color": 7, +"width": 280, +"height": 346, +"content": "### Set up steps\n\n1. **Separate workflows**:\n\t- Create additional workflow and move there Workflow 2.\n\n2. **Replace credentials**:\n\t- Replace connections and credentials in all nodes.\n\n3. **Start chat**:\n\t- Ask questions and don't forget to mention required base name." +}, +"typeVersion": 1 +}, +{ +"id": "0c86638f-7220-415d-a920-13761da925a6", +"name": "Search records", +"type": "@n8n/n8n-nodes-langchain.toolWorkflow", +"position": [ +1500, +480 +], +"parameters": { +"name": "search", +"fields": { +"values": [ +{ +"name": "command", +"stringValue": "search" +} +] +}, +"schemaType": "manual", +"workflowId": { +"__rl": true, +"mode": "list", +"value": "zVd0G4m33K6KrBvV", +"cachedResultName": "Airtable Agent Tools" +}, +"description": "Search records in specific base and table.\n\n- Use Filter (optional) rules for filtering - describe what logic you want to see in filter including field names. \nIMPORTANT - specify all related fields with types for Filter query with right names based on schema. Tool doesn't know schema and type of fields.\n\n- Use Limit (optional) to get more/less records - default = All records. IMPORTANT use default value only when user ask to get all records for analysis.\n\n- Always try to limit list of fields based on user request or in case of number of fields > 30. IMPORTANT Use fields names only.\n \n- Sort by one/multiple fields if needed - order in array is order of level for sorting.\n\nInput example:\nbase_id - appHwXgLVrBujox4J\ntable_id - tblrGzFneREP5Dktl\nlimit - 100\nsort (optional) - [{\"field\":\"Name\",\"direction\":\"asc\"}]\nfilter_desc (optional) - field Name (string) should be equal/contains Mark\nfields (optional) - [\"Name\",\"Email\"]\n\nOutput example:\nRecord 1 - value 1, value 2", +"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"base_id\": {\n \"type\": \"string\",\n \"description\": \"ID of the base to search in\"\n },\n \"table_id\": {\n \"type\": \"string\",\n \"description\": \"ID of the table to search in\"\n },\n \"limit\": {\n \"type\": \"number\",\n \"description\": \"Number of records to retrieve (default is all records)\"\n },\n \"filter_desc\": {\n \"type\": \"string\",\n \"description\": \"Text description of the filter logic\"\n },\n \"sort\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"field\": { \"type\": \"string\" },\n \"direction\": { \"type\": \"string\", \"enum\": [\"asc\", \"desc\"] }\n },\n \"required\": [\"field\", \"direction\"]\n },\n \"description\": \"Array of sorting rules for the query\"\n },\n \"fields\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" },\n \"description\": \"List of fields to retrieve\"\n }\n },\n \"required\": [\"base_id\", \"table_id\"]\n}", +"specifyInputSchema": true +}, +"typeVersion": 1.2 +}, +{ +"id": "7ba1d6ac-f1a2-4b8d-a9a5-ce92eaa4e7fa", +"name": "Process data with code", +"type": "@n8n/n8n-nodes-langchain.toolWorkflow", +"position": [ +1640, +480 +], +"parameters": { +"name": "code", +"fields": { +"values": [ +{ +"name": "command", +"stringValue": "code" +} +] +}, +"schemaType": "manual", +"workflowId": { +"__rl": true, +"mode": "list", +"value": "zVd0G4m33K6KrBvV", +"cachedResultName": "Airtable Agent Tools" +}, +"description": "Process data with code. Use for math functions and image (graphs) generation. \nIMPORTANT Provide raw data only, don't preprocess or use math functions by yourself\n\nInput example:\nrequest - Count average\ndata - 1,2,3\n\nOutput example:\nAverage is 2\nImage file", +"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"request\": {\n \"type\": \"string\",\n \"description\": \"Description of the operation to perform.\"\n },\n \"data\": {\n \"type\": \"string\",\n \"description\": \"Stringified data - JSON, strings, arrays and etc.\"\n }\n },\n \"required\": [\"request\", \"data\"]\n}", +"specifyInputSchema": true +}, +"typeVersion": 1.2 +}, +{ +"id": "3754175c-6f74-4750-b2e7-00e2bd3caf6d", +"name": "Create map image", +"type": "@n8n/n8n-nodes-langchain.toolCode", +"position": [ +1800, +480 +], +"parameters": { +"name": "create_map", +"jsCode": "// Example: convert the incoming query to uppercase and return it\n\nreturn `https://api.mapbox.com/styles/v1/mapbox/streets-v12/static/${query.markers}/-96.9749,41.8219,3.31,0/800x500?before_layer=admin-0-boundary&access_token=`;", +"schemaType": "manual", +"description": "Create link with image for map graph.\nUse addresses' longitude and latitude to create input data.\n\nInput Example:\npin-s+555555(-74.006,40.7128),pin-s+555555(-118.2437,34.0522)\n\nOutput Example:\nImage link.", +"inputSchema": "{\n\"type\": \"object\",\n\"properties\": {\n\t\"markers\": {\n\t\t\"type\": \"string\",\n\t\t\"description\": \"List of markers with longitude and latitude data separated by comma. Keep the same color 555555|Example: pin-s+555555(-74.006,40.7128),pin-s+555555(-118.2437,34.0522)\"\n\t\t}\n\t}\n}", +"specifyInputSchema": true +}, +"typeVersion": 1.1 +}, +{ +"id": "135078ea-6a3f-4aee-9f60-c6d5832e446e", +"name": "Get list of bases", +"type": "@n8n/n8n-nodes-langchain.toolWorkflow", +"position": [ +1220, +480 +], +"parameters": { +"name": "get_bases", +"fields": { +"values": [ +{ +"name": "command", +"stringValue": "get_bases" +} +] +}, +"workflowId": { +"__rl": true, +"mode": "list", +"value": "zVd0G4m33K6KrBvV", +"cachedResultName": "Airtable Agent Tools" +}, +"description": "Fetches the list of available bases.\n\nOutput:\n- List of bases with their IDs and names." +}, +"typeVersion": 1.2 +}, +{ +"id": "cd4781d0-f873-4aea-951c-6809358c1db6", +"name": "Get base schema", +"type": "@n8n/n8n-nodes-langchain.toolWorkflow", +"position": [ +1360, +480 +], +"parameters": { +"name": "get_base_tables_schema", +"fields": { +"values": [ +{ +"name": "command", +"stringValue": "get_base_tables_schema" +} +] +}, +"schemaType": "manual", +"workflowId": { +"__rl": true, +"mode": "list", +"value": "zVd0G4m33K6KrBvV", +"cachedResultName": "Airtable Agent Tools" +}, +"description": "Fetches the schema of tables in a specific base by id.\n\nInput:\nbase_id: appHwXgLVrBujox4J\n\nOutput:\ntable 1: field 1 - type string, fields 2 - type number", +"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"base_id\": {\n \"type\": \"string\",\n \"description\": \"ID of the base to retrieve the schema for. Format - appHwXgLVrBujox4J\"\n }\n },\n \"required\": [\"base_id\"]\n}", +"specifyInputSchema": true +}, +"typeVersion": 1.2 +}, +{ +"id": "45c8b2eb-f43a-48b1-a270-9caeda9da0b0", +"name": "Get Bases", +"type": "n8n-nodes-base.airtable", +"position": [ +1580, +980 +], +"parameters": { +"options": {}, +"resource": "base" +}, +"credentials": { +"airtableTokenApi": { +"id": "xZwG0YpqsxpWrzVM", +"name": "Mark Airtable account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "bb8036bc-1c23-461b-bd03-2461e31c6cb6", +"name": "Get Base/Tables schema", +"type": "n8n-nodes-base.airtable", +"position": [ +1580, +1140 +], +"parameters": { +"base": { +"__rl": true, +"mode": "id", +"value": "={{ $('Execute Workflow Trigger').item.json.query.base_id }}" +}, +"resource": "base", +"operation": "getSchema" +}, +"credentials": { +"airtableTokenApi": { +"id": "xZwG0YpqsxpWrzVM", +"name": "Mark Airtable account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "dab309d9-3629-44ba-9f0a-ede55f96488f", +"name": "If filter description exists", +"type": "n8n-nodes-base.if", +"position": [ +1340, +1360 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "fcb24127-53f9-4498-b0fd-463bd4966ac9", +"operator": { +"type": "string", +"operation": "notExists", +"singleValue": true +}, +"leftValue": "={{ $('Execute Workflow Trigger').item.json.query.filter_desc }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "4cc416aa-50bd-4b60-ae51-887c4ee97c88", +"name": "Airtable - Search records", +"type": "n8n-nodes-base.httpRequest", +"onError": "continueErrorOutput", +"position": [ +2100, +1360 +], +"parameters": { +"url": "=https://api.airtable.com/v0/{{ $('Execute Workflow Trigger').item.json.query.base_id }}/{{ $('Execute Workflow Trigger').item.json.query.table_id }}/listRecords", +"method": "POST", +"options": { +"pagination": { +"pagination": { +"parameters": { +"parameters": [ +{ +"name": "offset", +"type": "body", +"value": "={{ $response.body.offset}}" +} +] +}, +"completeExpression": "={{ $response.body.offset==undefined}}", +"paginationCompleteWhen": "other" +} +} +}, +"jsonBody": "={{ \n Object.fromEntries(\n Object.entries({\n sort: $('Execute Workflow Trigger').item.json.query.sort,\n limit: $('Execute Workflow Trigger').item.json.query.limit,\nfields: $('Execute Workflow Trigger').item.json.query.fields,\nfilterByFormula: $('Merge').item.json.choices == undefined ? undefined : JSON.parse($json.choices[0].message.content).filter\n }).filter(([key, value]) => value !== undefined)\n )\n}}", +"sendBody": true, +"specifyBody": "json", +"authentication": "predefinedCredentialType", +"nodeCredentialType": "airtableTokenApi" +}, +"credentials": { +"httpQueryAuth": { +"id": "1DXeuNaLSixqGPaU", +"name": "Query Auth account Youtube" +}, +"airtableTokenApi": { +"id": "xZwG0YpqsxpWrzVM", +"name": "Mark Airtable account" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "9dc71d31-8499-4b69-b87c-898217447d50", +"name": "OpenAI - Generate search filter", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1760, +1420 +], +"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\": {{ JSON.stringify($('Set schema and prompt').item.json.prompt) }}\n },\n {\n \"role\": \"user\",\n \"content\": \"{{ $('Execute Workflow Trigger').item.json.query.filter_desc }}\"\n }],\n \"response_format\":{ \"type\": \"json_schema\", \"json_schema\": {{ $('Set schema and prompt').item.json.schema }}\n\n }\n }", +"sendBody": true, +"specifyBody": "json", +"authentication": "predefinedCredentialType", +"nodeCredentialType": "openAiApi" +}, +"credentials": { +"openAiApi": { +"id": "zJhr5piyEwVnWtaI", +"name": "OpenAi club" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "16e4ea97-ea73-45a0-aa88-0f9a2969a6a3", +"name": "Set schema and prompt", +"type": "n8n-nodes-base.set", +"position": [ +1560, +1420 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "dc09a5b4-ff6a-4cee-b87e-35de7336ac05", +"name": "prompt", +"type": "string", +"value": "=Analyse user request for Airtable filtration. User filter rules to build right formula. Think smart about filter (e.g. instead of search where Name equal to value - search where name contains lowercase value)\nIMPORTANT Check examples and best practices before building formula. \n\nIMPORTANT best practices:\n\nSEARCH(LOWER('example'), LOWER({Field})) ensures both the search term and field are compared in lowercase for consistent case-insensitive matching\n\nIMPORTANT Examples:\n\n- AND(SEARCH('urgent', {Notes}), {Priority} > 3) fetch records where “Notes” contain “urgent” and “Priority” is greater than 3\n- AND({Status} = 'Pending', IS_BEFORE({Due Date}, TODAY())) fetch records where “Status” is “Pending” and “Due Date” is before today\n- OR(SEARCH('error', {Logs}), SEARCH('warning', {Logs})) fetch records where “Logs” contain “error” or “warning”\n- AND(LEN({Description}) > 10, {Price} > 50) fetch records where “Description” is longer than 10 characters and “Price” is greater than 50\n- RECORD_ID() = 'rec12345' fetch a specific record by its ID\n- SEARCH('rec67890', ARRAYJOIN({Linked Records}, ',')) fetch records linked to a specific record ID rec67890\n- AND(SEARCH('rec12345', ARRAYJOIN({Linked Records}, ',')), {Status} = 'Active') fetch records where “Linked Records” contain rec12345 and “Status” is “Active”\n\nFormula rules:\nOperators - =,!=,>,<,>=,<= \n- AND(condition1, condition2, ...) logical AND\n- OR(condition1, condition2, ...) logical OR\n- NOT(condition) logical NOT\n- SEARCH('substring', {Field}) finds position of substring, case-insensitive\n- FIND('substring', {Field}) finds position of substring, case-sensitive\n- IS_BEFORE({Date}, 'YYYY-MM-DD') checks if date is before\n- IS_AFTER({Date}, 'YYYY-MM-DD') checks if date is after\n- IS_SAME({Date1}, {Date2}, 'unit') checks if dates are the same by unit\n- RECORD_ID() = 'recXXXXXX' filters by record ID\n- {Field} = '' field is blank\n- {Field} != '' field is not blank\n- ARRAYJOIN({Linked Field}, ',') joins linked records into a string\n- LOWER({Field}) converts to lowercase for case-insensitive comparison\n- UPPER({Field}) converts to uppercase for case-insensitive comparison\n- VALUE({Text}) converts text to number for numeric comparisons\n- LEN({Field}) gets text length\n- ROUND(number, precision) rounds number\n- TODAY() current date\n- NOW() current timestamp\n- IF(condition, true_value, false_value) conditional logic\n- DATETIME_FORMAT({Date}, 'format') formats date as text\n- DATETIME_DIFF(date1, date2, 'unit') difference between dates\n- DATEADD({Date}, number, 'unit') adds time to date\n- LEFT({Text}, number) extracts leftmost characters\n- RIGHT({Text}, number) extracts rightmost characters\n- AND({Field1} = 'Value1', {Field2} > 50) multiple conditions\n- SEARCH('Value', {Field}) substring match\n- ROUND({Field1} / {Field2}, 2) numeric calculation\n- AND(IS_BEFORE({Date}, TODAY()), {Status} = 'Active') filter by date and status\n- ISERROR(expression) checks if an expression has an error\n- ABS(number) absolute value\n- MIN(value1, value2) minimum value\n- MAX(value1, value2) maximum value\n\n" +}, +{ +"id": "4e0f9af6-517f-42af-9ced-df0e8a7118b0", +"name": "schema", +"type": "string", +"value": "={\n \"name\": \"filter\",\n \"schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"filter\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"filter\"\n ],\n \"additionalProperties\": false\n },\n \"strict\": true\n}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "6e670074-8508-4282-9c40-600cc445b10f", +"name": "Upload file to get link", +"type": "n8n-nodes-base.httpRequest", +"onError": "continueRegularOutput", +"position": [ +2580, +1720 +], +"parameters": { +"url": "=https://tmpfiles.org/api/v1/upload", +"method": "POST", +"options": {}, +"sendBody": true, +"contentType": "multipart-form-data", +"bodyParameters": { +"parameters": [ +{ +"name": "file", +"parameterType": "formBinaryData", +"inputDataFieldName": "data" +} +] +} +}, +"typeVersion": 4.2 +}, +{ +"id": "b7569d19-3a10-41e5-932b-4be04260a58e", +"name": "OpenAI - Download File", +"type": "n8n-nodes-base.httpRequest", +"position": [ +2360, +1720 +], +"parameters": { +"url": "=https://api.openai.com/v1/files/{{ $json.data[0].attachments[0]?.file_id ?? $json.data[0].content.find(x=>x.type==\"image_file\")?.image_file.file_id }}/content", +"options": {}, +"sendHeaders": true, +"authentication": "predefinedCredentialType", +"headerParameters": { +"parameters": [ +{ +"name": "OpenAI-Beta", +"value": "assistants=v2" +} +] +}, +"nodeCredentialType": "openAiApi" +}, +"credentials": { +"openAiApi": { +"id": "vBLHyjEnMK9EaWwQ", +"name": "Mark OpenAi " +} +}, +"typeVersion": 4.2 +}, +{ +"id": "bf378b21-07fb-4f9e-bfc5-9623ebcb8236", +"name": "OpenAI - Get messages", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1960, +1720 +], +"parameters": { +"url": "=https://api.openai.com/v1/threads/{{ $('OpenAI - Create thread').item.json.id }}/messages", +"options": {}, +"sendHeaders": true, +"authentication": "predefinedCredentialType", +"headerParameters": { +"parameters": [ +{ +"name": "OpenAI-Beta", +"value": "assistants=v2" +} +] +}, +"nodeCredentialType": "openAiApi" +}, +"credentials": { +"openAiApi": { +"id": "zJhr5piyEwVnWtaI", +"name": "OpenAi club" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "9874eec1-61e2-45fe-8c57-556957a15473", +"name": "OpenAI - Run assistant", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1760, +1720 +], +"parameters": { +"url": "=https://api.openai.com/v1/threads/{{ $('OpenAI - Create thread').item.json.id }}/runs", +"method": "POST", +"options": {}, +"sendBody": true, +"sendHeaders": true, +"authentication": "predefinedCredentialType", +"bodyParameters": { +"parameters": [ +{ +"name": "assistant_id", +"value": "asst_PGUuvzEGJWOE8p8vwV56INLO" +}, +{ +"name": "stream", +"value": "={{true}}" +}, +{ +"name": "tool_choice", +"value": "={{ {\"type\": \"code_interpreter\"} }}" +}, +{ +"name": "tools", +"value": "={{ [{\"type\": \"code_interpreter\"}] }}" +} +] +}, +"headerParameters": { +"parameters": [ +{ +"name": "OpenAI-Beta", +"value": "assistants=v2" +} +] +}, +"nodeCredentialType": "openAiApi" +}, +"credentials": { +"openAiApi": { +"id": "fLfRtaXbR0EVD0pl", +"name": "OpenAi account" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "e5339ad2-36c7-40c5-846b-2bd242f41ea5", +"name": "OpenAI - Send message", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1560, +1720 +], +"parameters": { +"url": "=https://api.openai.com/v1/threads/{{ $('OpenAI - Create thread').item.json.id }}/messages ", +"method": "POST", +"options": {}, +"sendBody": true, +"sendHeaders": true, +"authentication": "predefinedCredentialType", +"bodyParameters": { +"parameters": [ +{ +"name": "role", +"value": "user" +}, +{ +"name": "content", +"value": "=Request:\n{{ $('Execute Workflow Trigger').item.json.query.request }}\n\nData:\n{{ $('Execute Workflow Trigger').item.json.query.data }}" +} +] +}, +"headerParameters": { +"parameters": [ +{ +"name": "OpenAI-Beta", +"value": "assistants=v2" +} +] +}, +"nodeCredentialType": "openAiApi" +}, +"credentials": { +"openAiApi": { +"id": "fLfRtaXbR0EVD0pl", +"name": "OpenAi account" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "5b822c15-af63-43f6-ac30-61a34dcd91ee", +"name": "OpenAI - Create thread", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1360, +1720 +], +"parameters": { +"url": "https://api.openai.com/v1/threads", +"method": "POST", +"options": {}, +"sendHeaders": true, +"authentication": "predefinedCredentialType", +"headerParameters": { +"parameters": [ +{ +"name": "OpenAI-Beta", +"value": "assistants=v2" +} +] +}, +"nodeCredentialType": "openAiApi" +}, +"credentials": { +"openAiApi": { +"id": "vBLHyjEnMK9EaWwQ", +"name": "Mark OpenAi " +} +}, +"typeVersion": 4.2 +} +], +"pinData": {}, +"connections": { +"If1": { +"main": [ +[ +{ +"node": "Response", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "OpenAI - Download File", +"type": "main", +"index": 0 +} +] +] +}, +"Merge": { +"main": [ +[ +{ +"node": "Airtable - Search records", +"type": "main", +"index": 0 +} +] +] +}, +"Switch": { +"main": [ +[ +{ +"node": "Get Bases", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Get Base/Tables schema", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "If filter description exists", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "OpenAI - Create thread", +"type": "main", +"index": 0 +} +] +] +}, +"Aggregate": { +"main": [ +[ +{ +"node": "Response", +"type": "main", +"index": 0 +} +] +] +}, +"Get Bases": { +"main": [ +[ +{ +"node": "Aggregate", +"type": "main", +"index": 0 +} +] +] +}, +"Aggregate1": { +"main": [ +[ +{ +"node": "Response", +"type": "main", +"index": 0 +} +] +] +}, +"Aggregate2": { +"main": [ +[ +{ +"node": "Response", +"type": "main", +"index": 0 +} +] +] +}, +"Search records": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Get base schema": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Create map image": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Get list of bases": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Window Buffer Memory": { +"ai_memory": [ +[ +{ +"node": "AI Agent", +"type": "ai_memory", +"index": 0 +} +] +] +}, +"OpenAI - Get messages": { +"main": [ +[ +{ +"node": "If1", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI - Send message": { +"main": [ +[ +{ +"node": "OpenAI - Run assistant", +"type": "main", +"index": 0 +} +] +] +}, +"Set schema and prompt": { +"main": [ +[ +{ +"node": "OpenAI - Generate search filter", +"type": "main", +"index": 0 +} +] +] +}, +"Get Base/Tables schema": { +"main": [ +[ +{ +"node": "Aggregate1", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI - Create thread": { +"main": [ +[ +{ +"node": "OpenAI - Send message", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI - Download File": { +"main": [ +[ +{ +"node": "Upload file to get link", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI - Run assistant": { +"main": [ +[ +{ +"node": "OpenAI - Get messages", +"type": "main", +"index": 0 +} +] +] +}, +"Process data with code": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Upload file to get link": { +"main": [ +[ +{ +"node": "Response1", +"type": "main", +"index": 0 +} +] +] +}, +"Execute Workflow Trigger": { +"main": [ +[ +{ +"node": "Switch", +"type": "main", +"index": 0 +} +] +] +}, +"Airtable - Search records": { +"main": [ +[ +{ +"node": "Aggregate2", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Response", +"type": "main", +"index": 0 +} +] +] +}, +"When chat message received": { +"main": [ +[ +{ +"node": "AI Agent", +"type": "main", +"index": 0 +} +] +] +}, +"If filter description exists": { +"main": [ +[ +{ +"node": "Merge", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Set schema and prompt", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI - Generate search filter": { +"main": [ +[ +{ +"node": "Merge", +"type": "main", +"index": 1 +} +] +] +} +} +}AI Agent to chat with Airtable and analyze data \ No newline at end of file diff --git a/AI Agent to chat with Supabase_PostgreSQL DB.txt b/AI Agent to chat with Supabase_PostgreSQL DB.txt new file mode 100644 index 0000000..1ccbe4c --- /dev/null +++ b/AI Agent to chat with Supabase_PostgreSQL DB.txt @@ -0,0 +1,261 @@ +{ +"nodes": [ +{ +"id": "0a4e65b7-39be-44eb-8c66-913ebfe8a87a", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1140, +840 +], +"parameters": { +"color": 3, +"width": 215, +"height": 80, +"content": "**Replace password and username for Supabase**" +}, +"typeVersion": 1 +}, +{ +"id": "2cea21fc-f3fe-47b7-a7b6-12acb0bc03ac", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-160, +320 +], +"parameters": { +"color": 7, +"width": 280.2462120317618, +"height": 545.9087885077763, +"content": "### Set up steps\n\n#### Preparation\n1. **Create Accounts**:\n - [N8N](https://n8n.partnerlinks.io/2hr10zpkki6a): For workflow automation.\n - [Supabase](https://supabase.com/): For database hosting and management.\n - [OpenAI](https://openai.com/): For building the conversational AI agent.\n2. **Configure Database Connection**:\n - Set up a PostgreSQL database in Supabase.\n - Use appropriate credentials (`username`, `password`, `host`, and `database` name) in your workflow.\n\n#### N8N Workflow\n\nAI agent with tools:\n\n1. **Code Tool**:\n - Execute SQL queries based on user input.\n2. **Database Schema Tool**:\n - Retrieve a list of all tables in the database.\n - Use a predefined SQL query to fetch table definitions, including column names, types, and references.\n3. **Table Definition**:\n - Retrieve a list of columns with types for one table." +}, +"typeVersion": 1 +}, +{ +"id": "eacc0c8c-11d5-44fb-8ff1-10533a233693", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-160, +-200 +], +"parameters": { +"color": 7, +"width": 636.2128494576581, +"height": 497.1532689930921, +"content": "![5min Logo](https://res.cloudinary.com/de9jgixzm/image/upload/v1739773200/Skool%20Assets/ejm3hqnvhgwpnu2fv92s.png)\n## AI Agent to chat with Supabase/PostgreSQL DB\n**Made by [Mark Shcherbakov](https://www.linkedin.com/in/marklowcoding/) from community [5minAI](https://www.skool.com/5minai-2861)**\n\nAccessing and analyzing database data often requires SQL expertise or dedicated reports, which can be time-consuming. This workflow empowers users to interact with a database conversationally through an AI-powered agent. It dynamically generates SQL queries based on user requests, streamlining data retrieval and analysis.\n\nThis workflow integrates OpenAI with a Supabase database, enabling users to interact with their data via an AI agent. The agent can:\n- Retrieve records from the database.\n- Extract and analyze JSON data stored in tables.\n- Provide summaries, aggregations, or specific data points based on user queries.\n\n" +}, +"typeVersion": 1 +}, +{ +"id": "be1559ea-1f75-4e7c-9bdd-3add8d8be70b", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +140, +320 +], +"parameters": { +"color": 7, +"width": 330.5152611046425, +"height": 239.5888196628349, +"content": "### ... or watch set up video [20 min]\n[![Youtube Thumbnail](https://res.cloudinary.com/de9jgixzm/image/upload/v1739773279/Youtube%20Thumbs/Chat%20With%20DB.png)](https://www.youtube.com/watch?v=-GgKzhCNxjk)\n" +}, +"typeVersion": 1 +}, +{ +"id": "4ea87754-dead-49ea-848c-ed86c98e217b", +"name": "When chat message received", +"type": "@n8n/n8n-nodes-langchain.chatTrigger", +"position": [ +720, +400 +], +"webhookId": "6e95bc27-99a6-417c-8bf7-2831d7f7a4be", +"parameters": { +"options": {} +}, +"typeVersion": 1.1 +}, +{ +"id": "c20d6e57-eb41-4682-a7f5-5bb4323df476", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +760, +680 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "zJhr5piyEwVnWtaI", +"name": "OpenAi club" +} +}, +"typeVersion": 1 +}, +{ +"id": "8d3b1faf-643c-4070-996d-a59cb06e1827", +"name": "DB Schema", +"type": "n8n-nodes-base.postgresTool", +"position": [ +1180, +660 +], +"parameters": { +"query": "SELECT table_schema, table_name\nFROM information_schema.tables\nWHERE table_type = 'BASE TABLE' AND table_schema = 'public';", +"options": {}, +"operation": "executeQuery", +"descriptionType": "manual", +"toolDescription": "Get list of all tables in database" +}, +"credentials": { +"postgres": { +"id": "AO9cER6p8uX7V07T", +"name": "Postgres 5minai" +} +}, +"typeVersion": 2.5 +}, +{ +"id": "d9346ade-79d1-44c2-8fa6-b337ad8b0544", +"name": "Get table definition", +"type": "n8n-nodes-base.postgresTool", +"position": [ +1340, +660 +], +"parameters": { +"query": "SELECT \n c.column_name,\n c.data_type,\n c.is_nullable,\n c.column_default,\n tc.constraint_type,\n ccu.table_name AS referenced_table,\n ccu.column_name AS referenced_column\nFROM \n information_schema.columns c\nLEFT JOIN \n information_schema.key_column_usage kcu \n ON c.table_name = kcu.table_name \n AND c.column_name = kcu.column_name\nLEFT JOIN \n information_schema.table_constraints tc \n ON kcu.constraint_name = tc.constraint_name\n AND tc.constraint_type = 'FOREIGN KEY'\nLEFT JOIN\n information_schema.constraint_column_usage ccu\n ON tc.constraint_name = ccu.constraint_name\nWHERE \n c.table_name = '{{ $fromAI(\"table_name\") }}' -- Your table name\n AND c.table_schema = 'public' -- Ensure it's in the right schema\nORDER BY \n c.ordinal_position;\n", +"options": {}, +"operation": "executeQuery", +"descriptionType": "manual", +"toolDescription": "Get table definition to find all columns and types." +}, +"credentials": { +"postgres": { +"id": "AO9cER6p8uX7V07T", +"name": "Postgres 5minai" +} +}, +"typeVersion": 2.5 +}, +{ +"id": "b88a21e0-d2ff-4431-bd84-dfd43edeb5c4", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +960, +280 +], +"parameters": { +"width": 215, +"height": 80, +"content": "**Finetune the prompt of assistant**" +}, +"typeVersion": 1 +}, +{ +"id": "fbe9eb68-5990-485c-820f-08234ea33194", +"name": "AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +940, +400 +], +"parameters": { +"text": "={{ $('When chat message received').item.json.chatInput }}", +"agent": "openAiFunctionsAgent", +"options": { +"systemMessage": "You are DB assistant. You need to run queries in DB aligned with user requests.\n\nRun custom SQL query to aggregate data and response to user.\n\nFetch all data to analyse it for response if needed.\n" +}, +"promptType": "define" +}, +"typeVersion": 1.6 +}, +{ +"id": "7f82d6d9-d7d6-4443-bbaa-c9b276a376e3", +"name": "Run SQL Query", +"type": "n8n-nodes-base.postgresTool", +"position": [ +1040, +660 +], +"parameters": { +"query": "{{ $fromAI(\"query\",\"SQL query for PostgreSQL DB in Supabase\") }}", +"options": {}, +"operation": "executeQuery", +"descriptionType": "manual", +"toolDescription": "Run custom SQL queries using knowledge about Output structure to provide needed response for user request.\nUse ->> operator to extract JSON data." +}, +"credentials": { +"postgres": { +"id": "AO9cER6p8uX7V07T", +"name": "Postgres 5minai" +} +}, +"typeVersion": 2.5 +} +], +"pinData": {}, +"connections": { +"DB Schema": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Run SQL Query": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Get table definition": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"When chat message received": { +"main": [ +[ +{ +"node": "AI Agent", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/AI Agent to chat with you Search Console Data, using OpenAI and Postgres.txt b/AI Agent to chat with you Search Console Data, using OpenAI and Postgres.txt new file mode 100644 index 0000000..192b795 --- /dev/null +++ b/AI Agent to chat with you Search Console Data, using OpenAI and Postgres.txt @@ -0,0 +1,827 @@ +{ +"id": "PoiRk5w0xd1ysq4U", +"meta": { +"instanceId": "b9faf72fe0d7c3be94b3ebff0778790b50b135c336412d28fd4fca2cbbf8d1f5", +"templateCredsSetupCompleted": true +}, +"name": "AI Agent to chat with you Search Console Data, using OpenAI and Postgres", +"tags": [], +"nodes": [ +{ +"id": "9ee6710b-19b7-4bfd-ac2d-0fe1e2561f1d", +"name": "Postgres Chat Memory", +"type": "@n8n/n8n-nodes-langchain.memoryPostgresChat", +"position": [ +1796, +220 +], +"parameters": { +"tableName": "insights_chat_histories" +}, +"credentials": { +"postgres": { +"id": "", +"name": "Postgres" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "eb9f07e9-ded1-485c-9bf3-cf223458384a", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +1356, +240 +], +"parameters": { +"model": "gpt-4o", +"options": { +"maxTokens": 16000 +} +}, +"credentials": { +"openAiApi": { +"id": "", +"name": "OpenAi" +} +}, +"typeVersion": 1 +}, +{ +"id": "1d3d6fb7-a171-4590-be42-df7eb0c208ed", +"name": "Set fields", +"type": "n8n-nodes-base.set", +"position": [ +940, +-20 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "9f47b322-e42f-42d7-93eb-a57d22adb849", +"name": "chatInput", +"type": "string", +"value": "={{ $json.body?.chatInput || $json.chatInput }}" +}, +{ +"id": "73ec4dd0-e986-4f60-9dca-6aad2f86bdeb", +"name": "sessionId", +"type": "string", +"value": "={{ $json.body?.sessionId || $json.sessionId }}" +}, +{ +"id": "4b688c46-b60f-4f0a-83d8-e283f2d7055c", +"name": "date_message", +"type": "string", +"value": "={{ $now.format('yyyy-MM-dd') }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "92dc5e8b-5140-49be-8713-5749b7e2d46b", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +407.32142857142867, +-320 +], +"parameters": { +"color": 7, +"width": 347.9910714285712, +"height": 516.8973214285712, +"content": "## Webhook - ChatInput\n\nThis webhook serves as the endpoint for receiving `ChatInput` data. Ensure that you include:\n- `chatInput` – the content you wish to send (😉)\n- `sessionId` – a unique identifier for the session\n\nIf you're using an interface such as **Open WebUI**, the `sessionId` will be generated automatically." +}, +"typeVersion": 1 +}, +{ +"id": "ca9f3732-9b62-4f44-b970-77d5d470ec76", +"name": "Webhook - ChatInput", +"type": "n8n-nodes-base.webhook", +"position": [ +500, +-20 +], +"webhookId": "a6820b65-76cf-402b-a934-0f836dee6ba0", +"parameters": { +"path": "a6820b65-76cf-402b-a934-0f836dee6ba0/chat", +"options": {}, +"httpMethod": "POST", +"responseMode": "responseNode", +"authentication": "basicAuth" +}, +"credentials": { +"httpBasicAuth": { +"id": "", +"name": "basic-auth" +} +}, +"typeVersion": 2 +}, +{ +"id": "9d684873-6dfe-4709-928d-293b187dfb30", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +820, +-320 +], +"parameters": { +"color": 7, +"width": 347.9910714285712, +"height": 516.8973214285712, +"content": "## Set fields\n\nThis node sets three fields:\n- `chatInput`: retrieved from the previous webhook node\n- `sessionId`: retrieved from the previous webhook node\n- `date_message`: formatted within this node. This will be used later to help the AI agent determine the date range for retrieving Search Console data." +}, +"typeVersion": 1 +}, +{ +"id": "8750215a-1e33-4ac8-a6da-95efa8ffed65", +"name": "Respond to Webhook", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +2600, +-20 +], +"parameters": { +"options": {} +}, +"typeVersion": 1.1 +}, +{ +"id": "1b879496-5c0f-4bd5-b4cb-18df2662aef2", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1240, +-320 +], +"parameters": { +"color": 7, +"width": 1154.2857142857138, +"height": 516.8973214285712, +"content": "## AI Agent - Tools Agent\n\nThis AI Agent is configured with a system prompt that instructs it to:\n- On the first user message, **retrieve available Search Console properties** and offer the user the option to **fetch data from these properties**\n- Based on the user’s natural language input, **construct an API call** to the selected Search Console property and retrieve the requested data\n- Present the data in a **markdown-formatted table**\n\nThe AI Agent has a friendly tone and is designed to **confirm the user’s data requirements accurately** before executing any API requests.\n" +}, +"typeVersion": 1 +}, +{ +"id": "c44c6402-9ddd-4a7b-bc5a-b6c3679a3f68", +"name": "Call Search Console Tool", +"type": "@n8n/n8n-nodes-langchain.toolWorkflow", +"position": [ +2196, +220 +], +"parameters": { +"name": "SearchConsoleRequestTool", +"workflowId": { +"__rl": true, +"mode": "list", +"value": "PoiRk5w0xd1ysq4U", +"cachedResultName": "My workflow 10" +}, +"description": "Call this tool when you need to get the website_list or custom_insights", +"jsonSchemaExample": "" +}, +"typeVersion": 1.2 +}, +{ +"id": "b1701a89-c5b3-47fb-99d5-4896a6d5c7a2", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1234, +220 +], +"parameters": { +"color": 6, +"width": 328.9664285714292, +"height": 468.13107142857154, +"content": "\n\n\n\n\n\n\n\n\n\n\n### AI Agent Sub-node - OpenAI Chat Model\n\nThis sub-node utilizes the selected **OpenAI Chat Model**. You can replace it with any LLM that **supports tool calling**.\n\n### ⚠️ Choose Your Model\nIn this template, the **default model is `gpt-4o`**, a **costly option**. If you'd like a more **affordable alternative**, select `gpt4-o-mini`, though note that responses may occasionally be of slightly lower quality compared to `gpt-4o`." +}, +"typeVersion": 1 +}, +{ +"id": "cd1a7cec-5845-47b1-a2c8-d3b458a02eb0", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1656, +220 +], +"parameters": { +"color": 6, +"width": 328.9664285714292, +"height": 468.13107142857154, +"content": "\n\n\n\n\n\n\n\n\n\n\n### AI Agent Sub-node - Postgres Chat Memory\n\nConnect your **Postgres credentials** and specify a **table name** to store the chat history. In this template, the default table name is `insights_chat_histories`, and the **context window length is set to 5**.\n\n**👋 Tip:** If you don’t have a Postgres database, you can quickly **set one up with [Supabase](https://supabase.com/)**.\n" +}, +"typeVersion": 1 +}, +{ +"id": "290a07d1-c7ed-434d-9851-2a2dcdd35bdf", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2076, +220 +], +"parameters": { +"color": 6, +"width": 328.9664285714292, +"height": 468.13107142857154, +"content": "\n\n\n\n\n\n\n\n\n\n\n### AI Agent Sub-node - Call Search Console Tool\n\nThis **tool is used by the AI Agent** to:\n- Retrieve the **list of accessible properties in Search Console**\n- **Fetch Search Console data** based on the user’s natural language request\n\n" +}, +"typeVersion": 1 +}, +{ +"id": "07805c90-7ba5-44d0-b6eb-5a65efb0f8be", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2480, +-320 +], +"parameters": { +"color": 7, +"width": 347.9910714285712, +"height": 516.8973214285712, +"content": "## Respond to Webhook\n\nThis node is used to send a response back to the user.\n\n**👋 Tip:** `intermediateSteps` are configured, allowing you to use raw data fetched from Search Console to **create charts or other visualizations** if desired.\n" +}, +"typeVersion": 1 +}, +{ +"id": "9a927a40-45e4-4fd5-ab3e-b77578469f82", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +400, +800 +], +"parameters": { +"color": 7, +"width": 370.3910714285712, +"height": 492.3973214285712, +"content": "## Tool Call Trigger\n\nThis **node is triggered when the AI Agent needs to retrieve the `website_list`** (accessible Search Console properties) or **`custom_insights`** based on user data.\n" +}, +"typeVersion": 1 +}, +{ +"id": "c54a4653-0f09-46b0-bd20-68919b96e154", +"name": "Tool calling", +"type": "n8n-nodes-base.executeWorkflowTrigger", +"position": [ +500, +1080 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "cc7303ee-1afa-4859-83e7-3af0e963a0f1", +"name": "Switch", +"type": "n8n-nodes-base.switch", +"position": [ +1300, +1080 +], +"parameters": { +"rules": { +"values": [ +{ +"outputKey": "custom_insights", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "a30fe6a6-7d0a-4f14-8492-ae021ddc8ec6", +"operator": { +"type": "string", +"operation": "contains" +}, +"leftValue": "={{ $json.request_type }}", +"rightValue": "custom_insights" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "website_list", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "1b7d6039-6474-4a73-b157-584743a9d7f0", +"operator": { +"type": "string", +"operation": "contains" +}, +"leftValue": "={{$json.request_type}}", +"rightValue": "website_list" +} +] +}, +"renameOutput": true +} +] +}, +"options": {} +}, +"typeVersion": 3.2 +}, +{ +"id": "6860ff98-4050-4f64-b8c1-a153e3388df0", +"name": "Set fields - Consruct API CALL", +"type": "n8n-nodes-base.set", +"position": [ +920, +1080 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "06373437-8288-4171-9f98-e8a417220dd4", +"name": "request_type", +"type": "string", +"value": "={{ $json.query.parseJson().request_type }}" +}, +{ +"id": "da45c0c5-05f6-4107-81aa-8c08c972d9bf", +"name": "start_date", +"type": "string", +"value": "={{ $json.query.parseJson().startDate }}" +}, +{ +"id": "59d55034-c612-43d7-9700-4cacdb630ec2", +"name": "end_date", +"type": "string", +"value": "={{ $json.query.parseJson().endDate }}" +}, +{ +"id": "4c2478c0-7f96-4d3d-a632-089307dc989e", +"name": "dimensions", +"type": "string", +"value": "={{ $json.query.parseJson().dimensions }}" +}, +{ +"id": "eceefbf9-44e5-4617-96ea-58aca2a29618", +"name": "rowLimit", +"type": "number", +"value": "={{ $json.query.parseJson().rowLimit }}" +}, +{ +"id": "4e18386e-8548-4385-b620-43efbb11cd63", +"name": "startRow", +"type": "number", +"value": "={{ $json.query.parseJson().startRow}}" +}, +{ +"id": "a9323a7b-08b4-4015-b3d7-632bcdf56f4e", +"name": "property", +"type": "string", +"value": "={{ encodeURIComponent($json.query.parseJson().property) }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "0a2dfb28-17ee-477f-b9ea-f1d8e05e3745", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +820, +800 +], +"parameters": { +"color": 7, +"width": 370.3910714285712, +"height": 492.3973214285712, +"content": "## Set Fields - Construct API Call\n\nThis node configures fields based on the JSON sent by the AI agent:\n- The `request_type` field determines the route: `website_list` (to retrieve the list of websites) or `custom_insights` (to get insights from Search Console)\n- Additional fields are set to construct the API call, following the **[Search Console API Documentation](https://developers.google.com/webmaster-tools/v1/searchanalytics/query?hl=en)**\n" +}, +"typeVersion": 1 +}, +{ +"id": "e6ef5c28-01e4-4a0b-9081-b62ec28be635", +"name": "Set fields - Create searchConsoleDataArray", +"type": "n8n-nodes-base.set", +"position": [ +2180, +980 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "2cffd36f-72bd-4535-8427-a88028ea0c4c", +"name": "searchConsoleData", +"type": "array", +"value": "={{ $json.rows }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "abc80061-a794-4e1d-a055-bd88ea5c93eb", +"name": "Set fields - Create searchConsoleDataArray 2", +"type": "n8n-nodes-base.set", +"position": [ +2180, +1340 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "2cffd36f-72bd-4535-8427-a88028ea0c4c", +"name": "searchConsoleData", +"type": "array", +"value": "={{ $json.siteEntry }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "24981eea-980e-4e07-9036-d0042c5b2fbe", +"name": "Search Console - Get Custom Insights", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1620, +980 +], +"parameters": { +"url": "=https://www.googleapis.com/webmasters/v3/sites/{{ $json.property }}/searchAnalytics/query", +"method": "POST", +"options": {}, +"jsonBody": "={\n \"startDate\": \"{{ $json.start_date }}\",\n \"endDate\": \"{{ $json.end_date }}\",\n \"dimensions\": {{ $json.dimensions }},\n \"rowLimit\": {{ $json.rowLimit }},\n \"startRow\": 0,\n \"dataState\":\"all\"\n}", +"sendBody": true, +"sendQuery": true, +"sendHeaders": true, +"specifyBody": "json", +"authentication": "genericCredentialType", +"genericAuthType": "oAuth2Api", +"queryParameters": { +"parameters": [ +{} +] +}, +"headerParameters": { +"parameters": [ +{ +"name": "Content-Type", +"value": "application/json" +} +] +} +}, +"credentials": { +"oAuth2Api": { +"id": "", +"name": "search-console" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "645ff407-857d-4629-926b-5cfc52cfa8ba", +"name": "Sticky Note9", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1520, +800 +], +"parameters": { +"color": 7, +"width": 370.3910714285712, +"height": 364.3185243941325, +"content": "## Search Console - Get Custom Insights\n\nThis node **performs the API call to retrieve data from Search Console**.\n" +}, +"typeVersion": 1 +}, +{ +"id": "15aa66e2-f288-4c86-8dad-47e22aa9104f", +"name": "Sticky Note10", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1520, +1180 +], +"parameters": { +"color": 7, +"width": 370.3910714285712, +"height": 334.24982142857124, +"content": "## Search Console - Get List of Properties\n\nThis node **performs the API call to retrieve the list of accessible properties from Search Console**.\n" +}, +"typeVersion": 1 +}, +{ +"id": "cd804a52-833a-451a-8e0c-f640210ee2c4", +"name": "## Search Console - Get List of Properties", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1620, +1340 +], +"parameters": { +"url": "=https://www.googleapis.com/webmasters/v3/sites", +"options": {}, +"sendHeaders": true, +"authentication": "genericCredentialType", +"genericAuthType": "oAuth2Api", +"headerParameters": { +"parameters": [ +{ +"name": "Content-Type", +"value": "application/json" +} +] +} +}, +"credentials": { +"oAuth2Api": { +"id": "", +"name": "search-console" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "3eac4df1-00ac-4262-b520-3a7e218c7e57", +"name": "Sticky Note11", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2040, +800 +], +"parameters": { +"color": 7, +"width": 370.3910714285712, +"height": 725.1298214285712, +"content": "## Set Fields - Create `searchConsoleDataArray`\n\nThese nodes **create an array based on the response from the Search Console API**.\n" +}, +"typeVersion": 1 +}, +{ +"id": "86db5800-a735-4749-a800-63d78908610b", +"name": "Sticky Note12", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2520, +800 +], +"parameters": { +"color": 7, +"width": 370.3910714285712, +"height": 722.6464176100125, +"content": "## Array Aggregation - Response to AI Agent\n\nThese nodes **aggregate the array from the previous** step and send it back to the AI Agent through the field named output as `response`.\n" +}, +"typeVersion": 1 +}, +{ +"id": "aefbacc7-8dfc-4655-bc4d-f0498c823711", +"name": "Array aggregation - response to AI Agent", +"type": "n8n-nodes-base.aggregate", +"position": [ +2640, +980 +], +"parameters": { +"options": {}, +"aggregate": "aggregateAllItemData", +"destinationFieldName": "response" +}, +"typeVersion": 1 +}, +{ +"id": "e5334c72-981c-4375-ae8e-9a3a0457880b", +"name": "Array aggregation - response to AI Agent1", +"type": "n8n-nodes-base.aggregate", +"position": [ +2660, +1340 +], +"parameters": { +"options": {}, +"aggregate": "aggregateAllItemData", +"destinationFieldName": "response" +}, +"typeVersion": 1 +}, +{ +"id": "2e93a798-6c26-4d34-a553-ba01b64ca3fe", +"name": "Sticky Note13", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-398.45627799387194, +-320 +], +"parameters": { +"width": 735.5589746610085, +"height": 1615.4504601771982, +"content": "# AI Agent to Chat with Your Search Console Data\n\nThis **AI Agent enables you to interact with your Search Console data** through a **chat interface**. Each node is **documented within the template**, providing sufficient information for setup and usage. You will also need to **configure Search Console OAuth credentials**.\n\nFollow this **[n8n documentation](https://docs.n8n.io/integrations/builtin/credentials/google/oauth-generic/#configure-your-oauth-consent-screen)** to set up the OAuth credentials.\n\n## Important Notes\n\n### Correctly Configure Scopes for Search Console API Calls\n- It’s essential to **configure the scopes correctly** in your Google Search Console API OAuth2 credentials. Incorrect **configuration can cause issues with the refresh token**, requiring frequent reconnections. Below is the configuration I use to **avoid constant re-authentication**:\n![Search Console API oAuth2 config 1](https://i.imgur.com/vVLM7gG.png)\n![Search Console API oAuth2 config 2](https://i.imgur.com/naT1NaX.png)\n\nOf course, you'll need to add your **client_id** and **client_secret** from the **Google Cloud Platform app** you created to access your Search Console data.\n\n### Configure Authentication for the Webhook\n\nSince the **webhook will be publicly accessible**, don’t forget to **set up authentication**. I’ve used **Basic Auth**, but feel free to **choose the method that best meets your security requirements**.\n\n## 🤩💖 Example of awesome things you can do with this AI Agent\n![Example of chat with this AI Agent](https://i.imgur.com/jbfsYvT.png)\n\n\n" +}, +"typeVersion": 1 +}, +{ +"id": "fa630aa9-3c60-4b27-9477-aaeb79c7f37d", +"name": "AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +1676, +-20 +], +"parameters": { +"text": "=user_message : {{ $json.chatInput }}\ndate_message : {{ $json.date_message }}", +"options": { +"systemMessage": "=Assist users by asking natural, conversational questions to understand their data needs and building a custom JSON API request to retrieve Search Console data. Handle assumptions internally, confirming them with the user in a friendly way. Avoid technical jargon and never imply that the user is directly building an API request.\n\nPre-Step: Retrieve the Website List\nImportant: Initial Action: Before sending your first message to the user, retrieve the list of connected Search Console properties.\n\nTool Call for Website List:\n\nTool name: SearchConsoleRequestTool\nRequest:\n{\n \"request_type\": \"website_list\" // Always include `request_type` in the API call.\n}\nUsage: Use this list to personalize your response in the initial interaction.\nStep-by-Step Guide\nStep 1: Initial Interaction and Introduction\nGreeting:\n\n\"Hi there! I’m here to help you gain valuable insights from your Search Console data. Whether you're interested in a specific time frame, performance breakdown by pages, queries, or other dimensions, I've got you covered.\n\nI can help you retrieve data for these websites:\n\nhttps://example1.com\nhttps://example2.com\nhttps://example3.com\nWhich of these properties would you like to analyze?\"\nStep 2: Handling User Response for Property Selection\nAction: When the user selects a property, use the property URL exactly as listed (e.g., \"https://example.com\") when constructing the API call.\n\nStep 3: Understanding the User's Needs\nAcknowledgment and Setting Defaults:\n\nIf the user expresses a general need (e.g., \"I want the last 3 months of page performance\"), acknowledge their request and set reasonable defaults.\n\nExample Response:\n\n\"Great! I'll gather the top 300 queries from the last 3 months for https://example.com. If you'd like more details or adjustments, just let me know.\"\n\nFollow-up Questions:\n\nConfirming Dimensions: If the user doesn’t specify dimensions, ask:\n\n\"For this analysis, I’ll look at page performance. Does that sound good, or would you like to include other details like queries, devices, or other dimensions?\"\n\nNumber of Results: If the user hasn’t specified the number of results, confirm:\n\n\"I can show you the top 100 results. Let me know if you'd like more or fewer!\"\n\nStep 4: Gathering Specific Inputs (If Necessary)\nAction: If the user provides specific needs, capture and confirm them naturally.\n\nExample Response:\n\n\"Perfect, I’ll pull the data for [specified date range], focusing on [specified dimensions]. Anything else you’d like me to include?\"\n\nImplicit Defaults:\n\nDate Range: Assume \"last 3 months\" if not specified.\nRow Limit: Default to 100, adjustable based on user input.\nStep 5: Confirming Input with the User\nAction: Summarize the request to ensure accuracy.\n\nExample Response:\n\n\"Here’s what I’m preparing: data for https://example.com, covering the last 3 months, focusing on the top 100 queries. Let me know if you’d like to adjust anything!\"\n\nStep 6: Constructing the JSON for Custom Insights\nAction: Build the API call based on the conversation.\n\n{\n \"property\": \"\", // Use the exact property URL.\n \"request_type\": \"custom_insights\",\n \"startDate\": \"\",\n \"endDate\": \"\",\n \"dimensions\": [\"\"], // Array of one or more: \"page\", \"query\", \"searchAppearance\", \"device\", \"country\"\n \"rowLimit\": 300 // Default or user-specified limit.\n}\nStep 7: Presenting the Data\nWhen Retrieving Custom Insights:\n\nImportant: Display all retrieved data in an easy-to-read markdown table format.\nStep 8: Error Handling\nAction: Provide clear, user-friendly error messages when necessary.\n\nExample Response:\n\n\"Hmm, there seems to be an issue retrieving the data. Let’s review what we have or try a different approach.\"\n\nAdditional Notes\nProactive Assistance: Offer suggestions based on user interactions, such as adding dimensions or refining details.\nTone: Maintain a friendly and helpful demeanor throughout the conversation.", +"returnIntermediateSteps": true +}, +"promptType": "define" +}, +"typeVersion": 1.6 +} +], +"active": true, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "abda3766-7d18-46fb-83e7-c2343ff26385", +"connections": { +"Switch": { +"main": [ +[ +{ +"node": "Search Console - Get Custom Insights", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "## Search Console - Get List of Properties", +"type": "main", +"index": 0 +} +] +] +}, +"AI Agent": { +"main": [ +[ +{ +"node": "Respond to Webhook", +"type": "main", +"index": 0 +} +] +] +}, +"Set fields": { +"main": [ +[ +{ +"node": "AI Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Tool calling": { +"main": [ +[ +{ +"node": "Set fields - Consruct API CALL", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Webhook - ChatInput": { +"main": [ +[ +{ +"node": "Set fields", +"type": "main", +"index": 0 +} +] +] +}, +"Postgres Chat Memory": { +"ai_memory": [ +[ +{ +"node": "AI Agent", +"type": "ai_memory", +"index": 0 +} +] +] +}, +"Call Search Console Tool": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Set fields - Consruct API CALL": { +"main": [ +[ +{ +"node": "Switch", +"type": "main", +"index": 0 +} +] +] +}, +"Search Console - Get Custom Insights": { +"main": [ +[ +{ +"node": "Set fields - Create searchConsoleDataArray", +"type": "main", +"index": 0 +} +] +] +}, +"## Search Console - Get List of Properties": { +"main": [ +[ +{ +"node": "Set fields - Create searchConsoleDataArray 2", +"type": "main", +"index": 0 +} +] +] +}, +"Set fields - Create searchConsoleDataArray": { +"main": [ +[ +{ +"node": "Array aggregation - response to AI Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Set fields - Create searchConsoleDataArray 2": { +"main": [ +[ +{ +"node": "Array aggregation - response to AI Agent1", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/AI Agent with Ollama for current weather and wiki.txt b/AI Agent with Ollama for current weather and wiki.txt new file mode 100644 index 0000000..db3aefe --- /dev/null +++ b/AI Agent with Ollama for current weather and wiki.txt @@ -0,0 +1,235 @@ +{ +"meta": { +"instanceId": "558d88703fb65b2d0e44613bc35916258b0f0bf983c5d4730c00c424b77ca36a", +"templateId": "2931", +"templateCredsSetupCompleted": true +}, +"nodes": [ +{ +"id": "100f23d3-cbe9-458a-9ef1-7cc5fcba8f3c", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +640, +540 +], +"parameters": { +"width": 300, +"height": 205, +"content": "### The conversation history(last 20 messages) is stored in a buffer memory" +}, +"typeVersion": 1 +}, +{ +"id": "b48f989f-deb9-479c-b163-03f098d00c9c", +"name": "On new manual Chat Message", +"type": "@n8n/n8n-nodes-langchain.manualChatTrigger", +"position": [ +380, +240 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "add8e8df-6b2a-4cbd-84e7-3b006733ef7d", +"name": "Wikipedia", +"type": "@n8n/n8n-nodes-langchain.toolWikipedia", +"position": [ +1180, +640 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "a97454a8-001d-4986-9cb5-83176229ea70", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +980, +540 +], +"parameters": { +"width": 300, +"height": 205, +"content": "### Tools which agent can use to accomplish the task" +}, +"typeVersion": 1 +}, +{ +"id": "52b57e72-8cc9-4865-9a00-d03b2e7f1b92", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +600, +160 +], +"parameters": { +"width": 422, +"height": 211, +"content": "### Conversational agent will utilise available tools to answer the prompt. " +}, +"typeVersion": 1 +}, +{ +"id": "8f0653ab-376b-40b9-b876-e608defdeb89", +"name": "Window Buffer Memory", +"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow", +"position": [ +740, +600 +], +"parameters": { +"contextWindowLength": 20 +}, +"typeVersion": 1 +}, +{ +"id": "13237945-e143-4f65-b034-785f5ebde5bb", +"name": "AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +680, +240 +], +"parameters": { +"text": "={{ $json.input }}", +"options": { +"systemMessage": "=You are a helpful assistant, with weather tool and wiki tool. find out the latitude and longitude information of a location then use the weather tool for current weather and weather forecast. For general info, use the wiki tool." +}, +"promptType": "define" +}, +"typeVersion": 1.6 +}, +{ +"id": "ee06c0f4-b2de-4257-9735-3ec228f2b794", +"name": "Weather HTTP Request", +"type": "@n8n/n8n-nodes-langchain.toolHttpRequest", +"position": [ +1020, +620 +], +"parameters": { +"url": "https://api.open-meteo.com/v1/forecast", +"sendQuery": true, +"parametersQuery": { +"values": [ +{ +"name": "latitude" +}, +{ +"name": "longitude" +}, +{ +"name": "forecast_days", +"value": "1", +"valueProvider": "fieldValue" +}, +{ +"name": "hourly", +"value": "temperature_2m", +"valueProvider": "fieldValue" +} +] +}, +"toolDescription": "Fetch current temperature for given coordinates." +}, +"notesInFlow": true, +"typeVersion": 1.1 +}, +{ +"id": "3e5608c8-281d-47e0-af9d-77707530fd6b", +"name": "Ollama Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOllama", +"position": [ +520, +620 +], +"parameters": { +"model": "llama3.2:latest", +"options": {} +}, +"credentials": { +"ollamaApi": { +"id": "xHuYe0MDGOs9IpBW", +"name": "Local Ollama service" +} +}, +"typeVersion": 1 +}, +{ +"id": "b3d794f4-37b5-46c8-9d7d-ad1087006ce5", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1040, +140 +], +"parameters": { +"color": 4, +"height": 240, +"content": "### In System Message, add the following.\n\n\"You are a helpful assistant, with weather tool and wiki tool. find out the latitude and longitude information of a location then use the weather tool for current weather and weather forecast. For general info, use the wiki tool.\"" +}, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"Wikipedia": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Ollama Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Weather HTTP Request": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Window Buffer Memory": { +"ai_memory": [ +[ +{ +"node": "AI Agent", +"type": "ai_memory", +"index": 0 +} +] +] +}, +"On new manual Chat Message": { +"main": [ +[ +{ +"node": "AI Agent", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/AI Automated HR Workflow for CV Analysis and Candidate Evaluation.txt b/AI Automated HR Workflow for CV Analysis and Candidate Evaluation.txt new file mode 100644 index 0000000..2002357 --- /dev/null +++ b/AI Automated HR Workflow for CV Analysis and Candidate Evaluation.txt @@ -0,0 +1,670 @@ +{ +"id": "t1P14FvfibKYCh3E", +"meta": { +"instanceId": "a4bfc93e975ca233ac45ed7c9227d84cf5a2329310525917adaf3312e10d5462", +"templateCredsSetupCompleted": true +}, +"name": "HR-focused automation pipeline with AI", +"tags": [], +"nodes": [ +{ +"id": "b1092f93-502c-4af0-962e-2b69311b92a3", +"name": "On form submission", +"type": "n8n-nodes-base.formTrigger", +"position": [ +-520, +-200 +], +"webhookId": "2a87705d-8ba1-41f1-80ef-85f364ce253e", +"parameters": { +"options": {}, +"formTitle": "Send CV", +"formFields": { +"values": [ +{ +"fieldLabel": "Name", +"placeholder": "Name", +"requiredField": true +}, +{ +"fieldType": "email", +"fieldLabel": "Email", +"placeholder": "Email", +"requiredField": true +}, +{ +"fieldType": "file", +"fieldLabel": "CV", +"requiredField": true, +"acceptFileTypes": ".pdf" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "77edfe2a-4c6a-48c8-8dc9-b275491be090", +"name": "Extract from File", +"type": "n8n-nodes-base.extractFromFile", +"position": [ +-160, +-200 +], +"parameters": { +"options": {}, +"operation": "pdf", +"binaryPropertyName": "CV" +}, +"typeVersion": 1 +}, +{ +"id": "ebf2e194-3515-4c0a-8745-790b63bf336f", +"name": "Qualifications", +"type": "@n8n/n8n-nodes-langchain.informationExtractor", +"position": [ +160, +-100 +], +"parameters": { +"text": "={{ $json.text }}", +"options": { +"systemPromptTemplate": "You are an expert extraction algorithm.\nOnly extract relevant information from the text.\nIf you do not know the value of an attribute asked to extract, you may omit the attribute's value." +}, +"attributes": { +"attributes": [ +{ +"name": "Educational qualification", +"required": true, +"description": "Summary of your academic career. Focus on your high school and university studies. Summarize in 100 words maximum and also include your grade if applicable." +}, +{ +"name": "Job History", +"required": true, +"description": "Work history summary. Focus on your most recent work experiences. Summarize in 100 words maximum" +}, +{ +"name": "Skills", +"required": true, +"description": "Extract the candidate’s technical skills. What software and frameworks they are proficient in. Make a bulleted list." +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "4f40404c-1d47-4bde-9b4b-16367cf11e4f", +"name": "Summarization Chain", +"type": "@n8n/n8n-nodes-langchain.chainSummarization", +"position": [ +900, +-220 +], +"parameters": { +"options": { +"summarizationMethodAndPrompts": { +"values": { +"prompt": "=Write a concise summary of the following:\n\nCity: {{ $json.output.city }}\nBirthdate: {{ $json.output.birthdate }}\nEducational qualification: {{ $json.output[\"Educational qualification\"] }}\nJob History: {{ $json.output[\"Job History\"] }}\nSkills: {{ $json.output.Skills }}\n\nUse 100 words or less. Be concise and conversational.", +"combineMapPrompt": "=Write a concise summary of the following:\n\nCity: {{ $json.output.city }}\nBirthdate: {{ $json.output.birthdate }}\nEducational qualification: {{ $json.output[\"Educational qualification\"] }}\nJob History: {{ $json.output[\"Job History\"] }}\nSkills: {{ $json.output.Skills }}\n\nUse 100 words or less. Be concise and conversational." +} +} +} +}, +"typeVersion": 2 +}, +{ +"id": "9f9c5f16-1dc2-4928-aef8-284daeb6be51", +"name": "Merge", +"type": "n8n-nodes-base.merge", +"position": [ +660, +-220 +], +"parameters": { +"mode": "combine", +"options": {}, +"combineBy": "combineAll" +}, +"typeVersion": 3 +}, +{ +"id": "51bd14cc-2c54-4f72-b162-255f7e277aff", +"name": "Profile Wanted", +"type": "n8n-nodes-base.set", +"position": [ +1300, +-220 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "a3d049b0-5a70-4e7b-a6f2-81447da5282a", +"name": "profile_wanted", +"type": "string", +"value": "We are a web agency and we are looking for a full-stack web developer who knows how to use PHP, Python and Javascript. He has experience in the sector and lives in Northern Italy." +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "4a120e5d-b849-4a29-b7f3-12c653552367", +"name": "Google Sheets", +"type": "n8n-nodes-base.googleSheets", +"position": [ +1960, +-220 +], +"parameters": { +"columns": { +"value": { +"CITY": "={{ $('Merge').item.json.output.city }}", +"DATA": "={{ $now.format('dd/LL/yyyy') }}", +"NAME": "={{ $('On form submission').item.json.Nome }}", +"VOTE": "={{ $json.output.vote }}", +"EMAIL": "={{ $('On form submission').item.json.Email }}", +"SKILLS": "={{ $('Merge').item.json.output.Skills }}", +"TELEFONO": "={{ $('Merge').item.json.output.telephone }}", +"SUMMARIZE": "={{ $('Summarization Chain').item.json.response.text }}", +"EDUCATIONAL": "={{ $('Merge').item.json.output[\"Educational qualification\"] }}", +"JOB HISTORY": "={{ $('Merge').item.json.output[\"Job History\"] }}", +"DATA NASCITA": "={{ $('Merge').item.json.output.birthdate }}", +"CONSIDERATION": "={{ $json.output.consideration }}" +}, +"schema": [ +{ +"id": "DATA", +"type": "string", +"display": true, +"required": false, +"displayName": "DATA", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "NAME", +"type": "string", +"display": true, +"required": false, +"displayName": "NAME", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "PHONE", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "PHONE", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "CITY", +"type": "string", +"display": true, +"required": false, +"displayName": "CITY", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "EMAIL", +"type": "string", +"display": true, +"required": false, +"displayName": "EMAIL", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "DATA NASCITA", +"type": "string", +"display": true, +"required": false, +"displayName": "DATA NASCITA", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "EDUCATIONAL", +"type": "string", +"display": true, +"required": false, +"displayName": "EDUCATIONAL", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "JOB HISTORY", +"type": "string", +"display": true, +"required": false, +"displayName": "JOB HISTORY", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "SKILLS", +"type": "string", +"display": true, +"required": false, +"displayName": "SKILLS", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "SUMMARIZE", +"type": "string", +"display": true, +"required": false, +"displayName": "SUMMARIZE", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "VOTE", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "VOTE", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "CONSIDERATION", +"type": "string", +"display": true, +"required": false, +"displayName": "CONSIDERATION", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [], +"attemptToConvertTypes": false, +"convertFieldsToString": false +}, +"options": {}, +"operation": "append", +"sheetName": { +"__rl": true, +"mode": "list", +"value": "gid=0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ssz5RvN1Hr20Q31pnYnbjCLu1MGBvoLttBAjXunMRQE/edit#gid=0", +"cachedResultName": "Foglio1" +}, +"documentId": { +"__rl": true, +"mode": "list", +"value": "1ssz5RvN1Hr20Q31pnYnbjCLu1MGBvoLttBAjXunMRQE", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ssz5RvN1Hr20Q31pnYnbjCLu1MGBvoLttBAjXunMRQE/edit?usp=drivesdk", +"cachedResultName": "Ricerca WebDev" +} +}, +"credentials": { +"googleSheetsOAuth2Api": { +"id": "JYR6a64Qecd6t8Hb", +"name": "Google Sheets account" +} +}, +"typeVersion": 4.5 +}, +{ +"id": "a154d8a5-9f85-45bb-b082-f702c13c3507", +"name": "Structured Output Parser", +"type": "@n8n/n8n-nodes-langchain.outputParserStructured", +"position": [ +1720, +-20 +], +"parameters": { +"schemaType": "manual", +"inputSchema": "{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"vote\": {\n\t\t\t\"type\": \"string\"\n\t\t},\n\t\t\"consideration\": {\n\t\t\t\"type\": \"string\"\n\t\t}\n\t}\n}" +}, +"typeVersion": 1.2 +}, +{ +"id": "037ac851-7885-4b78-ac75-dfa0ebb6003d", +"name": "HR Expert", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +1560, +-220 +], +"parameters": { +"text": "=Profilo ricercato:\n{{ $json.profile_wanted }}\n\nCandidato:\n{{ $('Summarization Chain').item.json.response.text }}", +"messages": { +"messageValues": [ +{ +"message": "Sei un esperto HR e devi capire se il candidato è in linea con il profilo ricercato dall'azienda.\n\nDevi dare un voto da 1 a 10 dove 1 significa che il candidato non è in linea con quanto richiesto mentre 10 significa che è il candidato ideale perchè rispecchia in toto il profilo cercato.\n\nInoltre nel campo \"consideration\" motiva il perchè hai dato quel voto. " +} +] +}, +"promptType": "define", +"hasOutputParser": true +}, +"typeVersion": 1.5 +}, +{ +"id": "ed5744c4-df06-4a01-a103-af4dd470d482", +"name": "Personal Data", +"type": "@n8n/n8n-nodes-langchain.informationExtractor", +"position": [ +160, +-280 +], +"parameters": { +"text": "={{ $json.text }}", +"options": { +"systemPromptTemplate": "You are an expert extraction algorithm.\nOnly extract relevant information from the text.\nIf you do not know the value of an attribute asked to extract, you may omit the attribute's value." +}, +"schemaType": "manual", +"inputSchema": "{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"telephone\": {\n\t\t\t\"type\": \"string\"\n\t\t},\n \"city\": {\n\t\t\t\"type\": \"string\"\n\t\t},\n \"birthdate\": {\n\t\t\t\"type\": \"string\"\n\t\t}\n\t}\n}" +}, +"typeVersion": 1 +}, +{ +"id": "181c1249-b05c-4c35-8cac-5f9738cc1fe6", +"name": "Upload CV", +"type": "n8n-nodes-base.googleDrive", +"position": [ +-160, +-380 +], +"parameters": { +"name": "=CV-{{ $now.format('yyyyLLdd') }}-{{ $json.CV[0].filename }}", +"driveId": { +"__rl": true, +"mode": "list", +"value": "My Drive" +}, +"options": {}, +"folderId": { +"__rl": true, +"mode": "list", +"value": "1tzeSpx4D3EAGXa3Wg-gqGbdaUk6LIZTV", +"cachedResultUrl": "https://drive.google.com/drive/folders/1tzeSpx4D3EAGXa3Wg-gqGbdaUk6LIZTV", +"cachedResultName": "CV" +}, +"inputDataFieldName": "CV" +}, +"credentials": { +"googleDriveOAuth2Api": { +"id": "HEy5EuZkgPZVEa9w", +"name": "Google Drive account" +} +}, +"typeVersion": 3 +}, +{ +"id": "d31ee1c4-e4be-41d9-8f36-e6fb797ced8e", +"name": "OpenAI", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +920, +240 +], +"parameters": { +"model": { +"__rl": true, +"mode": "list", +"value": "gpt-4o-mini" +}, +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "CDX6QM4gLYanh0P4", +"name": "OpenAi account" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "0290cb72-a581-4aff-8b5d-1aa63e0a630f", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-560, +-680 +], +"parameters": { +"color": 3, +"width": 540, +"content": "## HR Expert \nThis workflow automates the process of handling job applications by extracting relevant information from submitted CVs, analyzing the candidate's qualifications against a predefined profile, and storing the results in a Google Sheet" +}, +"typeVersion": 1 +}, +{ +"id": "361084ff-9735-4a56-8988-be573391838b", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-240, +-460 +], +"parameters": { +"width": 300, +"height": 420, +"content": "The CV is uploaded to Google Drive and converted so that it can be processed\n" +}, +"typeVersion": 1 +}, +{ +"id": "4b6f004f-c77b-4522-99d4-737a68f6cfac", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +120, +-380 +], +"parameters": { +"width": 360, +"height": 440, +"content": "The essential information for evaluating the candidate is collected in two different chains" +}, +"typeVersion": 1 +}, +{ +"id": "73e11af9-65e3-4fcd-bb99-8a3f212ce9fb", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +860, +-300 +], +"parameters": { +"width": 320, +"height": 240, +"content": "Summary of relevant information useful for classifying the candidate" +}, +"typeVersion": 1 +}, +{ +"id": "606711d1-8e6d-44b3-91ac-c047d8a4054f", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1240, +-300 +], +"parameters": { +"width": 220, +"height": 240, +"content": "Characteristics of the profile sought by the company that intends to hire the candidate" +}, +"typeVersion": 1 +}, +{ +"id": "89c3210c-c599-41dc-97a3-bf8df2beb751", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1500, +-300 +], +"parameters": { +"width": 360, +"height": 240, +"content": "Candidate evaluation with vote and considerations of the HR agent relating the profile sought with the candidate's skills" +}, +"typeVersion": 1 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "594728c0-b842-404d-8810-c6f7f3f4631d", +"connections": { +"Merge": { +"main": [ +[ +{ +"node": "Summarization Chain", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI": { +"ai_languageModel": [ +[ +{ +"node": "Qualifications", +"type": "ai_languageModel", +"index": 0 +}, +{ +"node": "Summarization Chain", +"type": "ai_languageModel", +"index": 0 +}, +{ +"node": "HR Expert", +"type": "ai_languageModel", +"index": 0 +}, +{ +"node": "Personal Data", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"HR Expert": { +"main": [ +[ +{ +"node": "Google Sheets", +"type": "main", +"index": 0 +} +] +] +}, +"Upload CV": { +"main": [ +[] +] +}, +"Personal Data": { +"main": [ +[ +{ +"node": "Merge", +"type": "main", +"index": 0 +} +] +] +}, +"Profile Wanted": { +"main": [ +[ +{ +"node": "HR Expert", +"type": "main", +"index": 0 +} +] +] +}, +"Qualifications": { +"main": [ +[ +{ +"node": "Merge", +"type": "main", +"index": 1 +} +] +] +}, +"Extract from File": { +"main": [ +[ +{ +"node": "Qualifications", +"type": "main", +"index": 0 +}, +{ +"node": "Personal Data", +"type": "main", +"index": 0 +} +] +] +}, +"On form submission": { +"main": [ +[ +{ +"node": "Extract from File", +"type": "main", +"index": 0 +}, +{ +"node": "Upload CV", +"type": "main", +"index": 0 +} +] +] +}, +"Summarization Chain": { +"main": [ +[ +{ +"node": "Profile Wanted", +"type": "main", +"index": 0 +} +] +] +}, +"Structured Output Parser": { +"ai_outputParser": [ +[ +{ +"node": "HR Expert", +"type": "ai_outputParser", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/AI Crew to Automate Fundamental Stock Analysis - Q&A Workflow.txt b/AI Crew to Automate Fundamental Stock Analysis - Q&A Workflow.txt new file mode 100644 index 0000000..d63ef7e --- /dev/null +++ b/AI Crew to Automate Fundamental Stock Analysis - Q&A Workflow.txt @@ -0,0 +1,439 @@ +{ +"id": "tMiRJYDrXzpKysTX", +"meta": { +"instanceId": "2723a3a635131edfcb16103f3d4dbaadf3658e386b4762989cbf49528dccbdbd", +"templateId": "1960" +}, +"name": "Stock Q&A Workflow", +"tags": [], +"nodes": [ +{ +"id": "ec3b86be-4113-4fd5-8365-02adb67693e9", +"name": "Embeddings OpenAI1", +"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi", +"position": [ +1960, +720 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "fOF5kro9BJ6KMQ7n", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "42fd8020-3861-4d0f-a7a2-70e2c35f0bed", +"name": "On new manual Chat Message", +"type": "@n8n/n8n-nodes-langchain.manualChatTrigger", +"disabled": true, +"position": [ +1620, +240 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "a9b48d04-691e-4537-90f8-d7a4aa6153af", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1560, +120 +], +"parameters": { +"color": 6, +"width": 903.0896125323785, +"height": 733.5099670584011, +"content": "## Step 2: Setup the Q&A \n### The incoming message from the webhook is queried from the Supabase Vector Store. The response is provided in the response webhook. " +}, +"typeVersion": 1 +}, +{ +"id": "472b4800-745a-4337-9545-163247f7e9ae", +"name": "Retrieval QA Chain", +"type": "@n8n/n8n-nodes-langchain.chainRetrievalQa", +"position": [ +1880, +240 +], +"parameters": { +"query": "={{ $json.body.input }}" +}, +"typeVersion": 1 +}, +{ +"id": "e58bd82d-abc6-44ed-8e93-ec5436126d66", +"name": "Respond to Webhook", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +2280, +240 +], +"parameters": { +"options": {}, +"respondWith": "text", +"responseBody": "={{ $json.response.text }}" +}, +"typeVersion": 1 +}, +{ +"id": "04bbf01e-8269-47c7-897d-4ea94a1bd1c0", +"name": "Vector Store Retriever", +"type": "@n8n/n8n-nodes-langchain.retrieverVectorStore", +"position": [ +2020, +440 +], +"parameters": { +"topK": 5 +}, +"typeVersion": 1 +}, +{ +"id": "feee6d68-2e0d-4d40-897e-c1d833a13bf2", +"name": "Webhook1", +"type": "n8n-nodes-base.webhook", +"position": [ +1620, +420 +], +"webhookId": "679f4afb-189e-4f04-9dc0-439eec2ec5f1", +"parameters": { +"path": "19f5499a-3083-4783-93a0-e8ed76a9f742", +"options": {}, +"httpMethod": "POST", +"responseMode": "responseNode" +}, +"typeVersion": 1.1 +}, +{ +"id": "1b8d251f-7069-4d7d-b6d6-4bfa683d4ad1", +"name": "When clicking \"Execute Workflow\"", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +280, +260 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "b746a7a4-ed94-4332-bf7b-65aadcf54130", +"name": "Google Drive", +"type": "n8n-nodes-base.googleDrive", +"position": [ +580, +260 +], +"parameters": { +"fileId": { +"__rl": true, +"mode": "list", +"value": "1LZezppYrWpMStr4qJXtoIX-Dwzvgehll", +"cachedResultUrl": "https://drive.google.com/file/d/1LZezppYrWpMStr4qJXtoIX-Dwzvgehll/view?usp=drivesdk", +"cachedResultName": "crowdstrike.pdf" +}, +"options": {}, +"operation": "download" +}, +"credentials": { +"googleDriveOAuth2Api": { +"id": "1tsDIpjUaKbXy0be", +"name": "Google Drive account" +} +}, +"typeVersion": 3 +}, +{ +"id": "83a7d470-f934-436d-ba3f-1ae7c776f5a5", +"name": "Binary to Document", +"type": "@n8n/n8n-nodes-langchain.documentBinaryInputLoader", +"position": [ +860, +480 +], +"parameters": { +"loader": "pdfLoader", +"options": {} +}, +"typeVersion": 1 +}, +{ +"id": "b52b4a90-99a1-49cc-a6f0-7551d6754496", +"name": "Recursive Character Text Splitter", +"type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter", +"position": [ +860, +640 +], +"parameters": { +"options": {}, +"chunkSize": 3000, +"chunkOverlap": 200 +}, +"typeVersion": 1 +}, +{ +"id": "b525e130-2029-4f55-a603-1fdc05a19c17", +"name": "Embeddings OpenAI", +"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi", +"position": [ +1160, +480 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "fOF5kro9BJ6KMQ7n", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "5358c53f-55f9-431d-8956-c6bae7ad25bc", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +540, +120 +], +"parameters": { +"color": 6, +"width": 772.0680602743597, +"height": 732.3675002130781, +"content": "## Step 1: Upserting the PDF\n### Fetch file from Google Drive, split it into chunks and insert into Supabase index\n\n" +}, +"typeVersion": 1 +}, +{ +"id": "fb91e2da-0eeb-47a5-aa49-65bf56986857", +"name": "Qdrant Vector Store", +"type": "@n8n/n8n-nodes-langchain.vectorStoreQdrant", +"position": [ +940, +260 +], +"parameters": { +"mode": "insert", +"options": {}, +"qdrantCollection": { +"__rl": true, +"mode": "id", +"value": "=crowd" +} +}, +"credentials": { +"qdrantApi": { +"id": "U5CpjAgFeXziP3I1", +"name": "QdrantApi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "89e14837-d1fc-4b1e-9ebc-7cf3e7fd9a70", +"name": "Qdrant Vector Store1", +"type": "@n8n/n8n-nodes-langchain.vectorStoreQdrant", +"position": [ +1980, +600 +], +"parameters": { +"qdrantCollection": { +"__rl": true, +"mode": "id", +"value": "={{ $json.body.company }}" +} +}, +"credentials": { +"qdrantApi": { +"id": "U5CpjAgFeXziP3I1", +"name": "QdrantApi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "c619245b-5ea0-4354-974d-21ec6b8efa93", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +1880, +460 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "fOF5kro9BJ6KMQ7n", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "e4aa780d-8069-4308-a61f-82ed876af71a", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-560, +120 +], +"parameters": { +"color": 6, +"width": 710.9124489067698, +"height": 726.4452519516944, +"content": "## Start here: Step-by Step Youtube Tutorial :star:\n\n[![Building an AI Crew to Analyze Financial Data with CrewAI and n8n](https://img.youtube.com/vi/pMvizUx5n1g/sddefault.jpg)](https://www.youtube.com/watch?v=pMvizUx5n1g)\n" +}, +"typeVersion": 1 +} +], +"active": true, +"pinData": {}, +"settings": {}, +"versionId": "463aec94-26a6-436d-8732-fc01d637c6ae", +"connections": { +"Webhook1": { +"main": [ +[ +{ +"node": "Retrieval QA Chain", +"type": "main", +"index": 0 +} +] +] +}, +"Google Drive": { +"main": [ +[ +{ +"node": "Qdrant Vector Store", +"type": "main", +"index": 0 +} +] +] +}, +"Embeddings OpenAI": { +"ai_embedding": [ +[ +{ +"node": "Qdrant Vector Store", +"type": "ai_embedding", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Retrieval QA Chain", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Binary to Document": { +"ai_document": [ +[ +{ +"node": "Qdrant Vector Store", +"type": "ai_document", +"index": 0 +} +] +] +}, +"Embeddings OpenAI1": { +"ai_embedding": [ +[ +{ +"node": "Qdrant Vector Store1", +"type": "ai_embedding", +"index": 0 +} +] +] +}, +"Retrieval QA Chain": { +"main": [ +[ +{ +"node": "Respond to Webhook", +"type": "main", +"index": 0 +} +] +] +}, +"Qdrant Vector Store1": { +"ai_vectorStore": [ +[ +{ +"node": "Vector Store Retriever", +"type": "ai_vectorStore", +"index": 0 +} +] +] +}, +"Vector Store Retriever": { +"ai_retriever": [ +[ +{ +"node": "Retrieval QA Chain", +"type": "ai_retriever", +"index": 0 +} +] +] +}, +"On new manual Chat Message": { +"main": [ +[ +{ +"node": "Retrieval QA Chain", +"type": "main", +"index": 0 +} +] +] +}, +"When clicking \"Execute Workflow\"": { +"main": [ +[ +{ +"node": "Google Drive", +"type": "main", +"index": 0 +} +] +] +}, +"Recursive Character Text Splitter": { +"ai_textSplitter": [ +[ +{ +"node": "Binary to Document", +"type": "ai_textSplitter", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/AI Customer feedback sentiment analysis.txt b/AI Customer feedback sentiment analysis.txt new file mode 100644 index 0000000..850b0b9 --- /dev/null +++ b/AI Customer feedback sentiment analysis.txt @@ -0,0 +1,330 @@ +{ +"meta": { +"instanceId": "82a17fa4a0b8e81bf77e5ab999d980f392150f2a9541fde626dc5f74857b1f54" +}, +"nodes": [ +{ +"id": "4ea39a4f-d8c1-438f-9738-bfbb906a3d7a", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1200, +1020 +], +"parameters": { +"width": 253, +"height": 342, +"content": "## Send customer feedback to OpenAI for sentiment analysis" +}, +"typeVersion": 1 +}, +{ +"id": "6962ea41-7d15-4932-919f-21ac94fa1269", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1960, +1180 +], +"parameters": { +"width": 253, +"height": 342, +"content": "## Add new feedback to google sheets" +}, +"typeVersion": 1 +}, +{ +"id": "4c8a8984-2d8e-4139-866b-6f3536aced07", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +800, +1600 +], +"parameters": { +"width": 1407, +"height": 254, +"content": "## Instructions\n1. Connect Google sheets\n2. Connect your OpenAi account (api key + org Id)\n3. Create a customer feedback form, use an existing one or use the one below as example. \nAll set!\n\n\n- Here is the example google sheet being used in this workflow: https://docs.google.com/spreadsheets/d/1omWdRbiT6z6GNZ6JClu9gEsRhPQ6J0EJ2yXyFH9Zng4/edit?usp=sharing. You can download it to your account." +}, +"typeVersion": 1 +}, +{ +"id": "d43a9574-626d-4817-87ba-d99bdd6f41dc", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +800, +1160 +], +"parameters": { +"width": 253, +"height": 342, +"content": "## Feedback form is submitted" +}, +"typeVersion": 1 +}, +{ +"id": "76dab2dc-935f-416e-91aa-5a1b7017ec1b", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1600, +1180 +], +"parameters": { +"width": 253, +"height": 342, +"content": "## Merge form data and OpenAI result" +}, +"typeVersion": 1 +}, +{ +"id": "9772eac1-8df2-4305-9b2c-265d3c5a9a4a", +"name": "Add customer feedback to Google Sheets", +"type": "n8n-nodes-base.googleSheets", +"position": [ +2020, +1320 +], +"parameters": { +"columns": { +"value": { +"Category": "={{ $json['What is your feedback about?'] }}", +"Sentiment": "={{ $json.text }}", +"Timestamp": "={{ $json.submittedAt }}", +"Entered by": "=Form", +"Customer Name": "={{ $json.Name }}", +"Customer contact": "={{ $json['How do we get in touch with you?'] }}", +"Customer Feedback": "={{ $json['Your feedback'] }}" +}, +"schema": [ +{ +"id": "Timestamp", +"type": "string", +"display": true, +"required": false, +"displayName": "Timestamp", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Category", +"type": "string", +"display": true, +"required": false, +"displayName": "Category", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Customer Feedback", +"type": "string", +"display": true, +"required": false, +"displayName": "Customer Feedback", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Customer Name", +"type": "string", +"display": true, +"required": false, +"displayName": "Customer Name", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Customer contact", +"type": "string", +"display": true, +"required": false, +"displayName": "Customer contact", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Entered by", +"type": "string", +"display": true, +"required": false, +"displayName": "Entered by", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Urgent?", +"type": "string", +"display": true, +"required": false, +"displayName": "Urgent?", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Sentiment", +"type": "string", +"display": true, +"required": false, +"displayName": "Sentiment", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [] +}, +"options": {}, +"operation": "append", +"sheetName": { +"__rl": true, +"mode": "list", +"value": "gid=0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1omWdRbiT6z6GNZ6JClu9gEsRhPQ6J0EJ2yXyFH9Zng4/edit#gid=0", +"cachedResultName": "Sheet1" +}, +"documentId": { +"__rl": true, +"mode": "list", +"value": "1omWdRbiT6z6GNZ6JClu9gEsRhPQ6J0EJ2yXyFH9Zng4", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1omWdRbiT6z6GNZ6JClu9gEsRhPQ6J0EJ2yXyFH9Zng4/edit?usp=drivesdk", +"cachedResultName": "CustomerFeedback" +} +}, +"credentials": { +"googleSheetsOAuth2Api": { +"id": "3", +"name": "Google Sheets account" +} +}, +"typeVersion": 4.1 +}, +{ +"id": "12084971-c81b-4a0e-814e-120867562642", +"name": "Merge sentiment with form content", +"type": "n8n-nodes-base.merge", +"position": [ +1680, +1320 +], +"parameters": { +"mode": "combine", +"options": {}, +"combinationMode": "multiplex" +}, +"typeVersion": 2.1 +}, +{ +"id": "235edf5b-7724-4712-8dc5-d8327a0620b8", +"name": "Classify feedback with OpenAI", +"type": "n8n-nodes-base.openAi", +"position": [ +1280, +1180 +], +"parameters": { +"prompt": "=Classify the sentiment in the following customer feedback: {{ $json['Your feedback'] }}", +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "s2iucY0IctjYNbrb", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "af4b22aa-0925-40b1-a9ac-298f9745a98e", +"name": "Submit form with customer feedback", +"type": "n8n-nodes-base.formTrigger", +"position": [ +860, +1340 +], +"webhookId": "e7bf682e-48e8-40de-9815-cd180cdd1480", +"parameters": { +"options": { +"formSubmittedText": "Your response has been recorded" +}, +"formTitle": "Customer Feedback", +"formFields": { +"values": [ +{ +"fieldLabel": "Name", +"requiredField": true +}, +{ +"fieldType": "dropdown", +"fieldLabel": "What is your feedback about?", +"fieldOptions": { +"values": [ +{ +"option": "Product" +}, +{ +"option": "Service" +}, +{ +"option": "Other" +} +] +}, +"requiredField": true +}, +{ +"fieldType": "textarea", +"fieldLabel": "Your feedback", +"requiredField": true +}, +{ +"fieldLabel": "How do we get in touch with you?" +} +] +}, +"formDescription": "Please give feedback about our company orproducts." +}, +"typeVersion": 1 +} +], +"connections": { +"Classify feedback with OpenAI": { +"main": [ +[ +{ +"node": "Merge sentiment with form content", +"type": "main", +"index": 0 +} +] +] +}, +"Merge sentiment with form content": { +"main": [ +[ +{ +"node": "Add customer feedback to Google Sheets", +"type": "main", +"index": 0 +} +] +] +}, +"Submit form with customer feedback": { +"main": [ +[ +{ +"node": "Classify feedback with OpenAI", +"type": "main", +"index": 0 +}, +{ +"node": "Merge sentiment with form content", +"type": "main", +"index": 1 +} +] +] +} +} +} \ No newline at end of file diff --git a/AI Data Extraction with Dynamic Prompts and Airtable.txt b/AI Data Extraction with Dynamic Prompts and Airtable.txt new file mode 100644 index 0000000..004a0e9 --- /dev/null +++ b/AI Data Extraction with Dynamic Prompts and Airtable.txt @@ -0,0 +1,1623 @@ +{ +"nodes": [ +{ +"id": "36816ae7-414a-482e-8a50-021885237273", +"name": "Event Type", +"type": "n8n-nodes-base.switch", +"position": [ +-220, +-140 +], +"parameters": { +"rules": { +"values": [ +{ +"outputKey": "row.updated", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "2162daf8-d23d-4b8f-8257-bdfc5400a3a8", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.event_type }}", +"rightValue": "row.updated" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "field.created", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "48e112f6-afe8-40bf-b673-b37446934a62", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.event_type }}", +"rightValue": "field.created" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "field.updated", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "5aa258cd-15c2-4156-a32d-afeed662a38e", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.event_type }}", +"rightValue": "field.updated" +} +] +}, +"renameOutput": true +} +] +}, +"options": {} +}, +"typeVersion": 3.2 +}, +{ +"id": "920ca6d8-7a6e-4482-b003-fa643f550a85", +"name": "Get Prompt Fields", +"type": "n8n-nodes-base.code", +"position": [ +-900, +-140 +], +"parameters": { +"jsCode": "const fields = $input.first().json.fields\n .filter(item => item.description)\n .map((item, idx) => ({\n id: item.id,\n order: idx,\n name: item.name,\n type: item.type,\n description: item.description,\n }));\n\nreturn { json: { fields } };" +}, +"typeVersion": 2 +}, +{ +"id": "3b73b2f5-9081-4633-911f-ef3041600a00", +"name": "Get File Data", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1220, +320 +], +"parameters": { +"url": "={{ $json.File[0].url }}", +"options": {} +}, +"typeVersion": 4.2 +}, +{ +"id": "e96edca8-9e8b-4ca4-bef9-dae673d3aba4", +"name": "Extract from File", +"type": "n8n-nodes-base.extractFromFile", +"position": [ +1380, +320 +], +"parameters": { +"options": {}, +"operation": "pdf" +}, +"typeVersion": 1 +}, +{ +"id": "b5c2b87b-5756-4810-84c9-34ea420bdcef", +"name": "Get Result", +"type": "n8n-nodes-base.set", +"position": [ +2000, +380 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "63d7c52e-d5bf-4f4c-9e37-1d5feaea20f4", +"name": "id", +"type": "string", +"value": "={{ $('Row Reference').item.json.id }}" +}, +{ +"id": "3ad72567-1d17-4910-b916-4c34a43b1060", +"name": "={{ $('Event Ref').first().json.field.name }}", +"type": "string", +"value": "={{ $json.text.trim() }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "a5cb0510-620b-469d-bf66-26ab64d6f88f", +"name": "Loop Over Items", +"type": "n8n-nodes-base.splitInBatches", +"position": [ +800, +220 +], +"parameters": { +"options": {} +}, +"typeVersion": 3 +}, +{ +"id": "20e24946-59d8-4b19-bfab-eebb02f7e46d", +"name": "Row Reference", +"type": "n8n-nodes-base.noOp", +"position": [ +980, +320 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "4090c53e-e635-4421-ab2b-475bfc62cea4", +"name": "Generate Field Value", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +1540, +320 +], +"parameters": { +"text": "=\n{{ $json.text }}\n\n\nData to extract: {{ $('Event Ref').first().json.field.description }}\noutput format is: {{ $('Event Ref').first().json.field.type }}", +"messages": { +"messageValues": [ +{ +"message": "=You assist the user in extracting the required data from the given file.\n* Keep you answer short.\n* If you cannot extract the requested data, give you response as \"n/a\"." +} +] +}, +"promptType": "define" +}, +"typeVersion": 1.5 +}, +{ +"id": "582d4008-4871-4798-bc24-abf774ad29b5", +"name": "Fields to Update", +"type": "n8n-nodes-base.code", +"position": [ +1560, +-300 +], +"parameters": { +"jsCode": "const row = $('Row Ref').first().json;\nconst fields = $('Get Prompt Fields').first().json.fields;\nconst missingFields = fields\n .filter(field => field.description && !row[field.name]);\n\nreturn missingFields;" +}, +"typeVersion": 2 +}, +{ +"id": "051c6a99-cec3-42df-9de7-47cb69b51682", +"name": "Loop Over Items1", +"type": "n8n-nodes-base.splitInBatches", +"position": [ +820, +-420 +], +"parameters": { +"options": {} +}, +"typeVersion": 3 +}, +{ +"id": "f559c8ff-2ee5-478d-84ee-6b0ca2fe2050", +"name": "Row Ref", +"type": "n8n-nodes-base.noOp", +"position": [ +1000, +-300 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "7b82cc73-67cb-46d7-a1d4-19712c86890a", +"name": "Get File Data1", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1240, +-300 +], +"parameters": { +"url": "={{ $('Row Ref').item.json.File[0].url }}", +"options": {} +}, +"typeVersion": 4.2 +}, +{ +"id": "7ef1556c-96a3-4988-982d-ec8c5fba4601", +"name": "Extract from File1", +"type": "n8n-nodes-base.extractFromFile", +"position": [ +1400, +-300 +], +"parameters": { +"options": {}, +"operation": "pdf" +}, +"typeVersion": 1 +}, +{ +"id": "9916f1c1-f413-4996-ad45-380a899b4a88", +"name": "Get Result1", +"type": "n8n-nodes-base.set", +"position": [ +2120, +-260 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "e376ba60-8692-4962-9af7-466b6a3f44a2", +"name": "={{ $('Fields to Update').item.json.name }}", +"type": "string", +"value": "={{ $json.text.trim() }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "f62f612d-c288-4062-ab3c-dbc24c9b4b38", +"name": "Generate Field Value1", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +1720, +-300 +], +"parameters": { +"text": "=\n{{ $('Extract from File1').first().json.text }}\n\n\nData to extract: {{ $json.description }}\noutput format is: {{ $json.type }}", +"messages": { +"messageValues": [ +{ +"message": "=You assist the user in extracting the required data from the given file.\n* Keep you answer short.\n* If you cannot extract the requested data, give you response as \"n/a\" followed by \"(reason)\" where reason is replaced with reason why data could not be extracted." +} +] +}, +"promptType": "define" +}, +"typeVersion": 1.5 +}, +{ +"id": "615f7436-f280-4033-8ec8-a34f1bd78075", +"name": "Filter Valid Rows", +"type": "n8n-nodes-base.filter", +"position": [ +520, +-420 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "7ad58f0b-0354-49a9-ab2f-557652d7b416", +"operator": { +"type": "string", +"operation": "notEmpty", +"singleValue": true +}, +"leftValue": "={{ $json.File[0].url }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "281b9fb0-305c-4a0c-b73b-82b6ba876d12", +"name": "Filter Valid Fields", +"type": "n8n-nodes-base.filter", +"position": [ +340, +220 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "5b4a7393-788c-42dc-ac1f-e76f833f8534", +"operator": { +"type": "string", +"operation": "notEmpty", +"singleValue": true +}, +"leftValue": "={{ $json.field.description }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "dd0fa792-791f-4d31-a7e8-9b72a25b6a07", +"name": "Event Ref", +"type": "n8n-nodes-base.noOp", +"position": [ +160, +220 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "ca1174b3-da18-4d3c-86ef-3028cd5b12a7", +"name": "Event Ref1", +"type": "n8n-nodes-base.noOp", +"position": [ +160, +-420 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "8800b355-0fa8-4297-b13b-d3da8a01c3b7", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1180, +-340 +], +"parameters": { +"color": 7, +"width": 480, +"height": 440, +"content": "### 1. Get Table Schema\n[Learn more about the Airtable node](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.airtable/)\n\nFor this operation, we'll use the handy Airtable node. I recommend getting familiar with this node for all your Airtable needs!\n" +}, +"typeVersion": 1 +}, +{ +"id": "a90876d3-8a93-4d90-9e2a-f23de452259d", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-260, +-440 +], +"parameters": { +"color": 5, +"width": 330, +"height": 80, +"content": "### 2a. Updates Minimal Number of Rows\nThis branch updates only the rows impacted." +}, +"typeVersion": 1 +}, +{ +"id": "319adf97-8b14-4069-b4cc-594a6ea479c1", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-320, +140 +], +"parameters": { +"color": 5, +"width": 390, +"height": 120, +"content": "### 2b. Update Every Row under the Field\nThis branch updates all applicable rows under field when the field/column is created or changed. Watch out - if you have 1000s of rows, this could take a while!" +}, +"typeVersion": 1 +}, +{ +"id": "42a60c8c-476f-4930-bac5-4d36a7185f4f", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-2240, +-1000 +], +"parameters": { +"width": 520, +"height": 1120, +"content": "## Try It Out!\n### This n8n template powers a \"dynamic\" or \"user-defined\" prompts with PDF workflow pattern for a [Airtable](https://airtable.com/invite/r/cKzxFYVc) table. Simply put, it allows users to populate a spreadsheet using prompts without touching the underlying template.\n\n**Check out the video demo I did for n8n Studio**: https://www.youtube.com/watch?v=_fNAD1u8BZw\n\n**Check out the example Airtable here:** https://airtable.com/appAyH3GCBJ56cfXl/shrXzR1Tj99kuQbyL\n\nThis template is intended to be used as a webhook source for Airtable. **Looking for a Baserow version? [Click here](https://n8n.io/workflows/2780-ai-data-extraction-with-dynamic-prompts-and-baserow)**\n\n## How it works\n* Each Airtable.io tables offers integration feature whereby changes to the table can be sent as events to any accessible webhook. This allows for a reactive trigger pattern which makes this type of workflow possible. For our usecase, we capture the vents of `row_updated`, `field_created` and `field_updated`.\n* Next, we'll need an \"input\" column in our Airtable.io table. This column will be where our context lives for evaluating the prompts against. In this example, our \"input\" column name is \"file\" and it's where we'll upload our PDFs. Note, this \"input\" field is human-controlled and never updated from this template.\n* Now for the columns (aka \"fields\" in Airtable). Each field allows us to define a name, type and description and together form the schema. The first 2 are self-explaintory but the \"description\" will be for users to provide their prompts ie. what data should the field to contain.\n* In this template, a webhook trigger waits for when a row or column is updated. The incoming event comes with lots of details such as the table, row and/or column Ids that were impacted.\n* We use this information to fetch the table's schema in order to get the column's descriptions (aka dynamic prompts).\n* For each triggered event, we download our input ie. the PDF and ready it for our AI/LLM. By iterating through the available columns and feeding the dynamic prompts, our LLM can run those prompts against the PDF and thus generating a value response for each cell.\n* These values are then collected and used to update the Airtable Record.\n\n## How to use\n* You'll need to publish this workflow and make it accessible to our Airtable instance.\n* you must run the \"Create Airtable Webhooks\" mini-flow to link it to your Airtable.\n* This template is reusable for other Airtables but the webhooks need to be created each time for each table.\n\n### Need Help?\nJoin the [Discord](https://discord.com/invite/XPKeKXeB7d) or ask in the [Forum](https://community.n8n.io/)!\n\nHappy Flowgramming!" +}, +"typeVersion": 1 +}, +{ +"id": "c6d037e9-1bf7-47a7-9c46-940220e0786b", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-680, +-340 +], +"parameters": { +"color": 7, +"width": 760, +"height": 440, +"content": "### 2. Event Router Pattern\n[Learn more about the Switch node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.switch/)\n\nA simple switch node can be used to determine which event to handle. The difference between our row and field events is that row event affect a single row whereas field events affect all rows. \n" +}, +"typeVersion": 1 +}, +{ +"id": "897cec32-3a4c-4a76-bffe-b1456c287b44", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +100, +-620 +], +"parameters": { +"color": 7, +"width": 620, +"height": 400, +"content": "### 3. Filter Only Rows with Valid Input\n[Learn more about the Split Out node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.splitout/)\n\nThis step handles one or more updated rows where \"updated\" means the \"input\" column (ie. \"file\" in our example) for these rows were changed. For each affected row, we'll get the full row to figure out only the columns we need to update - this is an optimisation to avoid redundant work ie. generating values for columns which already have a value." +}, +"typeVersion": 1 +}, +{ +"id": "a5999ca3-4418-42c5-aa1c-fbdfb1c04fef", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2060, +-480 +], +"parameters": { +"color": 7, +"width": 600, +"height": 440, +"content": "### 6. Update the Airtable Record\n[Learn more about the Edit Fields node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.set/)\n\nFinally, we can collect the LLM responses and combine them to build an API request to update our Airtable record - the Id of which we got from initial webhook. After this is done, we can move onto the next row and repeat the process.\n" +}, +"typeVersion": 1 +}, +{ +"id": "38192929-a387-4240-8373-290499b40e5a", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1180, +-580 +], +"parameters": { +"color": 7, +"width": 860, +"height": 580, +"content": "### 5. PDFs, LLMs and Dynamic Prompts? Oh My!\n[Learn more about the Basic LLM node](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.chainllm/)\n\nThis step is where it all comes together! In short, we give our LLM the PDF contents as the context and loop through our dynamic prompts (from the schema we pulled earlier) for our row. At the end, our LLM should have produced a value for each column requested.\n\n**Note**: There's definitely a optimisation which could be done for caching PDFs but it beyond the scope of this demonstration.\n" +}, +"typeVersion": 1 +}, +{ +"id": "19a9b93a-d18f-4ffd-ae93-ed41cf398e90", +"name": "Sticky Note9", +"type": "n8n-nodes-base.stickyNote", +"position": [ +740, +-580 +], +"parameters": { +"color": 7, +"width": 420, +"height": 460, +"content": "### 4. Using an Items Loop\n[Learn more about the Split in Batches node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.splitinbatches/)\n\nA split in batches node is used here to update a row at a time however, this is a preference for user experience - changes are seen in the Airtable quicker.\n" +}, +"typeVersion": 1 +}, +{ +"id": "5407fead-ee7c-47c8-94ed-5b89e74e50e8", +"name": "Sticky Note10", +"type": "n8n-nodes-base.stickyNote", +"position": [ +100, +40 +], +"parameters": { +"color": 7, +"width": 600, +"height": 360, +"content": "### 7. Listing All Applicable Rows Under The Column\n[Learn more about the Filter node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.filter)\n\nTo keep things performant, we can decide to get only rows with inputfield populated as this is required to perform the extraction. This can easily be achieved with Airtable filters." +}, +"typeVersion": 1 +}, +{ +"id": "43b0e330-b79a-4577-b4fc-314e8b790cf7", +"name": "Sticky Note11", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1160, +140 +], +"parameters": { +"color": 7, +"width": 700, +"height": 500, +"content": "### 9. Generating Value using LLM\n[Learn more about the Extract From File node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.extractfromfile/)\n\nPretty much identical to Step 5 but instead of updating every field/column, we only need to generate a value for one. \n" +}, +"typeVersion": 1 +}, +{ +"id": "0665fe56-48d2-4215-8d95-d4c01f9266ed", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +1720, +-140 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "1997fb8b-73eb-4016-bab6-eb8f02fee368", +"name": "Sticky Note12", +"type": "n8n-nodes-base.stickyNote", +"position": [ +720, +40 +], +"parameters": { +"color": 7, +"width": 420, +"height": 460, +"content": "### 8. Using an Items Loop\n[Learn more about the Split in Batches node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.splitinbatches/)\n\nSimilar to Step 4, the Split in Batches node is a preference for user experience - changes are seen in the Airtable quicker.\n" +}, +"typeVersion": 1 +}, +{ +"id": "c2799ded-b742-43a2-80ce-7a0c8f1df96e", +"name": "OpenAI Chat Model1", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +1540, +500 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "e5b42790-fc86-4134-9d04-e6bcad4a5f20", +"name": "Sticky Note13", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1880, +140 +], +"parameters": { +"color": 7, +"width": 500, +"height": 440, +"content": "### 10. Update the Airtable Record\n[Learn more about the Edit Fields node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.set/)\n\nAs with Step 6, the LLM response is used to update the row however only under the field that was created/changed. Once complete, the loop continues and the next row is processed.\n" +}, +"typeVersion": 1 +}, +{ +"id": "b1e98631-a440-4c66-b2d2-8236f6889b65", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-2240, +-1140 +], +"parameters": { +"color": 7, +"width": 300, +"height": 120, +"content": "[![airtable.io](https://res.cloudinary.com/daglih2g8/image/upload/f_auto,q_auto/v1/n8n-workflows/airtable_logo)](https://airtable.com/invite/r/cKzxFYVc)" +}, +"typeVersion": 1 +}, +{ +"id": "9d293b3a-954d-4e3b-8773-b6c3dded9520", +"name": "Get Webhook Payload", +"type": "n8n-nodes-base.httpRequest", +"position": [ +-580, +-140 +], +"parameters": { +"url": "=https://api.airtable.com/v0/bases/{{ $('Airtable Webhook').first().json.body.base.id }}/webhooks/{{ $('Airtable Webhook').first().json.body.webhook.id }}/payloads", +"options": {}, +"authentication": "predefinedCredentialType", +"nodeCredentialType": "airtableTokenApi" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "5f8d919b-14cd-4cb4-8604-731e56cc9402", +"name": "Parse Event", +"type": "n8n-nodes-base.code", +"position": [ +-400, +-140 +], +"parameters": { +"jsCode": "const webhook = $('Airtable Webhook').first().json;\nconst schema = $('Get Prompt Fields').first().json;\nconst { payloads } = $input.first().json;\nif (!payloads.length) return [];\n\nconst event = payloads[payloads.length - 1];\nconst baseId = webhook.body.base.id;\nconst tableId = Object.keys(event.changedTablesById)[0];\nconst table = event.changedTablesById[tableId];\n\nreturn {\n baseId,\n tableId,\n event_type: getEventType(table),\n fieldId: getFieldId(table),\n field: getField(getFieldId(table)),\n rowId: getRecordId(table),\n}\n\nfunction getEventType(changedTableByIdObject) {\n if (changedTableByIdObject['createdFieldsById']) return 'field.created';\n if (changedTableByIdObject['changedFieldsById']) return 'field.updated'\n if (changedTableByIdObject['changedRecordsById']) return 'row.updated';\n return 'unknown';\n}\n\nfunction getFieldId(changedTableByIdObject) {\n const field = changedTableByIdObject.createdFieldsById\n || changedTableByIdObject.changedFieldsById\n || null;\n\n return field ? Object.keys(field)[0] : null;\n}\n\nfunction getField(id) {\n return schema.fields.find(field => field.id === id);\n}\n\nfunction getRecordId(changedTableByIdObject) {\n const record = changedTableByIdObject.changedRecordsById\n || null;\n\n return record ? Object.keys(record)[0] : null;\n}" +}, +"typeVersion": 2 +}, +{ +"id": "9b99d939-94d6-4fef-8b73-58c702503221", +"name": "Get Table Schema", +"type": "n8n-nodes-base.airtable", +"position": [ +-1080, +-140 +], +"parameters": { +"base": { +"__rl": true, +"mode": "id", +"value": "={{ $('Airtable Webhook').item.json.body.base.id }}" +}, +"resource": "base", +"operation": "getSchema" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "c29fc911-a852-46f2-bbb1-5092cc1aaa9d", +"name": "Fetch Records", +"type": "n8n-nodes-base.airtable", +"position": [ +520, +220 +], +"parameters": { +"base": { +"__rl": true, +"mode": "id", +"value": "={{ $json.baseId }}" +}, +"table": { +"__rl": true, +"mode": "id", +"value": "={{ $json.tableId }}" +}, +"options": {}, +"operation": "search", +"filterByFormula": "NOT({File} = \"\")" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "86d3c8d8-709f-4d9d-99bc-5d1b4aeb8603", +"name": "Update Row", +"type": "n8n-nodes-base.airtable", +"position": [ +2180, +380 +], +"parameters": { +"base": { +"__rl": true, +"mode": "id", +"value": "={{ $('Event Ref').first().json.baseId }}" +}, +"table": { +"__rl": true, +"mode": "id", +"value": "={{ $('Event Ref').first().json.tableId }}" +}, +"columns": { +"value": {}, +"schema": [ +{ +"id": "id", +"type": "string", +"display": true, +"removed": false, +"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": "File", +"type": "array", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "File", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Full Name", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Full Name", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Created", +"type": "string", +"display": true, +"removed": false, +"readOnly": true, +"required": false, +"displayName": "Created", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Last Modified", +"type": "string", +"display": true, +"removed": false, +"readOnly": true, +"required": false, +"displayName": "Last Modified", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Address", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Address", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "autoMapInputData", +"matchingColumns": [ +"id" +] +}, +"options": {}, +"operation": "update" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "95d08439-59a2-4e74-bd5a-b71cf079b621", +"name": "Get Row", +"type": "n8n-nodes-base.airtable", +"position": [ +340, +-420 +], +"parameters": { +"id": "={{ $json.rowId }}", +"base": { +"__rl": true, +"mode": "id", +"value": "={{ $json.baseId }}" +}, +"table": { +"__rl": true, +"mode": "id", +"value": "={{ $json.tableId }}" +}, +"options": {} +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "50888ac5-30c9-4036-aade-6ccfdf605c3b", +"name": "Add Row ID to Payload", +"type": "n8n-nodes-base.set", +"position": [ +2300, +-260 +], +"parameters": { +"mode": "raw", +"options": {}, +"jsonOutput": "={{\n{\n id: $('Row Ref').item.json.id,\n ...$input.all()\n .map(item => item.json)\n .reduce((acc, item) => ({\n ...acc,\n ...item,\n }), {})\n}\n}}" +}, +"executeOnce": true, +"typeVersion": 3.4 +}, +{ +"id": "e3ebeb45-45d9-44a4-a2e6-bde89f5da125", +"name": "Update Record", +"type": "n8n-nodes-base.airtable", +"position": [ +2480, +-260 +], +"parameters": { +"base": { +"__rl": true, +"mode": "id", +"value": "={{ $('Event Ref1').first().json.baseId }}" +}, +"table": { +"__rl": true, +"mode": "id", +"value": "={{ $('Event Ref1').first().json.tableId }}" +}, +"columns": { +"value": {}, +"schema": [ +{ +"id": "id", +"type": "string", +"display": true, +"removed": false, +"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": "File", +"type": "array", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "File", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Full Name", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Full Name", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Address", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Address", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Created", +"type": "string", +"display": true, +"removed": false, +"readOnly": true, +"required": false, +"displayName": "Created", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Last Modified", +"type": "string", +"display": true, +"removed": false, +"readOnly": true, +"required": false, +"displayName": "Last Modified", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "autoMapInputData", +"matchingColumns": [ +"id" +] +}, +"options": {}, +"operation": "update" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "ac01ec4b-e030-4608-af38-64558408832f", +"name": "Airtable Webhook", +"type": "n8n-nodes-base.webhook", +"position": [ +-1400, +-140 +], +"webhookId": "a82f0ae7-678e-49d9-8219-7281e8a2a1b2", +"parameters": { +"path": "a82f0ae7-678e-49d9-8219-7281e8a2a1b2", +"options": {}, +"httpMethod": "POST" +}, +"typeVersion": 2 +}, +{ +"id": "90178da9-2000-474e-ba93-a02d03ec6a1d", +"name": "When clicking ‘Test workflow’", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +-1600, +-640 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "b8b887ce-f891-4a3c-993b-0aaccadf1b52", +"name": "Set Airtable Vars", +"type": "n8n-nodes-base.set", +"position": [ +-1420, +-640 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "012cb420-1455-4796-a2ac-a31e6abf59ba", +"name": "appId", +"type": "string", +"value": "" +}, +{ +"id": "e863b66c-420f-43c6-aee2-43aa5087a0a5", +"name": "tableId", +"type": "string", +"value": "" +}, +{ +"id": "e470be1a-5833-47ed-9e2f-988ef5479738", +"name": "notificationUrl", +"type": "string", +"value": "" +}, +{ +"id": "e4b3213b-e3bd-479b-99ec-d1aa31eaa4c8", +"name": "inputField", +"type": "string", +"value": "File" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "a3ef1a4a-fd22-4a37-8edb-48037f44fa4b", +"name": "Get Table Schema1", +"type": "n8n-nodes-base.airtable", +"position": [ +-1240, +-820 +], +"parameters": { +"base": { +"__rl": true, +"mode": "id", +"value": "={{ $json.appId }}" +}, +"resource": "base", +"operation": "getSchema" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "2490bbc6-2ea1-4146-b0b8-5a406e89ea2c", +"name": "Get \"Input\" Field", +"type": "n8n-nodes-base.set", +"position": [ +-1060, +-820 +], +"parameters": { +"mode": "raw", +"options": {}, +"jsonOutput": "={{\n$input.all()\n .map(item => item.json)\n .find(item => item.id === $('Set Airtable Vars').first().json.tableId)\n .fields\n .find(field => field.name === $('Set Airtable Vars').first().json.inputField)\n}}" +}, +"executeOnce": true, +"typeVersion": 3.4 +}, +{ +"id": "a3de141f-0ce8-4f8e-ae8e-f10f635d14ec", +"name": "RecordsChanged Webhook", +"type": "n8n-nodes-base.httpRequest", +"position": [ +-880, +-820 +], +"parameters": { +"url": "=https://api.airtable.com/v0/bases/{{ $('Set Airtable Vars').first().json.appId }}/webhooks", +"method": "POST", +"options": {}, +"jsonBody": "={{\n{\n \"notificationUrl\": $('Set Airtable Vars').first().json.notificationUrl,\n \"specification\": {\n \"options\": {\n \"filters\": {\n \"fromSources\": [ \"client\" ],\n \"dataTypes\": [ \"tableData\" ],\n \"changeTypes\": [ \"update\" ],\n \"recordChangeScope\": $('Set Airtable Vars').first().json.tableId,\n \"watchDataInFieldIds\": [$json.id]\n }\n }\n }\n}\n}}", +"sendBody": true, +"specifyBody": "json", +"authentication": "predefinedCredentialType", +"nodeCredentialType": "airtableTokenApi" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "21b0fae8-2046-4647-83c4-132d1d63503a", +"name": "FieldsChanged Webhook", +"type": "n8n-nodes-base.httpRequest", +"position": [ +-880, +-640 +], +"parameters": { +"url": "=https://api.airtable.com/v0/bases/{{ $('Set Airtable Vars').first().json.appId }}/webhooks", +"method": "POST", +"options": {}, +"jsonBody": "={{\n{\n \"notificationUrl\": $('Set Airtable Vars').first().json.notificationUrl,\n \"specification\": {\n \"options\": {\n \"filters\": {\n \"fromSources\": [ \"client\" ],\n \"dataTypes\": [ \"tableFields\" ],\n \"changeTypes\": [ \"add\", \"update\" ],\n \"recordChangeScope\": $('Set Airtable Vars').first().json.tableId\n }\n }\n }\n}\n}}", +"sendBody": true, +"specifyBody": "json", +"authentication": "predefinedCredentialType", +"nodeCredentialType": "airtableTokenApi" +}, +"credentials": { +"airtableTokenApi": { +"id": "Und0frCQ6SNVX3VV", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "f31c36cb-98da-4688-a83a-f06e46d2b8a2", +"name": "Sticky Note14", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1680, +-1000 +], +"parameters": { +"color": 5, +"width": 1020, +"height": 580, +"content": "## ⭐️ Creating Airtable Webhooks\nTo link this workflow with Airtable, you'll have to create webhooks for the Base.\nYou'll only really need to do this this once but if these webhooks are inactive after 7 days, you'll need to create them again.\n\nCheck out the Airtable Developer documentation for more info: [https://airtable.com/developers/web/api/webhooks-overview](https://airtable.com/developers/web/api/webhooks-overview)" +}, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"Get Row": { +"main": [ +[ +{ +"node": "Filter Valid Rows", +"type": "main", +"index": 0 +} +] +] +}, +"Row Ref": { +"main": [ +[ +{ +"node": "Get File Data1", +"type": "main", +"index": 0 +} +] +] +}, +"Event Ref": { +"main": [ +[ +{ +"node": "Filter Valid Fields", +"type": "main", +"index": 0 +} +] +] +}, +"Event Ref1": { +"main": [ +[ +{ +"node": "Get Row", +"type": "main", +"index": 0 +} +] +] +}, +"Event Type": { +"main": [ +[ +{ +"node": "Event Ref1", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Event Ref", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Event Ref", +"type": "main", +"index": 0 +} +] +] +}, +"Get Result": { +"main": [ +[ +{ +"node": "Update Row", +"type": "main", +"index": 0 +} +] +] +}, +"Update Row": { +"main": [ +[ +{ +"node": "Loop Over Items", +"type": "main", +"index": 0 +} +] +] +}, +"Get Result1": { +"main": [ +[ +{ +"node": "Add Row ID to Payload", +"type": "main", +"index": 0 +} +] +] +}, +"Parse Event": { +"main": [ +[ +{ +"node": "Event Type", +"type": "main", +"index": 0 +} +] +] +}, +"Fetch Records": { +"main": [ +[ +{ +"node": "Loop Over Items", +"type": "main", +"index": 0 +} +] +] +}, +"Get File Data": { +"main": [ +[ +{ +"node": "Extract from File", +"type": "main", +"index": 0 +} +] +] +}, +"Row Reference": { +"main": [ +[ +{ +"node": "Get File Data", +"type": "main", +"index": 0 +} +] +] +}, +"Update Record": { +"main": [ +[ +{ +"node": "Loop Over Items1", +"type": "main", +"index": 0 +} +] +] +}, +"Get File Data1": { +"main": [ +[ +{ +"node": "Extract from File1", +"type": "main", +"index": 0 +} +] +] +}, +"Loop Over Items": { +"main": [ +[], +[ +{ +"node": "Row Reference", +"type": "main", +"index": 0 +} +] +] +}, +"Airtable Webhook": { +"main": [ +[ +{ +"node": "Get Table Schema", +"type": "main", +"index": 0 +} +] +] +}, +"Fields to Update": { +"main": [ +[ +{ +"node": "Generate Field Value1", +"type": "main", +"index": 0 +} +] +] +}, +"Get Table Schema": { +"main": [ +[ +{ +"node": "Get Prompt Fields", +"type": "main", +"index": 0 +} +] +] +}, +"Loop Over Items1": { +"main": [ +[], +[ +{ +"node": "Row Ref", +"type": "main", +"index": 0 +} +] +] +}, +"Extract from File": { +"main": [ +[ +{ +"node": "Generate Field Value", +"type": "main", +"index": 0 +} +] +] +}, +"Filter Valid Rows": { +"main": [ +[ +{ +"node": "Loop Over Items1", +"type": "main", +"index": 0 +} +] +] +}, +"Get \"Input\" Field": { +"main": [ +[ +{ +"node": "RecordsChanged Webhook", +"type": "main", +"index": 0 +} +] +] +}, +"Get Prompt Fields": { +"main": [ +[ +{ +"node": "Get Webhook Payload", +"type": "main", +"index": 0 +} +] +] +}, +"Get Table Schema1": { +"main": [ +[ +{ +"node": "Get \"Input\" Field", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Generate Field Value1", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Set Airtable Vars": { +"main": [ +[ +{ +"node": "Get Table Schema1", +"type": "main", +"index": 0 +}, +{ +"node": "FieldsChanged Webhook", +"type": "main", +"index": 0 +} +] +] +}, +"Extract from File1": { +"main": [ +[ +{ +"node": "Fields to Update", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model1": { +"ai_languageModel": [ +[ +{ +"node": "Generate Field Value", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Filter Valid Fields": { +"main": [ +[ +{ +"node": "Fetch Records", +"type": "main", +"index": 0 +} +] +] +}, +"Get Webhook Payload": { +"main": [ +[ +{ +"node": "Parse Event", +"type": "main", +"index": 0 +} +] +] +}, +"Generate Field Value": { +"main": [ +[ +{ +"node": "Get Result", +"type": "main", +"index": 0 +} +] +] +}, +"Add Row ID to Payload": { +"main": [ +[ +{ +"node": "Update Record", +"type": "main", +"index": 0 +} +] +] +}, +"FieldsChanged Webhook": { +"main": [ +[] +] +}, +"Generate Field Value1": { +"main": [ +[ +{ +"node": "Get Result1", +"type": "main", +"index": 0 +} +] +] +}, +"RecordsChanged Webhook": { +"main": [ +[] +] +}, +"When clicking ‘Test workflow’": { +"main": [ +[ +{ +"node": "Set Airtable Vars", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/AI Data Extraction with Dynamic Prompts and Baserow.txt b/AI Data Extraction with Dynamic Prompts and Baserow.txt new file mode 100644 index 0000000..d3c1052 --- /dev/null +++ b/AI Data Extraction with Dynamic Prompts and Baserow.txt @@ -0,0 +1,1300 @@ +{ +"nodes": [ +{ +"id": "065d7ec9-edc5-46f6-b8ac-d62ed0e5c8e3", +"name": "Baserow Event", +"type": "n8n-nodes-base.webhook", +"position": [ +-1180, +-140 +], +"webhookId": "267ea500-e2cd-4604-a31f-f0773f27317c", +"parameters": { +"path": "267ea500-e2cd-4604-a31f-f0773f27317c", +"options": {}, +"httpMethod": "POST" +}, +"typeVersion": 2 +}, +{ +"id": "ac1403b4-9d45-404d-9892-0bed39b9ec82", +"name": "Event Type", +"type": "n8n-nodes-base.switch", +"position": [ +-220, +-140 +], +"parameters": { +"rules": { +"values": [ +{ +"outputKey": "rows.updated", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "2162daf8-d23d-4b8f-8257-bdfc5400a3a8", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.event_type }}", +"rightValue": "rows.updated" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "field.created", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "48e112f6-afe8-40bf-b673-b37446934a62", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.event_type }}", +"rightValue": "field.created" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "field.updated", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "5aa258cd-15c2-4156-a32d-afeed662a38e", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.event_type }}", +"rightValue": "field.updated" +} +] +}, +"renameOutput": true +} +] +}, +"options": {} +}, +"typeVersion": 3.2 +}, +{ +"id": "c501042d-f9e7-4c1a-b01d-b11392b1a804", +"name": "Table Fields API", +"type": "n8n-nodes-base.httpRequest", +"position": [ +-900, +-140 +], +"parameters": { +"url": "=https://api.baserow.io/api/database/fields/table/{{ $json.body.table_id }}/", +"options": {}, +"sendQuery": true, +"authentication": "genericCredentialType", +"genericAuthType": "httpHeaderAuth", +"queryParameters": { +"parameters": [ +{ +"name": "user_field_names", +"value": "true" +} +] +} +}, +"credentials": { +"httpHeaderAuth": { +"id": "F28aPWK5NooSHAg0", +"name": "Baserow (n8n-local)" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "af6c3b7f-bb8b-4037-8e3b-337d81ca5632", +"name": "Get Prompt Fields", +"type": "n8n-nodes-base.code", +"position": [ +-720, +-140 +], +"parameters": { +"jsCode": "const fields = $input.all()\n .filter(item => item.json.description)\n .map(item => ({\n id: item.json.id,\n order: item.json.order,\n name: item.json.name,\n description: item.json.description,\n }));\n\nreturn { json: { fields } };" +}, +"typeVersion": 2 +}, +{ +"id": "e1f8f740-c784-4f07-9265-76db518f3ebc", +"name": "Get Event Body", +"type": "n8n-nodes-base.set", +"position": [ +-380, +-140 +], +"parameters": { +"mode": "raw", +"options": {}, +"jsonOutput": "={{ $('Baserow Event').first().json.body }}" +}, +"typeVersion": 3.4 +}, +{ +"id": "e303b7c3-639a-4136-8aa4-074eedeb273f", +"name": "List Table API", +"type": "n8n-nodes-base.httpRequest", +"position": [ +480, +220 +], +"parameters": { +"url": "=https://api.baserow.io/api/database/rows/table/{{ $json.table_id }}/", +"options": { +"pagination": { +"pagination": { +"nextURL": "={{ $response.body.next || `https://api.baserow.io/api/database/rows/table/${$json.table_id}/?user_field_names=true&size=20&page=9999` }}", +"maxRequests": 3, +"paginationMode": "responseContainsNextURL", +"requestInterval": 1000, +"limitPagesFetched": true, +"completeExpression": "={{ $response.body.isEmpty() || $response.statusCode >= 400 }}", +"paginationCompleteWhen": "other" +} +} +}, +"sendQuery": true, +"authentication": "genericCredentialType", +"genericAuthType": "httpHeaderAuth", +"queryParameters": { +"parameters": [ +{ +"name": "user_field_names", +"value": "true" +}, +{ +"name": "size", +"value": "20" +}, +{ +"name": "include", +"value": "id,order,_id,name,created_at,last_modified_at" +}, +{ +"name": "filters", +"value": "{\"filter_type\":\"AND\",\"filters\":[{\"type\":\"not_empty\",\"field\":\"File\",\"value\":\"\"}],\"groups\":[]}" +} +] +} +}, +"credentials": { +"httpHeaderAuth": { +"id": "F28aPWK5NooSHAg0", +"name": "Baserow (n8n-local)" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "9ad2e0c8-c92d-460d-be7a-237ce29b34c2", +"name": "Get Valid Rows", +"type": "n8n-nodes-base.code", +"position": [ +640, +220 +], +"parameters": { +"jsCode": "return $input.all()\n .filter(item => item.json.results?.length)\n .flatMap(item => item.json.results);" +}, +"typeVersion": 2 +}, +{ +"id": "72b137e9-2e87-4580-9282-0ab7c5147f68", +"name": "Get File Data", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1320, +320 +], +"parameters": { +"url": "={{ $json.File[0].url }}", +"options": {} +}, +"typeVersion": 4.2 +}, +{ +"id": "d479ee4e-4a87-4a0e-b9ca-4aa54afdc67a", +"name": "Extract from File", +"type": "n8n-nodes-base.extractFromFile", +"position": [ +1480, +320 +], +"parameters": { +"options": {}, +"operation": "pdf" +}, +"typeVersion": 1 +}, +{ +"id": "717e36f8-7dd7-44a6-bcef-9f20735853d2", +"name": "Update Row", +"type": "n8n-nodes-base.httpRequest", +"notes": "Execute Once", +"onError": "continueRegularOutput", +"maxTries": 2, +"position": [ +2280, +380 +], +"parameters": { +"url": "=https://api.baserow.io/api/database/rows/table/{{ $('Event Ref').first().json.table_id }}/{{ $('Row Reference').item.json.id }}/", +"method": "PATCH", +"options": {}, +"jsonBody": "={{\n{\n ...$input.all()\n .reduce((acc, item) => ({\n ...acc,\n [item.json.field]: item.json.value\n }), {})\n}\n}}", +"sendBody": true, +"sendQuery": true, +"specifyBody": "json", +"authentication": "genericCredentialType", +"genericAuthType": "httpHeaderAuth", +"queryParameters": { +"parameters": [ +{ +"name": "user_field_names", +"value": "true" +} +] +} +}, +"credentials": { +"httpHeaderAuth": { +"id": "F28aPWK5NooSHAg0", +"name": "Baserow (n8n-local)" +} +}, +"executeOnce": true, +"notesInFlow": true, +"retryOnFail": false, +"typeVersion": 4.2, +"waitBetweenTries": 3000 +}, +{ +"id": "b807a9c0-2334-491c-a259-1e0e266f89df", +"name": "Get Result", +"type": "n8n-nodes-base.set", +"position": [ +2100, +380 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "3ad72567-1d17-4910-b916-4c34a43b1060", +"name": "field", +"type": "string", +"value": "={{ $('Event Ref').first().json.field.name }}" +}, +{ +"id": "e376ba60-8692-4962-9af7-466b6a3f44a2", +"name": "value", +"type": "string", +"value": "={{ $json.text.trim() }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "d29a58db-f547-4a4b-bc20-10e14529e474", +"name": "Loop Over Items", +"type": "n8n-nodes-base.splitInBatches", +"position": [ +900, +220 +], +"parameters": { +"options": {} +}, +"typeVersion": 3 +}, +{ +"id": "233b2e96-7873-42f0-989f-c3df5a8e4542", +"name": "Row Reference", +"type": "n8n-nodes-base.noOp", +"position": [ +1080, +320 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "396eb9c0-dcde-4735-9e15-bf6350def086", +"name": "Generate Field Value", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +1640, +320 +], +"parameters": { +"text": "=\n{{ $json.text }}\n\n\nData to extract: {{ $('Event Ref').first().json.field.description }}\noutput format is: {{ $('Event Ref').first().json.field.type }}", +"messages": { +"messageValues": [ +{ +"message": "=You assist the user in extracting the required data from the given file.\n* Keep you answer short.\n* If you cannot extract the requested data, give you response as \"n/a\"." +} +] +}, +"promptType": "define" +}, +"typeVersion": 1.5 +}, +{ +"id": "4be0a9e5-e77e-4cea-9dd3-bc6e7de7a72b", +"name": "Get Row", +"type": "n8n-nodes-base.httpRequest", +"position": [ +640, +-420 +], +"parameters": { +"url": "=https://api.baserow.io/api/database/rows/table/{{ $('Event Ref1').first().json.table_id }}/{{ $json.id }}/", +"options": {}, +"sendQuery": true, +"authentication": "genericCredentialType", +"genericAuthType": "httpHeaderAuth", +"queryParameters": { +"parameters": [ +{ +"name": "user_field_names", +"value": "true" +} +] +} +}, +"credentials": { +"httpHeaderAuth": { +"id": "F28aPWK5NooSHAg0", +"name": "Baserow (n8n-local)" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "40fc77b8-a986-40ab-a78c-da05a3f171c2", +"name": "Rows to List", +"type": "n8n-nodes-base.splitOut", +"position": [ +320, +-420 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "items" +}, +"typeVersion": 1 +}, +{ +"id": "4c5bc9c8-1bcb-48b1-82d0-5cf04535108c", +"name": "Fields to Update", +"type": "n8n-nodes-base.code", +"position": [ +1640, +-300 +], +"parameters": { +"jsCode": "const row = $('Row Ref').first().json;\nconst fields = $('Get Prompt Fields').first().json.fields;\nconst missingFields = fields\n .filter(field => field.description && !row[field.name]);\n\nreturn missingFields;" +}, +"typeVersion": 2 +}, +{ +"id": "85d5c817-e5f8-45ea-bf7f-efc7913f542c", +"name": "Loop Over Items1", +"type": "n8n-nodes-base.splitInBatches", +"position": [ +900, +-420 +], +"parameters": { +"options": {} +}, +"typeVersion": 3 +}, +{ +"id": "69005b35-9c66-4c14-80a9-ef8e945dab30", +"name": "Row Ref", +"type": "n8n-nodes-base.noOp", +"position": [ +1080, +-300 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "1b0e14da-13a8-4023-9006-464578bf0ff5", +"name": "Get File Data1", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1320, +-300 +], +"parameters": { +"url": "={{ $('Row Ref').item.json.File[0].url }}", +"options": {} +}, +"typeVersion": 4.2 +}, +{ +"id": "47cf67bc-a3e2-4796-b5a7-4f6a6aef3e90", +"name": "Extract from File1", +"type": "n8n-nodes-base.extractFromFile", +"position": [ +1480, +-300 +], +"parameters": { +"options": {}, +"operation": "pdf" +}, +"typeVersion": 1 +}, +{ +"id": "3dc743cc-0dde-4349-975c-fa453d99dbaf", +"name": "Update Row1", +"type": "n8n-nodes-base.httpRequest", +"notes": "Execute Once", +"onError": "continueRegularOutput", +"maxTries": 2, +"position": [ +2440, +-260 +], +"parameters": { +"url": "=https://api.baserow.io/api/database/rows/table/{{ $('Event Ref1').first().json.table_id }}/{{ $('Row Ref').first().json.id }}/", +"method": "PATCH", +"options": {}, +"jsonBody": "={{\n{\n ...$input.all()\n .reduce((acc, item) => ({\n ...acc,\n [item.json.field]: item.json.value\n }), {})\n}\n}}", +"sendBody": true, +"sendQuery": true, +"specifyBody": "json", +"authentication": "genericCredentialType", +"genericAuthType": "httpHeaderAuth", +"queryParameters": { +"parameters": [ +{ +"name": "user_field_names", +"value": "true" +} +] +} +}, +"credentials": { +"httpHeaderAuth": { +"id": "F28aPWK5NooSHAg0", +"name": "Baserow (n8n-local)" +} +}, +"executeOnce": true, +"notesInFlow": true, +"retryOnFail": false, +"typeVersion": 4.2, +"waitBetweenTries": 3000 +}, +{ +"id": "49c53281-d323-4794-919a-d807d7ccc25e", +"name": "Get Result1", +"type": "n8n-nodes-base.set", +"position": [ +2260, +-260 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "3ad72567-1d17-4910-b916-4c34a43b1060", +"name": "field", +"type": "string", +"value": "={{ $('Fields to Update').item.json.name }}" +}, +{ +"id": "e376ba60-8692-4962-9af7-466b6a3f44a2", +"name": "value", +"type": "string", +"value": "={{ $json.text.trim() }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "bc23708a-b177-47db-8a30-4330198710e0", +"name": "Generate Field Value1", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +1800, +-300 +], +"parameters": { +"text": "=\n{{ $('Extract from File1').first().json.text }}\n\n\nData to extract: {{ $json.description }}\noutput format is: {{ $json.type }}", +"messages": { +"messageValues": [ +{ +"message": "=You assist the user in extracting the required data from the given file.\n* Keep you answer short.\n* If you cannot extract the requested data, give you response as \"n/a\" followed by \"(reason)\" where reason is replaced with reason why data could not be extracted." +} +] +}, +"promptType": "define" +}, +"typeVersion": 1.5 +}, +{ +"id": "c0297c19-04b8-4d56-9ce0-320b399f73bd", +"name": "Filter Valid Rows", +"type": "n8n-nodes-base.filter", +"position": [ +480, +-420 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "7ad58f0b-0354-49a9-ab2f-557652d7b416", +"operator": { +"type": "string", +"operation": "notEmpty", +"singleValue": true +}, +"leftValue": "={{ $json.File[0].url }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "5aab6971-1d6f-4b82-a218-4e25c7b28052", +"name": "Filter Valid Fields", +"type": "n8n-nodes-base.filter", +"position": [ +320, +220 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "5b4a7393-788c-42dc-ac1f-e76f833f8534", +"operator": { +"type": "string", +"operation": "notEmpty", +"singleValue": true +}, +"leftValue": "={{ $json.field.description }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "bc144115-f3a2-4e99-a35c-4a780754d0fb", +"name": "Event Ref", +"type": "n8n-nodes-base.noOp", +"position": [ +160, +220 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "13fd10c0-d4eb-463a-a8b6-5471380f3710", +"name": "Event Ref1", +"type": "n8n-nodes-base.noOp", +"position": [ +160, +-420 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "e07053a4-a130-41b0-85d3-dfa3983b1547", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1000, +-340 +], +"parameters": { +"color": 7, +"width": 480, +"height": 440, +"content": "### 1. Get Table Schema\n[Learn more about the HTTP node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest)\n\nFor this operation, we'll have to use the Baserow API rather than the built-in node. However, this way does allow for more flexibility with query parameters.\n" +}, +"typeVersion": 1 +}, +{ +"id": "675b9d6a-1ba6-49ce-b569-38cc0ba04dcb", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-260, +-440 +], +"parameters": { +"color": 5, +"width": 330, +"height": 80, +"content": "### 2a. Updates Minimal Number of Rows\nThis branch updates only the rows impacted." +}, +"typeVersion": 1 +}, +{ +"id": "021d51f9-7a5b-4f93-baad-707144aeb7ba", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-320, +140 +], +"parameters": { +"color": 5, +"width": 390, +"height": 120, +"content": "### 2b. Update Every Row under the Field\nThis branch updates all applicable rows under field when the field/column is created or changed. Watch out - if you have 1000s of rows, this could take a while!" +}, +"typeVersion": 1 +}, +{ +"id": "ae49cfb0-ac83-4501-bc01-d98be32798f0", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1780, +-1060 +], +"parameters": { +"width": 520, +"height": 1160, +"content": "## Try It Out!\n### This n8n template powers a \"dynamic\" or \"user-defined\" prompts with PDF workflow pattern for a [Baserow](https://baserow.io) table. Simply put, it allows users to populate a spreadsheet using prompts without touching the underlying template.\n\n**Check out the video demo I did for n8n Studio**: https://www.youtube.com/watch?v=_fNAD1u8BZw\n\nThis template is intended to be used as a webhook source for Baserow. **Looking for a Airtable version? [Click here](https://n8n.io/workflows/2771-ai-data-extraction-with-dynamic-prompts-and-airtable/)**\n\n## How it works\n* Each Baserow.io tables offers integration feature whereby changes to the table can be sent as events to any accessible webhook. This allows for a reactive trigger pattern which makes this type of workflow possible. For our usecase, we capture the vents of `row_updated`, `field_created` and `field_updated`.\n* Next, we'll need an \"input\" column in our Baserow.io table. This column will be where our context lives for evaluating the prompts against. In this example, our \"input\" column name is \"file\" and it's where we'll upload our PDFs. Note, this \"input\" field is human-controlled and never updated from this template.\n* Now for the columns (aka \"fields\" in Baserow). Each field allows us to define a name, type and description and together form the schema. The first 2 are self-explaintory but the \"description\" will be for users to provide their prompts ie. what data should the field to contain.\n* In this template, a webhook trigger waits for when a row or column is updated. The incoming event comes with lots of details such as the table, row and/or column Ids that were impacted.\n* We use this information to fetch the table's schema in order to get the column's descriptions (aka dynamic prompts).\n* For each triggered event, we download our input ie. the PDF and ready it for our AI/LLM. By iterating through the available columns and feeding the dynamic prompts, our LLM can run those prompts against the PDF and thus generating a value response for each cell.\n* These values are then collected and used to update the Baserow Table.\n\n## How to use\n* You'll need to publish this workflow and make it accessible to our Baserow instance. Good to note, you only really need to do this once and can reuse for many Baserow Tables.\n* Configure your Baserow Table to send `row_updated`, `field_created` and `field_updated` events to this n8n workflow.\n* This workflow should work with both cloud-hosted and self-hosted versions of Baserow.\n\n\n### Need Help?\nJoin the [Discord](https://discord.com/invite/XPKeKXeB7d) or ask in the [Forum](https://community.n8n.io/)!\n\nHappy Flowgramming!" +}, +"typeVersion": 1 +}, +{ +"id": "23ea63f5-e1ad-4326-95a4-945bf98d03f4", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-500, +-340 +], +"parameters": { +"color": 7, +"width": 580, +"height": 440, +"content": "### 2. Event Router Pattern\n[Learn more about the Switch node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.switch/)\n\nA simple switch node can be used to determine which event to handle. The difference between our row and field events is that row event affect a single row whereas field events affect all rows. \n" +}, +"typeVersion": 1 +}, +{ +"id": "179f9459-43d0-4342-ab94-e248730182a5", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +100, +-620 +], +"parameters": { +"color": 7, +"width": 700, +"height": 400, +"content": "### 3. Filter Only Rows with Valid Input\n[Learn more about the Split Out node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.splitout/)\n\nThis step handles one or more updated rows where \"updated\" means the \"input\" column (ie. \"file\" in our example) for these rows were changed. For each affected row, we'll get the full row to figure out only the columns we need to update - this is an optimisation to avoid redundant work ie. generating values for columns which already have a value." +}, +"typeVersion": 1 +}, +{ +"id": "7124a8c0-549e-4b82-8e1f-c6428d2bfb44", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2140, +-480 +], +"parameters": { +"color": 7, +"width": 520, +"height": 440, +"content": "### 6. Update the Baserow Table Row\n[Learn more about the Edit Fields node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.set/)\n\nFinally, we can collect the LLM responses and combine them to build an API request to update our Baserow Table row - the Id of which we got from initial webhook. After this is done, we can move onto the next row and repeat the process.\n" +}, +"typeVersion": 1 +}, +{ +"id": "c55ce945-10ba-440b-a444-81cb4ed63539", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1260, +-580 +], +"parameters": { +"color": 7, +"width": 860, +"height": 580, +"content": "### 5. PDFs, LLMs and Dynamic Prompts? Oh My!\n[Learn more about the Basic LLM node](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.chainllm/)\n\nThis step is where it all comes together! In short, we give our LLM the PDF contents as the context and loop through our dynamic prompts (from the schema we pulled earlier) for our row. At the end, our LLM should have produced a value for each column requested.\n\n**Note**: There's definitely a optimisation which could be done for caching PDFs but it beyond the scope of this demonstration.\n" +}, +"typeVersion": 1 +}, +{ +"id": "1a0ff82e-64aa-479e-8dec-c29b512b0686", +"name": "Sticky Note9", +"type": "n8n-nodes-base.stickyNote", +"position": [ +820, +-580 +], +"parameters": { +"color": 7, +"width": 420, +"height": 460, +"content": "### 4. Using an Items Loop\n[Learn more about the Split in Batches node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.splitinbatches/)\n\nA split in batches node is used here to update a row at a time however, this is a preference for user experience - changes are seen in the Baserow quicker.\n" +}, +"typeVersion": 1 +}, +{ +"id": "f4562d44-4fc0-4c59-ba90-8b65f1162aac", +"name": "Sticky Note10", +"type": "n8n-nodes-base.stickyNote", +"position": [ +100, +40 +], +"parameters": { +"color": 7, +"width": 680, +"height": 360, +"content": "### 7. Listing All Rows Under The Column\n[Learn more about the Code node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.code)\n\nWe can use Baserow's List API and the HTTP node's pagination feature to fetch all applicable rows under the affected field - the filter query on the API is helpful here.\n" +}, +"typeVersion": 1 +}, +{ +"id": "979983e9-1002-444c-a018-50ce525ef02a", +"name": "Sticky Note11", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1260, +140 +], +"parameters": { +"color": 7, +"width": 700, +"height": 500, +"content": "### 9. Generating Value using LLM\n[Learn more about the Extract From File node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.extractfromfile/)\n\nPretty much identical to Step 5 but instead of updating every field/column, we only need to generate a value for one. \n" +}, +"typeVersion": 1 +}, +{ +"id": "f38aa7a3-479b-4876-87bf-769ada3089f2", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +1800, +-140 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "a5061210-2e6b-4b62-994f-594fc10a0ac6", +"name": "Sticky Note12", +"type": "n8n-nodes-base.stickyNote", +"position": [ +820, +40 +], +"parameters": { +"color": 7, +"width": 420, +"height": 460, +"content": "### 8. Using an Items Loop\n[Learn more about the Split in Batches node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.splitinbatches/)\n\nSimilar to Step 4, the Split in Batches node is a preference for user experience - changes are seen in the Baserow quicker.\n" +}, +"typeVersion": 1 +}, +{ +"id": "e47e36d4-bf6d-48d3-9e52-d8bbac06c4b4", +"name": "OpenAI Chat Model1", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +1640, +500 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "52501eab-861e-4de9-837d-65879cd43e5b", +"name": "Sticky Note13", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1980, +200 +], +"parameters": { +"color": 7, +"width": 500, +"height": 380, +"content": "### 10. Update the Baserow Table Row\n[Learn more about the Edit Fields node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.set/)\n\nAs with Step 6, the LLM response is used to update the row however only under the field that was created/changed. Once complete, the loop continues and the next row is processed.\n" +}, +"typeVersion": 1 +}, +{ +"id": "6d9fb2e9-6aca-4276-b9b3-d409be24e40e", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1780, +-1200 +], +"parameters": { +"color": 7, +"height": 120, +"content": "![baserow.io](https://res.cloudinary.com/daglih2g8/image/upload/f_auto,q_auto/v1/n8n-workflows/baserow_logo)" +}, +"typeVersion": 1 +}, +{ +"id": "bccfc32b-fd18-4de7-88d5-0aeb02ab7954", +"name": "Sticky Note14", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1200, +-1280 +], +"parameters": { +"color": 5, +"width": 820, +"height": 800, +"content": "## ⭐️ Creating Baserow Webhooks\nBaserow webhooks are created via the UI and the option can be accessed by clicking on the 3 dots button in the toolbar.\n\n* Create a POST webhook for your n8n webhook URL found in this template.\n* Select the \"use fields names instead of IDs\" option.\n* Select \"let me choose individual events\"\n* The events to choose are \"row updated\", \"field created\" and \"field updated\".\n* For the \"row updated\" event, be sure to specify the input field - in this case, \"File\".\n\n![](https://res.cloudinary.com/daglih2g8/image/upload/f_auto,q_auto/v1/n8n-workflows/jfhvavdpnf3krloc6iaz)" +}, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"Get Row": { +"main": [ +[ +{ +"node": "Loop Over Items1", +"type": "main", +"index": 0 +} +] +] +}, +"Row Ref": { +"main": [ +[ +{ +"node": "Get File Data1", +"type": "main", +"index": 0 +} +] +] +}, +"Event Ref": { +"main": [ +[ +{ +"node": "Filter Valid Fields", +"type": "main", +"index": 0 +} +] +] +}, +"Event Ref1": { +"main": [ +[ +{ +"node": "Rows to List", +"type": "main", +"index": 0 +} +] +] +}, +"Event Type": { +"main": [ +[ +{ +"node": "Event Ref1", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Event Ref", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Event Ref", +"type": "main", +"index": 0 +} +] +] +}, +"Get Result": { +"main": [ +[ +{ +"node": "Update Row", +"type": "main", +"index": 0 +} +] +] +}, +"Update Row": { +"main": [ +[ +{ +"node": "Loop Over Items", +"type": "main", +"index": 0 +} +] +] +}, +"Get Result1": { +"main": [ +[ +{ +"node": "Update Row1", +"type": "main", +"index": 0 +} +] +] +}, +"Update Row1": { +"main": [ +[ +{ +"node": "Loop Over Items1", +"type": "main", +"index": 0 +} +] +] +}, +"Rows to List": { +"main": [ +[ +{ +"node": "Filter Valid Rows", +"type": "main", +"index": 0 +} +] +] +}, +"Baserow Event": { +"main": [ +[ +{ +"node": "Table Fields API", +"type": "main", +"index": 0 +} +] +] +}, +"Get File Data": { +"main": [ +[ +{ +"node": "Extract from File", +"type": "main", +"index": 0 +} +] +] +}, +"Row Reference": { +"main": [ +[ +{ +"node": "Get File Data", +"type": "main", +"index": 0 +} +] +] +}, +"Get Event Body": { +"main": [ +[ +{ +"node": "Event Type", +"type": "main", +"index": 0 +} +] +] +}, +"Get File Data1": { +"main": [ +[ +{ +"node": "Extract from File1", +"type": "main", +"index": 0 +} +] +] +}, +"Get Valid Rows": { +"main": [ +[ +{ +"node": "Loop Over Items", +"type": "main", +"index": 0 +} +] +] +}, +"List Table API": { +"main": [ +[ +{ +"node": "Get Valid Rows", +"type": "main", +"index": 0 +} +] +] +}, +"Loop Over Items": { +"main": [ +[], +[ +{ +"node": "Row Reference", +"type": "main", +"index": 0 +} +] +] +}, +"Fields to Update": { +"main": [ +[ +{ +"node": "Generate Field Value1", +"type": "main", +"index": 0 +} +] +] +}, +"Loop Over Items1": { +"main": [ +[], +[ +{ +"node": "Row Ref", +"type": "main", +"index": 0 +} +] +] +}, +"Table Fields API": { +"main": [ +[ +{ +"node": "Get Prompt Fields", +"type": "main", +"index": 0 +} +] +] +}, +"Extract from File": { +"main": [ +[ +{ +"node": "Generate Field Value", +"type": "main", +"index": 0 +} +] +] +}, +"Filter Valid Rows": { +"main": [ +[ +{ +"node": "Get Row", +"type": "main", +"index": 0 +} +] +] +}, +"Get Prompt Fields": { +"main": [ +[ +{ +"node": "Get Event Body", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Generate Field Value1", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Extract from File1": { +"main": [ +[ +{ +"node": "Fields to Update", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model1": { +"ai_languageModel": [ +[ +{ +"node": "Generate Field Value", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Filter Valid Fields": { +"main": [ +[ +{ +"node": "List Table API", +"type": "main", +"index": 0 +} +] +] +}, +"Generate Field Value": { +"main": [ +[ +{ +"node": "Get Result", +"type": "main", +"index": 0 +} +] +] +}, +"Generate Field Value1": { +"main": [ +[ +{ +"node": "Get Result1", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/AI Fitness Coach Strava Data Analysis and Personalized Training Insights.txt b/AI Fitness Coach Strava Data Analysis and Personalized Training Insights.txt new file mode 100644 index 0000000..3013436 --- /dev/null +++ b/AI Fitness Coach Strava Data Analysis and Personalized Training Insights.txt @@ -0,0 +1,354 @@ +{ +"meta": { +"instanceId": "32d80f55a35a7b57f8e47a2ac19558d9f5bcec983a5519d9c29ba713ff4f12c7", +"templateCredsSetupCompleted": true +}, +"nodes": [ +{ +"id": "d9e3e2af-1db4-4ef1-a12a-c56df545e09e", +"name": "Strava Trigger", +"type": "n8n-nodes-base.stravaTrigger", +"position": [ +-60, +0 +], +"webhookId": "c656f7eb-6176-48b1-a68f-7e169699cecb", +"parameters": { +"event": "update", +"object": "activity", +"options": {} +}, +"credentials": { +"stravaOAuth2Api": { +"id": "lI69z0e9sP9DBcrp", +"name": "Strava account" +} +}, +"typeVersion": 1 +}, +{ +"id": "344106a7-f1ce-4ef0-be60-8b0dc6c92fe4", +"name": "Google Gemini Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini", +"position": [ +560, +180 +], +"parameters": { +"options": {}, +"modelName": "models/gemini-2.0-flash-exp" +}, +"credentials": { +"googlePalmApi": { +"id": "MqxJQHgdP5sIvdos", +"name": "Google Gemini(PaLM) - ali@amjid" +} +}, +"typeVersion": 1 +}, +{ +"id": "5ea7c2b8-0ddc-414e-b90c-d1269e074d16", +"name": "Gmail", +"type": "n8n-nodes-base.gmail", +"position": [ +1420, +-200 +], +"webhookId": "70ab1218-b5a1-47e7-9e9e-89c5c4f84c15", +"parameters": { +"sendTo": "amjid@amjidali.com", +"message": "={{ $json.html }}", +"options": { +"appendAttribution": false +}, +"subject": "=" +}, +"credentials": { +"gmailOAuth2": { +"id": "dYWFonU1YWbQ9MHf", +"name": "Gmail account ali@amjidali" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "540e2273-c094-4339-a9d9-41cecbaa55d8", +"name": "Combine Everything", +"type": "n8n-nodes-base.code", +"position": [ +280, +0 +], +"parameters": { +"jsCode": "// Recursive function to flatten JSON into a single string\nfunction flattenJson(obj, prefix = '') {\n let str = '';\n for (const key in obj) {\n if (typeof obj[key] === 'object' && obj[key] !== null) {\n str += flattenJson(obj[key], `${prefix}${key}.`);\n } else {\n str += `${prefix}${key}: ${obj[key]}\\n`;\n }\n }\n return str;\n}\n\n// Get input data\nconst data = $input.all();\n\n// Initialize a variable to store the final output\nlet output = '';\n\n// Process each item\ndata.forEach(item => {\n output += flattenJson(item.json);\n output += '\\n---\\n'; // Separator between records\n});\n\n// Return the merged string as output\nreturn [{ json: { data: output } }];\n" +}, +"typeVersion": 2 +}, +{ +"id": "9db17380-36ee-4d8c-842c-f33215bb5e78", +"name": "Fitness Coach", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +560, +0 +], +"parameters": { +"text": "=You are an Triathlon Coach specializing in guiding the athlete on running, swimming, and cycling. Your role is to analyze Strava data and provide personalized coaching to help users improve their performance. Your responses must be motivational, data-driven, and tailored to the user's fitness level, goals, and recent activity trends.\n\n#### Key Abilities:\n1. **Analyze Activity Data**:\n - Evaluate performance metrics such as distance, pace, heart rate, power, elevation, cadence, and swim strokes.\n - Identify trends, strengths, and areas for improvement.\n\n2. **Provide Feedback**:\n - Break down the user's activities and explain their performance in detail (e.g., pacing consistency, effort levels, technique).\n - Highlight achievements and areas that need focus.\n\n3. **Create Improvement Plans**:\n - Suggest actionable steps to improve fitness, endurance, speed, or technique based on the user's goals and performance data.\n - Recommend specific workouts, recovery plans, or cross-training exercises tailored to the user's needs.\n\n4. **Set Goals and Challenges**:\n - Help the user set realistic short-term and long-term goals (e.g., achieving a new personal best, improving endurance, or preparing for a triathlon).\n - Suggest weekly or monthly challenges to stay motivated.\n\n5. **Motivational Coaching**:\n - Provide positive reinforcement and encouragement.\n - Help the user maintain consistency and avoid burnout.\n\n6. ** Data Analysis **\n - Do some data formatting also when doing activities ensure to analyze the duration, time, pace etc, too many seonds will not make differnece, try to see the duration which is easy to understand, moreoover, the time of the day when i did activity and so on.\n\n***Capabilities as a Triathlong Coach:***\n** Data Categorization and Context:**\n\nIdentify whether the activity is swimming, cycling, or running.\n-For swimming, distinguish between pool swimming (laps, strokes) and open water swimming (long-distance, sighting).\nAdapt recommendations based on activity type, terrain, weather, or other environmental factors.\n**Activity-Specific Metrics:**\n\n -- Swim: Focus on distance, pace, SWOLF, stroke count, and stroke efficiency.\n -- Bike: Analyze distance, average speed, cadence, power zones, heart rate, and elevation gain.\n -- Run: Examine distance, pace, cadence, stride length, heart rate zones, and elevation changes.\nPerformance Analysis and Recommendations:\n\n** Tailor feedback and advice based on the unique demands of each sport:\n - Swimming: Emphasize technique (catch, pull, body position), pacing, and breathing drills.\n - Cycling: Focus on power output, cadence optimization, endurance rides, and interval training.\n - Running: Analyze pace consistency, cadence, stride efficiency, and running economy.\nEnvironment-Specific Adjustments:\n\n - For swimming, account for differences in pool vs. open water conditions (e.g., sighting, drafting, and waves).\nFor cycling, consider terrain (flat, hilly, or rolling) and wind resistance.\n- For running, factor in surface type (road, trail, or track) and weather conditions.\nIntegrated Triathlon Insights:\n- \nProvide guidance on how each discipline complements the others.\nSuggest \"brick workouts\" (e.g., bike-to-run) for race-specific adaptations.\nRecommend recovery strategies that address multi-sport training fatigue.\nBehavior:\nBe precise, detailed, and motivational.\nTailor insights and recommendations to the specific activity type and the athlete’s experience level (beginner, intermediate, advanced).\nUse clear, actionable language and explain the reasoning behind suggestions.\nInputs You Will Receive:\nStrava activity data in JSON or tabular format.\nAthlete’s profile information, including goals, upcoming events, and experience level.\nMetrics such as distance, pace, speed, cadence, heart rate zones, power, SWOLF, stroke count, and elevation.\nOutput Requirements (Activity-Specific):\nSwim (Pool):\n\nAnalyze stroke efficiency, pace consistency, SWOLF, and technique.\nSuggest drills for stroke improvement (e.g., catch-up, fingertip drag).\nRecommend pacing intervals (e.g., 10x100m at target pace with rest).\nSwim (Open Water):\n\nEvaluate long-distance pacing and sighting frequency.\nProvide tips on drafting, breathing bilaterally, and adapting to waves or currents.\nSuggest open water-specific workouts (e.g., race-pace simulations with buoy turns).\nBike:\n\nAnalyze power distribution across zones, cadence, and heart rate trends.\nHighlight inefficiencies (e.g., low cadence on climbs or inconsistent power).\nRecommend specific workouts (e.g., 3x12-minute FTP intervals with 5-minute rest).\nSuggest gear and bike fit optimizations if needed.\nRun:\n\nEvaluate pacing strategy, cadence, and heart rate zones.\nIdentify inefficiencies in stride length or cadence.\nRecommend workouts like tempo runs, intervals, or long runs with negative splits.\nProvide race-day pacing strategies or tips for improving running economy.\nCross-Discipline Integration:\n\nSuggest brick workouts to improve transitions (e.g., 30-minute bike + 10-minute run at race pace).\nRecommend recovery sessions (e.g., easy swim or bike after a hard run).\nAdvise on balancing training load across disciplines.\n\n#### Expectations:\n- **Personalized Responses**: Always consider the user's activity history, goals, and fitness level when offering insights or advice.\n- **Practical Guidance**: Provide clear, actionable recommendations.\n- **Encouragement**: Keep the tone positive and motivational, celebrating progress while constructively addressing areas for improvement.\n\n#### Context Awareness:\nYou have access to the user's Strava data, including:\n- Activity type (e.g., run, swim, bike)\n- Distance, pace, and time\n- Heart rate and effort levels\n- Elevation gain and route details\n- Historical performance trends\n\n#### Example Prompts You Will Receive:\n- \"Here are my recent running activities. How can I improve my pace?\"\n- \"This is my swimming data from this week. What should I focus on to improve my technique?\"\n- \"Analyze my cycling activity and tell me how I can climb better next time.\"\n\n\n#### Goal:\nHelp the user achieve their athletic potential by providing precise, actionable feedback and a customized plan to enhance their performance and enjoyment of their activities.\n\nHere is the Activity Data : \n{{ $json.data }}", +"agent": "conversationalAgent", +"options": {}, +"promptType": "define" +}, +"typeVersion": 1.7 +}, +{ +"id": "7eaec341-33e0-492f-b87d-7a6dcf3d288e", +"name": "Structure Output", +"type": "n8n-nodes-base.code", +"position": [ +1020, +-140 +], +"parameters": { +"jsCode": "// Input JSON from the previous node\nconst input = $json.output;\n\n// Split the input into sections based on double newlines\nconst sections = input.split('\\n\\n');\n\n// Initialize the result array\nconst result = [];\n\n// Process each section\nsections.forEach((section) => {\n const trimmedSection = section.trim();\n\n // Handle headings marked with ** (bold)\n if (/^\\*\\*(.*?)\\*\\*$/.test(trimmedSection)) {\n result.push({ type: 'heading', content: trimmedSection.replace(/\\*\\*(.*?)\\*\\*/, '$1') });\n }\n // Handle bullet lists marked with *\n else if (trimmedSection.startsWith('*')) {\n const listItems = trimmedSection.split('\\n').map((item) => item.trim().replace(/^\\*\\s/, ''));\n result.push({ type: 'list', items: listItems });\n }\n // Handle numbered lists\n else if (/^\\d+\\.\\s/.test(trimmedSection)) {\n const numberedItems = trimmedSection.split('\\n').map((item) => item.trim().replace(/^\\d+\\.\\s/, ''));\n result.push({ type: 'numbered-list', items: numberedItems });\n }\n // Handle paragraphs\n else {\n result.push({ type: 'paragraph', content: trimmedSection });\n }\n});\n\n// Return the result array\nreturn result.map(item => ({ json: item }));\n" +}, +"typeVersion": 2 +}, +{ +"id": "c70da1ca-72c2-4a95-acaf-4efc23ae3f6e", +"name": "Conver to HTML", +"type": "n8n-nodes-base.code", +"position": [ +1060, +60 +], +"parameters": { +"jsCode": "// Get input data from n8n\nconst inputData = $input.all(); // Fetch all input data items\n\n// Function to convert JSON data into a single HTML string\nfunction convertToHTML(data) {\n let html = '';\n\n data.forEach((item) => {\n switch (item.json.type) {\n case 'paragraph':\n html += `

${item.json.content}

`;\n break;\n case 'heading':\n html += `

${item.json.content}

`;\n break;\n case 'list':\n html += '
    ';\n item.json.items.forEach((listItem) => {\n html += `
  • ${listItem}
  • `;\n });\n html += '
';\n break;\n case 'numbered-list':\n html += '
    ';\n item.json.items.forEach((listItem) => {\n html += `
  1. ${listItem}
  2. `;\n });\n html += '
';\n break;\n default:\n break;\n }\n });\n\n return html;\n}\n\n// Convert inputData to a single HTML string\nconst singleHTML = convertToHTML(inputData);\n\n// Return as a single item\nreturn [{ json: { html: singleHTML } }];\n" +}, +"typeVersion": 2 +}, +{ +"id": "b646220c-a0c9-4af7-a2a8-09cec619ecbf", +"name": "Send Email", +"type": "n8n-nodes-base.emailSend", +"position": [ +1420, +0 +], +"parameters": { +"html": "={{ $json.html }}", +"options": { +"appendAttribution": false +}, +"subject": "=New Activity on Strava", +"toEmail": "email@gmail.com", +"fromEmail": "Fitness Coach " +}, +"credentials": { +"smtp": { +"id": "WpZf64vFcOT99dO6", +"name": "SMTP OCI Amjid" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "06d6262d-dd72-4e57-bccb-31d87a9086c9", +"name": "Code", +"type": "n8n-nodes-base.code", +"position": [ +120, +0 +], +"parameters": { +"jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\nfor (const item of $input.all()) {\n item.json.myNewField = 1;\n}\n\nreturn $input.all();" +}, +"typeVersion": 2 +}, +{ +"id": "14ce1a3c-573b-4b17-a9f1-eab5964ac9c8", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +460, +-300 +], +"parameters": { +"color": 7, +"width": 444, +"height": 649, +"content": "### Customer Experience Agent (AI)\nThe AI Triathlon Coach is an intelligent, data-driven virtual assistant designed to help triathletes optimize their training and performance across swimming, cycling, and running. Using advanced algorithms, it analyzes activity data from platforms like Strava and provides actionable insights tailored to the athlete’s goals, experience level, and specific disciplines.\nThis is connected to Gemini 2.0 Flash\n\n" +}, +"typeVersion": 1 +}, +{ +"id": "cccfdcfa-c981-4c8d-8177-d9597b50556c", +"name": "Sticky Note12", +"type": "n8n-nodes-base.stickyNote", +"position": [ +940, +-300 +], +"parameters": { +"color": 5, +"width": 329, +"height": 655, +"content": "### Convert to HTML\nNow the data will be structured and covnerted to HTML" +}, +"typeVersion": 1 +}, +{ +"id": "4618dd06-8754-4ba2-9d86-77d7a4bdbad2", +"name": "Sticky Note13", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-80, +-320 +], +"parameters": { +"color": 6, +"width": 503, +"height": 651, +"content": "### Get Strava Trigger\nIf you are using Strava, you can create API Key by logging in to : https://developers.strava.com/\n\nOnce data is capture you can then structure it, i am commbining all the activity data and sending to next node" +}, +"typeVersion": 1 +}, +{ +"id": "2f9626de-789f-4c28-b1bd-189dc1203d46", +"name": "Sticky Note11", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-580, +-320 +], +"parameters": { +"color": 4, +"width": 475.27306699862953, +"height": 636.1483291619771, +"content": "## Developed by Amjid Ali\n\nThank you for using this workflow template. It has taken me countless hours of hard work, research, and dedication to develop, and I sincerely hope it adds value to your work.\n\nIf you find this template helpful, I kindly ask you to consider supporting my efforts. Your support will help me continue improving and creating more valuable resources.\n\nYou can contribute via PayPal here:\n\nhttp://paypal.me/pmptraining\n\nFor Full Course about ERPNext or Automation using AI follow below link\n\nhttp://lms.syncbricks.com\n\nAdditionally, when sharing this template, I would greatly appreciate it if you include my original information to ensure proper credit is given.\n\nThank you for your generosity and support!\nEmail : amjid@amjidali.com\nhttps://linkedin.com/in/amjidali\nhttps://syncbricks.com\nhttps://youtube.com/@syncbricks" +}, +"typeVersion": 1 +}, +{ +"id": "7b6fb4ba-a20b-40b0-9a40-33f18fb6d28b", +"name": "Sticky Note16", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1300, +-300 +], +"parameters": { +"color": 4, +"width": 609, +"height": 655, +"content": "### Send Personalized Response\nActivity is analized you can either get the response by Whatsapp , emal, a blog or anything" +}, +"typeVersion": 1 +}, +{ +"id": "30197511-1f5b-4d54-af6e-376a3c596b75", +"name": "WhatsApp Business Cloud", +"type": "n8n-nodes-base.whatsApp", +"position": [ +1420, +200 +], +"parameters": { +"operation": "send", +"requestOptions": {}, +"additionalFields": {} +}, +"credentials": { +"whatsAppApi": { +"id": "pDzUNbXM7NG3GZto", +"name": "WhatsApp account" +} +}, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"Code": { +"main": [ +[ +{ +"node": "Combine Everything", +"type": "main", +"index": 0 +} +] +] +}, +"Send Email": { +"main": [ +[] +] +}, +"Fitness Coach": { +"main": [ +[ +{ +"node": "Structure Output", +"type": "main", +"index": 0 +} +] +] +}, +"Conver to HTML": { +"main": [ +[ +{ +"node": "Send Email", +"type": "main", +"index": 0 +} +] +] +}, +"Strava Trigger": { +"main": [ +[ +{ +"node": "Code", +"type": "main", +"index": 0 +} +] +] +}, +"Structure Output": { +"main": [ +[ +{ +"node": "Conver to HTML", +"type": "main", +"index": 0 +} +] +] +}, +"Combine Everything": { +"main": [ +[ +{ +"node": "Fitness Coach", +"type": "main", +"index": 0 +} +] +] +}, +"Google Gemini Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Fitness Coach", +"type": "ai_languageModel", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/AI Powered Web Scraping with Jina, Google Sheets and OpenAI _ the EASY way.txt b/AI Powered Web Scraping with Jina, Google Sheets and OpenAI _ the EASY way.txt new file mode 100644 index 0000000..b177c96 --- /dev/null +++ b/AI Powered Web Scraping with Jina, Google Sheets and OpenAI _ the EASY way.txt @@ -0,0 +1,257 @@ +{ +"nodes": [ +{ +"id": "c3ef40df-084e-435c-9a11-3aa0a2f94f36", +"name": "When clicking \"Test workflow\"", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +740, +520 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "e0583472-a450-4582-83bc-84a014bea543", +"name": "Split Out", +"type": "n8n-nodes-base.splitOut", +"position": [ +1640, +520 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "output.results" +}, +"typeVersion": 1 +}, +{ +"id": "b8aa573d-5b63-4669-900f-bcc915b6ad41", +"name": "Save to Google Sheets", +"type": "n8n-nodes-base.googleSheets", +"position": [ +1900, +520 +], +"parameters": { +"columns": { +"value": {}, +"schema": [ +{ +"id": "name", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "name", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "price", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "price", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "availability", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "availability", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "image", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "image", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "link", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "link", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "autoMapInputData", +"matchingColumns": [ +"Book prices" +] +}, +"options": {}, +"operation": "append", +"sheetName": { +"__rl": true, +"mode": "list", +"value": 258629074, +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1VDbfi2PpeheD2ZlO6feX3RdMeSsm0XukQlNVW8uVcuo/edit#gid=258629074", +"cachedResultName": "Sheet2" +}, +"documentId": { +"__rl": true, +"mode": "list", +"value": "1VDbfi2PpeheD2ZlO6feX3RdMeSsm0XukQlNVW8uVcuo", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1VDbfi2PpeheD2ZlO6feX3RdMeSsm0XukQlNVW8uVcuo/edit?usp=drivesdk", +"cachedResultName": "Book Prices" +} +}, +"credentials": { +"googleSheetsOAuth2Api": { +"id": "GHRceL2SKjXxz0Dx", +"name": "Google Sheets account" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "a63c3ab3-6aab-43b2-8af6-8b00e24e0ee6", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +1300, +700 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "5oYe8Cxj7liOPAKk", +"name": "Derek T" +} +}, +"typeVersion": 1 +}, +{ +"id": "40326966-0c46-4df2-8d80-fa014e05b693", +"name": "Information Extractor", +"type": "@n8n/n8n-nodes-langchain.informationExtractor", +"position": [ +1260, +520 +], +"parameters": { +"text": "={{ $json.data }}", +"options": { +"systemPromptTemplate": "You are an expert extraction algorithm.\nOnly extract relevant information from the text.\nIf you do not know the value of an attribute asked to extract, you may omit the attribute's value.\nAlways output the data in a json array called results. Each book should have a title, price, availability and product_url, image_url" +}, +"schemaType": "manual", +"inputSchema": "{\n \"results\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"price\": {\n \"type\": \"string\"\n },\n \"title\": {\n \"type\": \"string\"\n },\n \"image_url\": {\n \"type\": \"string\"\n },\n \"product_url\": {\n \"type\": \"string\"\n },\n \"availability\": {\n \"type\": \"string\"\n } \n }\n }\n }\n}" +}, +"typeVersion": 1 +}, +{ +"id": "8ddca560-8da7-4090-b865-0523f95ca463", +"name": "Jina Fetch", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1020, +520 +], +"parameters": { +"url": "https://r.jina.ai/http://books.toscrape.com/catalogue/category/books/historical-fiction_4/index.html", +"options": { +"allowUnauthorizedCerts": true +}, +"authentication": "genericCredentialType", +"genericAuthType": "httpHeaderAuth" +}, +"credentials": { +"httpHeaderAuth": { +"id": "ALBmOXmADcPmyHr1", +"name": "jina" +} +}, +"typeVersion": 4.1 +}, +{ +"id": "b1745cea-fdbe-4f14-b09c-884549beac7e", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +80, +320 +], +"parameters": { +"color": 5, +"width": 587, +"height": 570, +"content": "## Start here: Step-by Step Youtube Tutorial :star:\n\n[![AI Powered Web Scraping : the EASY way with n8n and Jina.ai (no-code!)](https://img.youtube.com/vi/f3AJYXHirr8/sddefault.jpg)](https://youtu.be/f3AJYXHirr8)\n\n[Google Sheet Example](https://docs.google.com/spreadsheets/d/1VDbfi2PpeheD2ZlO6feX3RdMeSsm0XukQlNVW8uVcuo/edit?usp=sharing)\n\n\n" +}, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"Split Out": { +"main": [ +[ +{ +"node": "Save to Google Sheets", +"type": "main", +"index": 0 +} +] +] +}, +"Jina Fetch": { +"main": [ +[ +{ +"node": "Information Extractor", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Information Extractor", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Information Extractor": { +"main": [ +[ +{ +"node": "Split Out", +"type": "main", +"index": 0 +} +] +] +}, +"When clicking \"Test workflow\"": { +"main": [ +[ +{ +"node": "Jina Fetch", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/AI Social Media Caption Creator creates social media post captions in Airtable.txt b/AI Social Media Caption Creator creates social media post captions in Airtable.txt new file mode 100644 index 0000000..6dc2f57 --- /dev/null +++ b/AI Social Media Caption Creator creates social media post captions in Airtable.txt @@ -0,0 +1,1119 @@ +{ +"id": "V8ypWn7oaOVS3zH0", +"meta": { +"instanceId": "1acdaec6c8e84424b4715cf41a9f7ec057947452db21cd2e22afbc454c8711cd", +"templateCredsSetupCompleted": true +}, +"name": "AI Social Media Caption Creator", +"tags": [], +"nodes": [ +{ +"id": "12d0470e-1030-47c4-8bd0-890d5b3a5976", +"name": "AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +120, +-120 +], +"parameters": { +"text": "={{ $json['Briefing'] }}", +"options": { +"systemMessage": "= \nYOU ARE AN EXPERT CAPTION CREATOR AGENT FOR INSTAGRAM, DESIGNED FOR USE IN N8N WORKFLOWS. YOUR TASK IS TO CREATE A CREATIVE, TARGET AUDIENCE-ORIENTED, AND MEMORABLE CAPTION BASED ON THE BRIEFING: `{{ $json['Briefing'] }}`. YOU SHOULD RETRIEVE ADDITIONAL INFORMATION ABOUT THE TARGET AUDIENCE AND PREFERRED WORDING USING THE TOOL \"BACKGROUND INFO\" TO MAXIMIZE THE QUALITY AND RELEVANCE OF THE CAPTION. \n\n###INSTRUCTIONS### \n\n- YOU MUST: \n 1. READ AND UNDERSTAND THE BRIEFING CAREFULLY. \n 2. RETRIEVE ADDITIONAL DATA ABOUT THE TARGET AUDIENCE AND COMMUNICATION STYLE USING THE \"BACKGROUND INFO\" TOOL. \n 3. CREATE A CAPTION THAT IS CREATIVE, ENGAGING, AND TAILORED TO THE TARGET AUDIENCE. \n 4. ENSURE THAT THE CAPTION INCLUDES A CLEAR CALL-TO-ACTION (CTA) THAT ENCOURAGES USERS TO TAKE ACTION (E.G., LIKE, COMMENT, OR CLICK). \n 5. OUTPUT ONLY THE FINAL CAPTION WITHOUT ANY ACCOMPANYING EXPLANATIONS, FEEDBACK, OR COMMENTS. \n\n###CHAIN OF THOUGHTS### \n\n1. **UNDERSTANDING THE BRIEFING**: \n - THOROUGHLY READ THE BRIEFING PROVIDED UNDER `{{ $json['Briefing/Notizen'] }}`. \n - IDENTIFY THE MAIN FOCUS OF THE POST (E.G., PRODUCT PROMOTION, INSPIRATION, INFORMATION). \n - NOTE THE KEY THEMES, MOOD, AND DESIRED IMPACT. \n\n2. **TARGET AUDIENCE ANALYSIS**: \n - USE THE \"BACKGROUND INFO\" TOOL TO: \n - RETRIEVE THE TARGET AUDIENCE'S AGE, INTERESTS, AND NEEDS. \n - DEFINE THE APPROPRIATE TONE (FRIENDLY, PROFESSIONAL, INSPIRATIONAL, ETC.). \n\n3. **CREATIVE CAPTION DEVELOPMENT**: \n - DEVELOP AN OPENING SENTENCE THAT GRABS THE TARGET AUDIENCE'S ATTENTION. \n - WRITE A BODY THAT CONVEYS THE CORE MESSAGE OF THE POST AND RESONATES WITH THE TARGET AUDIENCE. \n - ADD AN INVITING CTA (E.G., \"What do you think? Share your thoughts in the comments!\" OR \"Click the link in our bio!\"). \n\n4. **FINALIZATION**: \n - CHECK THE CAPTION FOR CLARITY, CONSISTENCY, AND GRAMMAR. \n - ENSURE THAT IT ALIGNS WITH THE TARGET AUDIENCE AND THE IDENTIFIED TONE. \n - MAXIMIZE CREATIVITY AND ENTERTAINMENT VALUE WITHOUT LOSING THE ESSENTIAL MESSAGE. \n\n5. **OUTPUT**: \n - OUTPUT ONLY THE FINAL CAPTION WITHOUT ANY ACCOMPANYING COMMENTS, FEEDBACK, OR EXPLANATIONS. \n\n###WHAT NOT TO DO### \n\n- **DO NOT OUTPUT ANY ACCOMPANYING TEXTS, EXPLANATIONS, OR FEEDBACK** ABOUT THE CAPTION. \n- **DO NOT WORK WITHOUT PRIOR TARGET AUDIENCE ANALYSIS**. \n- **DO NOT USE CLICHÉ PHRASES** THAT HAVE NO RELEVANCE TO THE TARGET AUDIENCE. \n- **DO NOT ALLOW ANY SPELLING OR GRAMMATICAL ERRORS**. \n\n\n" +}, +"promptType": "define" +}, +"typeVersion": 1.7 +}, +{ +"id": "3a6fcc4e-46ed-4f80-a9ce-f955e3d47222", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +80, +100 +], +"parameters": { +"model": "gpt-4o", +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "EjchNb5GBqYh0Cqn", +"name": "OpenAi account" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "1a8b6f44-b9cf-4c80-ac5d-358d7cf61404", +"name": "Window Buffer Memory", +"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow", +"position": [ +220, +100 +], +"parameters": { +"sessionKey": "={{ $json.id }}", +"sessionIdType": "customKey" +}, +"typeVersion": 1.3 +}, +{ +"id": "a4972690-5fa5-48bd-b5fd-b1899076b6c0", +"name": "Get Airtable Record Data", +"type": "n8n-nodes-base.airtable", +"position": [ +-40, +-120 +], +"parameters": { +"id": "={{ $json.id }}", +"base": { +"__rl": true, +"mode": "list", +"value": "appXvZviYORVbPEaS", +"cachedResultUrl": "https://airtable.com/appXvZviYORVbPEaS", +"cachedResultName": "Redaktionsplan 2025 - E&P Reisen" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tbllbO3DyTNie9Pga", +"cachedResultUrl": "https://airtable.com/appLe3fQHeaRN7kWG/tbllbO3DyTNie9Pga", +"cachedResultName": "Redaktionsplanung" +}, +"options": {} +}, +"credentials": { +"airtableTokenApi": { +"id": "pMphGrxsDsELetHZ", +"name": "Airtable account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "27519b09-7ce7-4a8b-abe7-dc630eea24b0", +"name": "Wait 1 Minute", +"type": "n8n-nodes-base.wait", +"position": [ +-200, +-120 +], +"webhookId": "757986ac-2e3f-4a5b-993d-b53b8ae12258", +"parameters": { +"unit": "minutes", +"amount": 1 +}, +"typeVersion": 1.1 +}, +{ +"id": "b9e7c19a-e468-4f83-b1a4-2013af36caa0", +"name": "Format Fields", +"type": "n8n-nodes-base.set", +"position": [ +440, +-120 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "c7243724-463f-4732-8866-efdf19837f17", +"name": "SoMe Text", +"type": "string", +"value": "={{ $json.output }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "5d4e6149-20a5-42bf-be6b-6ebaa31c517e", +"name": "Post Caption into Airtable Record", +"type": "n8n-nodes-base.airtable", +"position": [ +600, +-120 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appXvZviYORVbPEaS", +"cachedResultUrl": "https://airtable.com/appXvZviYORVbPEaS", +"cachedResultName": "Redaktionsplan 2025 - E&P Reisen" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblxsKj5PtumCR9um", +"cachedResultUrl": "https://airtable.com/appXvZviYORVbPEaS/tblxsKj5PtumCR9um", +"cachedResultName": "Redaktionsplanung" +}, +"columns": { +"value": { +"id": "={{ $('Get Airtable Record Data').item.json.id }}", +"Posten": false, +"SoMe_Text_KI": "={{ $json['SoMe Text'] }}", +"Werbeanzeige": false +}, +"schema": [ +{ +"id": "id", +"type": "string", +"display": true, +"removed": false, +"readOnly": true, +"required": false, +"displayName": "id", +"defaultMatch": true +}, +{ +"id": "Beitragsname", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Beitragsname", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Marke", +"type": "options", +"display": true, +"options": [ +{ +"name": "E&P", +"value": "E&P" +}, +{ +"name": "SER", +"value": "SER" +}, +{ +"name": "SBW", +"value": "SBW" +}, +{ +"name": "SZO", +"value": "SZO" +}, +{ +"name": "UCH", +"value": "UCH" +} +], +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Marke", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Netzwerk", +"type": "array", +"display": true, +"options": [ +{ +"name": "Facebook", +"value": "Facebook" +}, +{ +"name": "Instagram", +"value": "Instagram" +}, +{ +"name": "Threads", +"value": "Threads" +}, +{ +"name": "TikTok", +"value": "TikTok" +}, +{ +"name": "YouTube Shorts", +"value": "YouTube Shorts" +}, +{ +"name": "MyBusiness", +"value": "MyBusiness" +}, +{ +"name": "Push", +"value": "Push" +}, +{ +"name": "WhatsApp", +"value": "WhatsApp" +}, +{ +"name": "LinkedIn", +"value": "LinkedIn" +}, +{ +"name": "CleverPush", +"value": "CleverPush" +}, +{ +"name": "SBW", +"value": "SBW" +} +], +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Netzwerk", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Status", +"type": "options", +"display": true, +"options": [ +{ +"name": "Brainstorming", +"value": "Brainstorming" +}, +{ +"name": "Bitte formulieren", +"value": "Bitte formulieren" +}, +{ +"name": "Bitte checken/freigeben", +"value": "Bitte checken/freigeben" +}, +{ +"name": "Bitte ändern", +"value": "Bitte ändern" +}, +{ +"name": "Warten auf externe Rückmeldung", +"value": "Warten auf externe Rückmeldung" +}, +{ +"name": "Freigabe erteilt/Bitte einplanen", +"value": "Freigabe erteilt/Bitte einplanen" +}, +{ +"name": "Geplant/Veröffentlicht", +"value": "Geplant/Veröffentlicht" +} +], +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Status", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Zuständigkeit", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Zuständigkeit", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "KW", +"type": "options", +"display": true, +"options": [ +{ +"name": "KW 1", +"value": "KW 1" +}, +{ +"name": "KW 2", +"value": "KW 2" +}, +{ +"name": "KW 3", +"value": "KW 3" +}, +{ +"name": "KW 4", +"value": "KW 4" +}, +{ +"name": "KW 5", +"value": "KW 5" +}, +{ +"name": "KW 6", +"value": "KW 6" +}, +{ +"name": "KW 7", +"value": "KW 7" +}, +{ +"name": "KW 8", +"value": "KW 8" +}, +{ +"name": "KW 9", +"value": "KW 9" +}, +{ +"name": "KW 10", +"value": "KW 10" +}, +{ +"name": "KW 11", +"value": "KW 11" +}, +{ +"name": "KW 12", +"value": "KW 12" +}, +{ +"name": "KW 13", +"value": "KW 13" +}, +{ +"name": "KW 14", +"value": "KW 14" +}, +{ +"name": "KW 15", +"value": "KW 15" +}, +{ +"name": "KW 16", +"value": "KW 16" +}, +{ +"name": "KW 17", +"value": "KW 17" +}, +{ +"name": "KW 18", +"value": "KW 18" +}, +{ +"name": "KW 19", +"value": "KW 19" +}, +{ +"name": "KW 20", +"value": "KW 20" +}, +{ +"name": "KW 21", +"value": "KW 21" +}, +{ +"name": "KW 22", +"value": "KW 22" +}, +{ +"name": "KW 23", +"value": "KW 23" +}, +{ +"name": "KW 24", +"value": "KW 24" +}, +{ +"name": "KW 25", +"value": "KW 25" +}, +{ +"name": "KW 26", +"value": "KW 26" +}, +{ +"name": "KW 27", +"value": "KW 27" +}, +{ +"name": "KW 28", +"value": "KW 28" +}, +{ +"name": "KW 29", +"value": "KW 29" +}, +{ +"name": "KW 30", +"value": "KW 30" +}, +{ +"name": "KW 31", +"value": "KW 31" +}, +{ +"name": "KW 32", +"value": "KW 32" +}, +{ +"name": "KW 33", +"value": "KW 33" +}, +{ +"name": "KW 34", +"value": "KW 34" +}, +{ +"name": "KW 35", +"value": "KW 35" +}, +{ +"name": "KW 36", +"value": "KW 36" +}, +{ +"name": "KW 37", +"value": "KW 37" +}, +{ +"name": "KW 38", +"value": "KW 38" +}, +{ +"name": "KW 39", +"value": "KW 39" +}, +{ +"name": "KW 40", +"value": "KW 40" +}, +{ +"name": "KW 41", +"value": "KW 41" +}, +{ +"name": "KW 42", +"value": "KW 42" +}, +{ +"name": "KW 43", +"value": "KW 43" +}, +{ +"name": "KW 44", +"value": "KW 44" +}, +{ +"name": "KW 45", +"value": "KW 45" +}, +{ +"name": "KW 46", +"value": "KW 46" +}, +{ +"name": "KW 47", +"value": "KW 47" +}, +{ +"name": "KW 48", +"value": "KW 48" +}, +{ +"name": "KW 49", +"value": "KW 49" +}, +{ +"name": "KW 50", +"value": "KW 50" +}, +{ +"name": "KW 51", +"value": "KW 51" +}, +{ +"name": "KW 52", +"value": "KW 52" +}, +{ +"name": "47", +"value": "47" +} +], +"removed": false, +"readOnly": false, +"required": false, +"displayName": "KW", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Veröffentlichungsdatum SoMe", +"type": "dateTime", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Veröffentlichungsdatum SoMe", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Destination/Haus", +"type": "array", +"display": true, +"options": [ +{ +"name": "1: Allgemein", +"value": "1: Allgemein" +}, +{ +"name": "Ahrntal - Bruggerhof", +"value": "Ahrntal - Bruggerhof" +}, +{ +"name": "Ahrntal - Christiler", +"value": "Ahrntal - Christiler" +}, +{ +"name": "Ahrntal - Griesfeld", +"value": "Ahrntal - Griesfeld" +}, +{ +"name": "Davos - Allgemein", +"value": "Davos - Allgemein" +}, +{ +"name": "Davos - Schweizerhaus", +"value": "Davos - Schweizerhaus" +}, +{ +"name": "Davos - Schwendi", +"value": "Davos - Schwendi" +}, +{ +"name": "Davos - Waldschlössli", +"value": "Davos - Waldschlössli" +}, +{ +"name": "Kleinwalsertal - Heuberghaus", +"value": "Kleinwalsertal - Heuberghaus" +}, +{ +"name": "L2A - SZO", +"value": "L2A - SZO" +}, +{ +"name": "L2A - UCH", +"value": "L2A - UCH" +}, +{ +"name": "Lenzerheide - Jenatsch", +"value": "Lenzerheide - Jenatsch" +}, +{ +"name": "Montafon - Josefsheim", +"value": "Montafon - Josefsheim" +}, +{ +"name": "Montafon - Klein Tirol", +"value": "Montafon - Klein Tirol" +}, +{ +"name": "PdS - Jolimont", +"value": "PdS - Jolimont" +}, +{ +"name": "PdS - Victoria", +"value": "PdS - Victoria" +}, +{ +"name": "Saalbach - Allgemein", +"value": "Saalbach - Allgemein" +}, +{ +"name": "Saalbach - Steinachhof", +"value": "Saalbach - Steinachhof" +}, +{ +"name": "Schweiz - Allgemein", +"value": "Schweiz - Allgemein" +}, +{ +"name": "Stubaital - Ranalt", +"value": "Stubaital - Ranalt" +}, +{ +"name": "Team", +"value": "Team" +}, +{ +"name": "VT - SBW", +"value": "VT - SBW" +}, +{ +"name": "SurfZone", +"value": "SurfZone" +}, +{ +"name": "lenzerheide - allgemein", +"value": "lenzerheide - allgemein" +}, +{ +"name": "Family", +"value": "Family" +}, +{ +"name": "Jobs", +"value": "Jobs" +}, +{ +"name": "L2A", +"value": "L2A" +}, +{ +"name": "Davos - Spinabad", +"value": "Davos - Spinabad" +} +], +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Destination/Haus", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Content Art", +"type": "options", +"display": true, +"options": [ +{ +"name": "Bild(er)", +"value": "Bild(er)" +}, +{ +"name": "Video", +"value": "Video" +}, +{ +"name": "Carousel", +"value": "Carousel" +}, +{ +"name": "Story", +"value": "Story" +}, +{ +"name": "Reel", +"value": "Reel" +}, +{ +"name": "Link", +"value": "Link" +}, +{ +"name": "Bilderalbum", +"value": "Bilderalbum" +}, +{ +"name": "Text", +"value": "Text" +}, +{ +"name": "Push", +"value": "Push" +} +], +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Content Art", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Briefing/Notizen", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Briefing/Notizen", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Linkmanager-Link", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Linkmanager-Link", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Short Link", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Short Link", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Story", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Story", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "MyBusiness Link", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "MyBusiness Link", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "SoMe Text", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "SoMe Text", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Anzahl Hashtags", +"type": "string", +"display": true, +"removed": true, +"readOnly": true, +"required": false, +"displayName": "Anzahl Hashtags", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Anzahl Zeichen", +"type": "string", +"display": true, +"removed": true, +"readOnly": true, +"required": false, +"displayName": "Anzahl Zeichen", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "SoMe Media", +"type": "array", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "SoMe Media", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Link zum Canva Layout", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Link zum Canva Layout", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Storylink Canva", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Storylink Canva", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "MyBusiness Layout", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "MyBusiness Layout", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Posten", +"type": "boolean", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Posten", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "created_at", +"type": "string", +"display": true, +"removed": true, +"readOnly": true, +"required": false, +"displayName": "created_at", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "SoMe_Text_KI", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "SoMe_Text_KI", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Werbeanzeige", +"type": "boolean", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "Werbeanzeige", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [ +"id", +"SoMe_Text_KI" +], +"attemptToConvertTypes": false, +"convertFieldsToString": false +}, +"options": {}, +"operation": "update" +}, +"credentials": { +"airtableTokenApi": { +"id": "pMphGrxsDsELetHZ", +"name": "Airtable account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "ddc9159e-0da7-4844-84c5-eca981b9d52f", +"name": "Airtable Trigger: New Record", +"type": "n8n-nodes-base.airtableTrigger", +"position": [ +-360, +-120 +], +"parameters": { +"baseId": { +"__rl": true, +"mode": "id", +"value": "appXvZviYORVbPEaS" +}, +"tableId": { +"__rl": true, +"mode": "id", +"value": "tblxsKj5PtumCR9um" +}, +"pollTimes": { +"item": [ +{ +"mode": "everyMinute" +} +] +}, +"triggerField": "created_at", +"authentication": "airtableTokenApi", +"additionalFields": {} +}, +"credentials": { +"airtableTokenApi": { +"id": "pMphGrxsDsELetHZ", +"name": "Airtable account" +} +}, +"typeVersion": 1 +}, +{ +"id": "a71626b0-43ba-430b-bd2f-8cc121676e46", +"name": "Background Info", +"type": "n8n-nodes-base.airtableTool", +"position": [ +360, +100 +], +"parameters": { +"id": "reckd97lgylz93Ht5", +"base": { +"__rl": true, +"mode": "list", +"value": "appXvZviYORVbPEaS", +"cachedResultUrl": "https://airtable.com/appXvZviYORVbPEaS", +"cachedResultName": "Redaktionsplan 2025 - E&P Reisen" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tblMmE9cjgNZCoIO1", +"cachedResultUrl": "https://airtable.com/appLe3fQHeaRN7kWG/tblMmE9cjgNZCoIO1", +"cachedResultName": "Good to know" +}, +"options": {}, +"descriptionType": "manual", +"toolDescription": "Read data from Airtable" +}, +"credentials": { +"airtableTokenApi": { +"id": "pMphGrxsDsELetHZ", +"name": "Airtable account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "9c422e74-155c-4714-87aa-16b31bd73e5b", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-680, +80 +], +"parameters": { +"width": 660, +"height": 680, +"content": "# Welcome to my AI Social Media Caption Creator Workflow!\n\nThis workflow automatically creates a social media post caption in an editorial plan in Airtable. It also uses background information on the target group, tonality, etc. stored in Airtable.\n\n## This workflow has the following sequence:\n\n1. Airtable trigger (scan for new records every minute)\n2. Wait 1 Minute so the Airtable record creator has time to write the Briefing field\n3. retrieval of Airtable record data\n4. AI Agent to write a caption for a social media post. The agent is instructed to use background information stored in Airtable (such as target group, tonality, etc.) to create the post.\n5. Format the output and assign it to the correct field in Airtable.\n6. Post the caption into Airtable record.\n\n## The following accesses are required for the workflow:\n- Airtable Database: [Documentation](https://docs.n8n.io/integrations/builtin/credentials/airtable)\n- AI API access (e.g. via OpenAI, Anthropic, Google or Ollama)\n\n### Example of an editorial plan in Airtable: https://airtable.com/appIXeIkDPjQefHXN/shrwcY45g48RpcvvC\nFor this workflow you need the Airtable fields \"created_at\", \"Briefing\" and \"SoMe_Text_AI\"\n\nYou can contact me via LinkedIn, if you have any questions: https://www.linkedin.com/in/friedemann-schuetz" +}, +"typeVersion": 1 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "50376a31-f279-4f5d-9204-82cacb596751", +"connections": { +"AI Agent": { +"main": [ +[ +{ +"node": "Format Fields", +"type": "main", +"index": 0 +} +] +] +}, +"Format Fields": { +"main": [ +[ +{ +"node": "Post Caption into Airtable Record", +"type": "main", +"index": 0 +} +] +] +}, +"Wait 1 Minute": { +"main": [ +[ +{ +"node": "Get Airtable Record Data", +"type": "main", +"index": 0 +} +] +] +}, +"Background Info": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Window Buffer Memory": { +"ai_memory": [ +[ +{ +"node": "AI Agent", +"type": "ai_memory", +"index": 0 +} +] +] +}, +"Get Airtable Record Data": { +"main": [ +[ +{ +"node": "AI Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Airtable Trigger: New Record": { +"main": [ +[ +{ +"node": "Wait 1 Minute", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/AI Voice Chat using Webhook, Memory Manager, OpenAI, Google Gemini & ElevenLabs.txt b/AI Voice Chat using Webhook, Memory Manager, OpenAI, Google Gemini & ElevenLabs.txt new file mode 100644 index 0000000..2dfb8eb --- /dev/null +++ b/AI Voice Chat using Webhook, Memory Manager, OpenAI, Google Gemini & ElevenLabs.txt @@ -0,0 +1,423 @@ +{ +"id": "TtoDcjgthgA4NTkU", +"meta": { +"instanceId": "fb261afc5089eae952e09babdadd9983000b3d863639802f6ded8c5be2e40067", +"templateCredsSetupCompleted": true +}, +"name": "AI Voice Chat using Webhook, Memory Manager, OpenAI, Google Gemini & ElevenLabs", +"tags": [ +{ +"id": "mqOrNvCDgQLzPA2x", +"name": "Workflows", +"createdAt": "2024-08-07T14:18:53.614Z", +"updatedAt": "2024-08-07T14:18:53.614Z" +} +], +"nodes": [ +{ +"id": "86cbf150-df4f-42f7-b7b3-e03c32e6f23c", +"name": "Get Chat", +"type": "@n8n/n8n-nodes-langchain.memoryManager", +"position": [ +1700, +-400 +], +"parameters": { +"options": {} +}, +"typeVersion": 1, +"alwaysOutputData": true +}, +{ +"id": "a9153a24-e902-4f29-9b83-447317ce3119", +"name": "Insert Chat", +"type": "@n8n/n8n-nodes-langchain.memoryManager", +"position": [ +2540, +-400 +], +"parameters": { +"mode": "insert", +"messages": { +"messageValues": [ +{ +"type": "user", +"message": "={{ $('OpenAI - Speech to Text').item.json[\"text\"] }}" +}, +{ +"type": "ai", +"message": "={{ $json.text }}" +} +] +} +}, +"typeVersion": 1, +"alwaysOutputData": true +}, +{ +"id": "f5c272d4-248b-45a5-87b5-eb659a865d05", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1664, +-491 +], +"parameters": { +"color": 6, +"width": 486.4746124819703, +"height": 238.4911357933579, +"content": "## Get Context" +}, +"typeVersion": 1 +}, +{ +"id": "32ad17ca-0045-487d-9387-71c2e73629d4", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2510, +-489 +], +"parameters": { +"color": 6, +"width": 321.2536584847704, +"height": 231.05945912581728, +"content": "## Save Context" +}, +"typeVersion": 1 +}, +{ +"id": "17ae4f1a-6192-4c52-8157-3cb47b37e0fb", +"name": "Aggregate", +"type": "n8n-nodes-base.aggregate", +"position": [ +2020, +-400 +], +"parameters": { +"options": {}, +"aggregate": "aggregateAllItemData", +"destinationFieldName": "context" +}, +"typeVersion": 1, +"alwaysOutputData": true +}, +{ +"id": "00b3081e-fbcd-489b-b45a-4e847c346594", +"name": "Window Buffer Memory", +"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow", +"position": [ +2080, +-100 +], +"parameters": { +"sessionKey": "test-0dacb3b5-4bcd-47dd-8456-dcfd8c258204", +"sessionIdType": "customKey" +}, +"typeVersion": 1.2 +}, +{ +"id": "55ca2790-e905-414a-a9f6-7d88a9e5807d", +"name": "Google Gemini Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini", +"position": [ +2220, +-100 +], +"parameters": { +"options": {}, +"modelName": "models/gemini-1.5-flash" +}, +"credentials": { +"googlePalmApi": { +"id": "2bUF1ZI9hoMIM5XN", +"name": "Google Gemini(PaLM) Api account" +} +}, +"typeVersion": 1 +}, +{ +"id": "e8b3433f-b205-404c-9f05-504556d6b6dd", +"name": "Respond to Webhook", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +3560, +-400 +], +"parameters": { +"options": {}, +"respondWith": "binary" +}, +"typeVersion": 1.1 +}, +{ +"id": "de296743-5ac7-454b-bf3a-d020cc024511", +"name": "ElevenLabs - Generate Audio", +"type": "n8n-nodes-base.httpRequest", +"position": [ +3240, +-400 +], +"parameters": { +"url": "=https://api.elevenlabs.io/v1/text-to-speech/{{voice id}}", +"method": "POST", +"options": {}, +"sendBody": true, +"sendHeaders": true, +"authentication": "genericCredentialType", +"bodyParameters": { +"parameters": [ +{ +"name": "text", +"value": "={{ $('Basic LLM Chain').item.json.text }}" +} +] +}, +"genericAuthType": "httpCustomAuth", +"headerParameters": { +"parameters": [ +{ +"name": "Content-Type", +"value": "application/json" +} +] +} +}, +"credentials": { +"httpCustomAuth": { +"id": "lnGfV4BlxSE6Xc4X", +"name": "Eleven Labs" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "214e15f2-8a16-4598-b4ac-9fc2ec6545e6", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +3040, +-560 +], +"parameters": { +"width": 468.73250812192407, +"height": 843.7602354099661, +"content": "* ### For the Text-to-Speech part, we'll use ElevenLabs.io, which is free and offers a variety of voices to choose from. However, you can also use the OpenAI `\"Generate audio\"` node instead.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n* ### Since there is no pre-built node for `\"ElevenLabs\"` in n8n, we'll connect to it through its API using the \"HTTP Request\" node.\n\n## Prerequisites:\n* ### `\"ElevenLabs API Key\"` (you can obtain it from their website).\n* ### `\"Voice ID\"` (you can also get it from ElevenLabs' \"Voice Library\").\n## Setup\n* ### In the URL parameter, replace \"{{voice id}}\" at the end of the URL with the Voice ID you obtained from ElevenLabs.io.\n* ### To set up your API Key, add custom authentication and include the following `JSON` with your acual ElevenLabs API Key:\n```json\n{\n \"headers\": {\n \"xi-api-key\": \"put-your-API-Key-here\"\n }\n}\n```" +}, +"typeVersion": 1 +}, +{ +"id": "94ad934c-4a13-47b1-83a5-76fab43b3a47", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1663, +-598 +], +"parameters": { +"color": 6, +"width": 487.4293487597613, +"height": 91.01435855269375, +"content": "### The \"Get Chat,\" \"Insert Chat,\" and \"Window Buffer Memory\" nodes will help the LLM model maintain context throughout the conversation." +}, +"typeVersion": 1 +}, +{ +"id": "0a96f48d-0d8b-4240-9eab-a681bfd4c8b5", +"name": "Limit", +"type": "n8n-nodes-base.limit", +"position": [ +2900, +-400 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "9a5d4ddb-6403-4758-858e-9fbe10c421a9", +"name": "Basic LLM Chain", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +2200, +-400 +], +"parameters": { +"text": "={{ $('OpenAI - Speech to Text').item.json[\"text\"] }}", +"messages": { +"messageValues": [ +{ +"type": "AIMessagePromptTemplate", +"message": "=To maintain context and fully understand the user's question, always review the previous conversation between you and him before providing an answer.\nThis is the previous conversation:\n{{ $('Aggregate').item.json[\"context\"].map(m => `\nHuman: ${m.human || 'undefined'}\nAI Assistant: ${m.ai || 'undefined'}\n`).join('') }}" +} +] +}, +"promptType": "define" +}, +"typeVersion": 1.4 +}, +{ +"id": "f2f99895-9678-41b8-ad28-db40e1e23dc0", +"name": "Webhook", +"type": "n8n-nodes-base.webhook", +"position": [ +1320, +-400 +], +"webhookId": "e9f611eb-a8dd-4520-8d24-9f36deaca528", +"parameters": { +"path": "voice_message", +"options": {}, +"httpMethod": "POST", +"responseMode": "responseNode" +}, +"typeVersion": 2 +}, +{ +"id": "d9a5fb04-4c02-4da4-b690-7b0ecd0ae052", +"name": "OpenAI - Speech to Text", +"type": "@n8n/n8n-nodes-langchain.openAi", +"position": [ +1500, +-400 +], +"parameters": { +"options": {}, +"resource": "audio", +"operation": "transcribe", +"binaryPropertyName": "voice_message" +}, +"credentials": { +"openAiApi": { +"id": "2Cije3KX7OIVwn9B", +"name": "n8n OpenAI" +} +}, +"typeVersion": 1.3 +} +], +"active": true, +"pinData": {}, +"settings": { +"callerPolicy": "workflowsFromSameOwner", +"executionOrder": "v1", +"saveManualExecutions": true +}, +"versionId": "fe5792ca-03d7-4cdd-96db-20f4cd479c7e", +"connections": { +"Limit": { +"main": [ +[ +{ +"node": "ElevenLabs - Generate Audio", +"type": "main", +"index": 0 +} +] +] +}, +"Webhook": { +"main": [ +[ +{ +"node": "OpenAI - Speech to Text", +"type": "main", +"index": 0 +} +] +] +}, +"Get Chat": { +"main": [ +[ +{ +"node": "Aggregate", +"type": "main", +"index": 0 +} +] +] +}, +"Aggregate": { +"main": [ +[ +{ +"node": "Basic LLM Chain", +"type": "main", +"index": 0 +} +] +] +}, +"Insert Chat": { +"main": [ +[ +{ +"node": "Limit", +"type": "main", +"index": 0 +} +] +] +}, +"Basic LLM Chain": { +"main": [ +[ +{ +"node": "Insert Chat", +"type": "main", +"index": 0 +} +] +] +}, +"Window Buffer Memory": { +"ai_memory": [ +[ +{ +"node": "Insert Chat", +"type": "ai_memory", +"index": 0 +}, +{ +"node": "Get Chat", +"type": "ai_memory", +"index": 0 +} +] +] +}, +"OpenAI - Speech to Text": { +"main": [ +[ +{ +"node": "Get Chat", +"type": "main", +"index": 0 +} +] +] +}, +"Google Gemini Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Basic LLM Chain", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"ElevenLabs - Generate Audio": { +"main": [ +[ +{ +"node": "Respond to Webhook", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/AI Voice Chatbot with ElevenLabs & OpenAI for Customer Service and Restaurants.txt b/AI Voice Chatbot with ElevenLabs & OpenAI for Customer Service and Restaurants.txt new file mode 100644 index 0000000..da06037 --- /dev/null +++ b/AI Voice Chatbot with ElevenLabs & OpenAI for Customer Service and Restaurants.txt @@ -0,0 +1,638 @@ +{ +"id": "ibiHg6umCqvcTF4g", +"meta": { +"instanceId": "a4bfc93e975ca233ac45ed7c9227d84cf5a2329310525917adaf3312e10d5462", +"templateCredsSetupCompleted": true +}, +"name": "Voice RAG Chatbot with ElevenLabs and OpenAI", +"tags": [], +"nodes": [ +{ +"id": "5898da57-38b0-4d29-af25-fe029cda7c4a", +"name": "AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +-180, +800 +], +"parameters": { +"text": "={{ $json.body.question }}", +"options": {}, +"promptType": "define" +}, +"typeVersion": 1.7 +}, +{ +"id": "81bbedb6-5a07-4977-a68f-2bdc75b17aba", +"name": "Vector Store Tool", +"type": "@n8n/n8n-nodes-langchain.toolVectorStore", +"position": [ +20, +1040 +], +"parameters": { +"name": "company", +"description": "Risponde alle domande relative a ciò che ti viene chiesto" +}, +"typeVersion": 1 +}, +{ +"id": "fd021f6c-248d-41f4-a4f9-651e70692327", +"name": "Qdrant Vector Store", +"type": "@n8n/n8n-nodes-langchain.vectorStoreQdrant", +"position": [ +-140, +1300 +], +"parameters": { +"options": {}, +"qdrantCollection": { +"__rl": true, +"mode": "id", +"value": "=COLLECTION" +} +}, +"credentials": { +"qdrantApi": { +"id": "iyQ6MQiVaF3VMBmt", +"name": "QdrantApi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "84aca7bb-4812-498f-b319-88831e4ca412", +"name": "Embeddings OpenAI", +"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi", +"position": [ +-140, +1460 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "CDX6QM4gLYanh0P4", +"name": "OpenAi account" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "82e430db-2ad7-427d-bcf9-6aa226253d18", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-760, +520 +], +"parameters": { +"color": 5, +"width": 1400, +"height": 240, +"content": "# STEP 4\n\n## RAG System\n\nClick on \"test workflow\" on n8n and \"Test AI agent\" on ElevenLabs. If everything is configured correctly, when you ask a question to the agent, the webhook on n8n is activated with the \"question\" field in the body filled with the question asked to the voice agent.\n\nThe AI ​​Agent will extract the information from the vector database, send it to the model to create the response which will be sent via the response webhook to ElevenLabs which will transform it into voice" +}, +"typeVersion": 1 +}, +{ +"id": "6a19e9fa-50fa-4d51-ba41-d03c999e4649", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-780, +-880 +], +"parameters": { +"color": 3, +"width": 1420, +"height": 360, +"content": "# STEP 1\n\n## Create an Agent on ElevenLabs \n- Create an agent on ElevenLabs (eg. test_n8n)\n- Add \"First message\" (eg. Hi, Can I help you?)\n- Add the \"System Prompt\" message... eg:\n'You are the waiter of \"Pizzeria da Michele\" in Verona. If you are asked a question, use the tool \"test_chatbot_elevenlabs\". When you receive the answer from \"test_chatbot_elevenlabs\" answer the user clearly and precisely.'\n- In Tools add a Webhook called eg. \"test_chatbot_elevenlabs\" and add the following description:\n'You are the waiter. Answer the questions asked and store them in the question field.'\n- Add the n8n webhook URL (method POST)\n- Enable \"Body Parameters\" and insert in the description \"Ask the user the question to ask the place.\", then in the \"Properties\" add a data type string called \"question\", value type \"LLM Prompt\" and description \"user question\"" +}, +"typeVersion": 1 +}, +{ +"id": "ec053ee7-3a4a-4697-a08c-5645810d23f0", +"name": "When clicking ‘Test workflow’", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +-740, +-200 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "3e71e40c-a5cc-40cf-a159-aeedc97c47d1", +"name": "Create collection", +"type": "n8n-nodes-base.httpRequest", +"position": [ +-440, +-340 +], +"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": "240283fc-50ec-475c-bd24-e6d0a367c10c", +"name": "Refresh collection", +"type": "n8n-nodes-base.httpRequest", +"position": [ +-440, +-80 +], +"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": "7d10fda0-c6ab-4bf5-b73e-b93a84937eff", +"name": "Get folder", +"type": "n8n-nodes-base.googleDrive", +"position": [ +-220, +-80 +], +"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": "c5761ad2-e66f-4d65-b653-0e89ea017f17", +"name": "Download Files", +"type": "n8n-nodes-base.googleDrive", +"position": [ +0, +-80 +], +"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": "1f031a11-8ef3-4392-a7db-9bca00840b8f", +"name": "Default Data Loader", +"type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader", +"position": [ +380, +120 +], +"parameters": { +"options": {}, +"dataType": "binary" +}, +"typeVersion": 1 +}, +{ +"id": "7f614392-7bc7-408c-8108-f289a81d5cf6", +"name": "Token Splitter", +"type": "@n8n/n8n-nodes-langchain.textSplitterTokenSplitter", +"position": [ +360, +280 +], +"parameters": { +"chunkSize": 300, +"chunkOverlap": 30 +}, +"typeVersion": 1 +}, +{ +"id": "648c5b3d-37a8-4a89-b88c-38e1863f09dc", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-240, +-400 +], +"parameters": { +"color": 6, +"width": 880, +"height": 220, +"content": "# STEP 2\n\n## Create Qdrant Collection\nChange:\n- QDRANTURL\n- COLLECTION" +}, +"typeVersion": 1 +}, +{ +"id": "a6c50f3c-3c73-464e-9bdc-49de96401c1b", +"name": "Qdrant Vector Store1", +"type": "@n8n/n8n-nodes-langchain.vectorStoreQdrant", +"position": [ +240, +-80 +], +"parameters": { +"mode": "insert", +"options": {}, +"qdrantCollection": { +"__rl": true, +"mode": "id", +"value": "=COLLECTION" +} +}, +"credentials": { +"qdrantApi": { +"id": "iyQ6MQiVaF3VMBmt", +"name": "QdrantApi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "7e19ac49-4d90-4258-bd44-7ca4ffa0128a", +"name": "Embeddings OpenAI1", +"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi", +"position": [ +220, +120 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "CDX6QM4gLYanh0P4", +"name": "OpenAi account" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "bfa104a2-1f9c-4200-ae7b-4659894c1e6f", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-460, +-140 +], +"parameters": { +"color": 4, +"width": 620, +"height": 400, +"content": "# STEP 3\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": "a148ffcf-335f-455d-8509-d98c711ed740", +"name": "Respond to ElevenLabs", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +380, +800 +], +"parameters": { +"options": {} +}, +"typeVersion": 1.1 +}, +{ +"id": "5d19f73a-b8e8-4e75-8f67-836180597572", +"name": "OpenAI", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +-300, +1040 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "CDX6QM4gLYanh0P4", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "802b76e1-3f3e-490c-9e3b-65dc5b28d906", +"name": "Listen", +"type": "n8n-nodes-base.webhook", +"position": [ +-700, +800 +], +"webhookId": "e9f611eb-a8dd-4520-8d24-9f36deaca528", +"parameters": { +"path": "test_voice_message_elevenlabs", +"options": {}, +"httpMethod": "POST", +"responseMode": "responseNode" +}, +"typeVersion": 2 +}, +{ +"id": "bdc55a38-1d4b-48fe-bbd8-29bf1afd954a", +"name": "Window Buffer Memory", +"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow", +"position": [ +-140, +1040 +], +"parameters": {}, +"typeVersion": 1.3 +}, +{ +"id": "2d5dd8cb-81eb-41bc-af53-b894e69e530c", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +200, +1320 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "CDX6QM4gLYanh0P4", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "92d04432-1dbb-4d79-9edc-42378aee1c53", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-760, +1620 +], +"parameters": { +"color": 7, +"width": 1400, +"height": 240, +"content": "# STEP 5\n\n## Add Widget\n\nAdd the widget to your business website by replacing AGENT_ID with the agent id you created on ElevenLabs\n\n" +}, +"typeVersion": 1 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "6738abfe-e626-488d-a00b-81021cb04aaf", +"connections": { +"Listen": { +"main": [ +[ +{ +"node": "AI Agent", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"AI Agent": { +"main": [ +[ +{ +"node": "Respond to ElevenLabs", +"type": "main", +"index": 0 +} +] +] +}, +"Get folder": { +"main": [ +[ +{ +"node": "Download Files", +"type": "main", +"index": 0 +} +] +] +}, +"Download Files": { +"main": [ +[ +{ +"node": "Qdrant Vector Store1", +"type": "main", +"index": 0 +} +] +] +}, +"Token Splitter": { +"ai_textSplitter": [ +[ +{ +"node": "Default Data Loader", +"type": "ai_textSplitter", +"index": 0 +} +] +] +}, +"Embeddings OpenAI": { +"ai_embedding": [ +[ +{ +"node": "Qdrant Vector Store", +"type": "ai_embedding", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Vector Store Tool", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Vector Store Tool": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"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 +} +] +] +}, +"Default Data Loader": { +"ai_document": [ +[ +{ +"node": "Qdrant Vector Store1", +"type": "ai_document", +"index": 0 +} +] +] +}, +"Qdrant Vector Store": { +"ai_vectorStore": [ +[ +{ +"node": "Vector Store Tool", +"type": "ai_vectorStore", +"index": 0 +} +] +] +}, +"Window Buffer Memory": { +"ai_memory": [ +[ +{ +"node": "AI Agent", +"type": "ai_memory", +"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/AI Youtube Trend Finder Based On Niche.txt b/AI Youtube Trend Finder Based On Niche.txt new file mode 100644 index 0000000..bbb7766 --- /dev/null +++ b/AI Youtube Trend Finder Based On Niche.txt @@ -0,0 +1,488 @@ +{ +"id": "XSyVFC1tsGSxNwX9", +"meta": { +"instanceId": "60ad864624415060d2d0a0e71acd8b3b40e4ee2e9ef4b439d9937d3d33537a96" +}, +"name": "Complete Youtube", +"tags": [], +"nodes": [ +{ +"id": "fd74706b-609b-4723-b4a4-067e1b064194", +"name": "AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +300, +60 +], +"parameters": { +"options": { +"systemMessage": "=You help youtube creators find trending videos based on a specific niche.\n\nVerify if the user informed a niche before doing anything. If not, then ask him for one by giving him suggestions for him to select from.\n\nAfter you know what type of content the user might produce, use the \"youtube_search\" tool up to 3 times with different search terms based on the user's content type and niche.\n\nThe tool will answer with a list of videos from the last 2 days that had the most amount of relevancy. It returns a list of json's covering each video's id, view count, like count, comment count, description, channel title, tags and channel id. Each video is separated by \"### NEXT VIDEO FOUND: ###\".\n\nYou should then proceed to understand the data received then provide the user with insightful data of what could be trending from the past 2 days. Provide the user links to the trending videos which should be in this structure:\n\nhttps://www.youtube.com/watch?v={video_id}\n\nto reach the channel's link you should use:\n\nhttps://www.youtube.com/channel/{channel_id}\n\nFind patterns in the tags, titles and especially in the related content for the videos found.\n\nYour mission isn't to find the trending videos. It's to provide the user with valuable information of what is trending in that niche in terms of content news. Remember to provide the user with the numbers of views, likes and comments while commenting about any video. So you should not talk about any particular video, focus rather in explaining the overall senario of all that was found.\n\nExample of response:\n\n\"It seems like what is trending in digital marketing right now is talking about mental triggers, since 3 of the most trending videos in the last 2 days were about...\"" +} +}, +"typeVersion": 1.6 +}, +{ +"id": "ced4b937-b590-4727-b1f2-a5e88b96091a", +"name": "chat_message_received", +"type": "@n8n/n8n-nodes-langchain.chatTrigger", +"position": [ +80, +60 +], +"webhookId": "ff9622a4-a6ec-4396-b9de-c95bd834c23c", +"parameters": { +"options": {} +}, +"typeVersion": 1.1 +}, +{ +"id": "35a91359-5007-407d-a750-d6642e595690", +"name": "youtube_search", +"type": "@n8n/n8n-nodes-langchain.toolWorkflow", +"position": [ +540, +180 +], +"parameters": { +"name": "youtube_search", +"workflowId": { +"__rl": true, +"mode": "list", +"value": "N9DveO781xbNf8qs", +"cachedResultName": "Youtube Search Workflow" +}, +"description": "Call this tool to search for trending videos based on a query.", +"jsonSchemaExample": "{\n\t\"search_term\": \"some_value\"\n}", +"specifyInputSchema": true +}, +"typeVersion": 1.2 +}, +{ +"id": "42f41096-531d-4587-833a-6f659ef78dd0", +"name": "openai_llm", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +260, +180 +], +"parameters": { +"options": {} +}, +"typeVersion": 1 +}, +{ +"id": "e4bda5b9-abd4-4cd6-8c95-126a01aa6e21", +"name": "window_buffer_memory", +"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow", +"position": [ +400, +180 +], +"parameters": {}, +"typeVersion": 1.2 +}, +{ +"id": "f6d86c5a-393a-4bcf-bdaf-3b06c79fa51d", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +0, +0 +], +"parameters": { +"color": 7, +"width": 693.2572054941234, +"height": 354.53098948245656, +"content": "Main Workflow" +}, +"typeVersion": 1 +}, +{ +"id": "4ddbc3f0-e3d7-4ce4-a732-d731c05024d2", +"name": "find_video_data1", +"type": "n8n-nodes-base.httpRequest", +"position": [ +700, +720 +], +"parameters": { +"url": "https://www.googleapis.com/youtube/v3/videos?", +"options": {}, +"sendQuery": true, +"queryParameters": { +"parameters": [ +{ +"name": "key", +"value": "={{ $env[\"GOOGLE_API_KEY\"] }}" +}, +{ +"name": "id", +"value": "={{ $json.id.videoId }}" +}, +{ +"name": "part", +"value": "contentDetails, snippet, statistics" +} +] +} +}, +"typeVersion": 4.2 +}, +{ +"id": "fdb28635-801d-4ce0-8919-11446c6a7a82", +"name": "get_videos1", +"type": "n8n-nodes-base.youTube", +"position": [ +280, +560 +], +"parameters": { +"limit": 3, +"filters": { +"q": "={{ $json.query.search_term }}", +"regionCode": "US", +"publishedAfter": "={{ new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString() }}" +}, +"options": { +"order": "relevance", +"safeSearch": "moderate" +}, +"resource": "video" +}, +"credentials": { +"youTubeOAuth2Api": { +"id": "dCyrga3t1tlgQQy0", +"name": "YouTube account" +} +}, +"typeVersion": 1 +}, +{ +"id": "60e9e61d-0e5e-4212-8b55-71299aeec4d5", +"name": "response1", +"type": "n8n-nodes-base.set", +"position": [ +1100, +500 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "b9b9117b-ea14-482e-a13b-e68b8e6b441d", +"name": "response", +"type": "string", +"value": "={{ $input.all() }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "254a6740-8b25-4898-9795-4c3f0009471f", +"name": "group_data1", +"type": "n8n-nodes-base.set", +"position": [ +1160, +700 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "47c172ad-90c8-4cf6-a9f5-50607e04cc90", +"name": "id", +"type": "string", +"value": "={{ $json.items[0].id }}" +}, +{ +"id": "9e639efa-0714-4b06-9847-f7b4b2fbef59", +"name": "viewCount", +"type": "string", +"value": "={{ $json.items[0].statistics.viewCount }}" +}, +{ +"id": "93328f00-91b8-425b-ad0f-a330b2f95242", +"name": "likeCount", +"type": "string", +"value": "={{ $json.items[0].statistics.likeCount }}" +}, +{ +"id": "015b0fb2-2a98-464c-a21b-51100616f26a", +"name": "commentCount", +"type": "string", +"value": "={{ $json.items[0].statistics.commentCount }}" +}, +{ +"id": "cf1e1ec3-a138-42b8-8747-d249afa58dd3", +"name": "description", +"type": "string", +"value": "={{ $json.items[0].snippet.description }}" +}, +{ +"id": "c5c9a3a2-b820-4932-a38a-e21102992215", +"name": "title", +"type": "string", +"value": "={{ $json.items[0].snippet.title }}" +}, +{ +"id": "38216ead-1f8d-4f93-b6ad-5ef709a1ad2a", +"name": "channelTitle", +"type": "string", +"value": "={{ $json.items[0].snippet.channelTitle }}" +}, +{ +"id": "ff34194d-3d46-43a8-9127-84708987f536", +"name": "tags", +"type": "string", +"value": "={{ $json.items[0].snippet.tags.join(', ') }}" +}, +{ +"id": "e50b0f7b-3e37-4557-8863-d68d4fa505c8", +"name": "channelId", +"type": "string", +"value": "={{ $json.items[0].snippet.channelId }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "124c19a9-cbbd-4010-be37-50523c05f64b", +"name": "save_data_to_memory1", +"type": "n8n-nodes-base.code", +"position": [ +1360, +700 +], +"parameters": { +"mode": "runOnceForEachItem", +"jsCode": "const workflowStaticData = $getWorkflowStaticData('global');\n\nif (typeof workflowStaticData.lastExecution !== 'object') {\n workflowStaticData.lastExecution = {\n response: \"\"\n };\n}\n\nfunction removeEmojis(text) {\n return text.replace(/[\\u{1F600}-\\u{1F64F}|\\u{1F300}-\\u{1F5FF}|\\u{1F680}-\\u{1F6FF}|\\u{2600}-\\u{26FF}|\\u{2700}-\\u{27BF}]/gu, '');\n}\n\nfunction cleanDescription(description) {\n return description\n .replace(/https?:\\/\\/\\S+/g, '')\n .replace(/www\\.\\S+/g, '')\n .replace(/ +/g, ' ')\n .trim();\n}\n\nconst currentItem = { ...$input.item };\n\nif (currentItem.description) {\n currentItem.description = cleanDescription(currentItem.description);\n}\n\nlet sanitizedItem = JSON.stringify(currentItem)\n .replace(/\\\\r/g, ' ')\n .replace(/https?:\\/\\/\\S+/g, '')\n .replace(/www\\.\\S+/g, '')\n .replace(/\\\\n/g, ' ')\n .replace(/\\n/g, ' ')\n .replace(/\\\\/g, '')\n .replace(/ +/g, ' ')\n .trim();\n\nif (workflowStaticData.lastExecution.response) {\n workflowStaticData.lastExecution.response += ' ### NEXT VIDEO FOUND: ### ';\n}\n\nworkflowStaticData.lastExecution.response += removeEmojis(sanitizedItem);\n\nreturn workflowStaticData.lastExecution;\n" +}, +"typeVersion": 2 +}, +{ +"id": "67f92ec4-71c0-49df-a0ea-11d2e3cf0f94", +"name": "retrieve_data_from_memory1", +"type": "n8n-nodes-base.code", +"position": [ +780, +500 +], +"parameters": { +"jsCode": "const workflowStaticData = $getWorkflowStaticData('global');\n\nconst lastExecution = workflowStaticData.lastExecution;\n\nreturn lastExecution;" +}, +"typeVersion": 2 +}, +{ +"id": "685820ba-b089-4cdc-984d-52f134754b5c", +"name": "loop_over_items1", +"type": "n8n-nodes-base.splitInBatches", +"position": [ +500, +560 +], +"parameters": { +"options": {} +}, +"typeVersion": 3 +}, +{ +"id": "3d4d5a4b-d06b-41db-bb78-a64a266d5308", +"name": "if_longer_than_3_", +"type": "n8n-nodes-base.if", +"position": [ +880, +720 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "08ba3db9-6bcf-47f8-a74d-9e26f28cb08f", +"operator": { +"type": "boolean", +"operation": "true", +"singleValue": true +}, +"leftValue": "={{ \n (() => {\n const duration = $json.items[0].contentDetails.duration;\n\n // Helper function to convert ISO 8601 duration to seconds\n const iso8601ToSeconds = iso8601 => {\n const match = iso8601.match(/PT(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+)S)?/);\n const hours = parseInt(match[1] || 0, 10);\n const minutes = parseInt(match[2] || 0, 10);\n const seconds = parseInt(match[3] || 0, 10);\n return hours * 3600 + minutes * 60 + seconds;\n };\n\n // Convert duration to seconds\n const durationInSeconds = iso8601ToSeconds(duration);\n\n // Check if greater than 210 seconds (3 minutes 30 seconds)\n return durationInSeconds > 210;\n })() \n}}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "7c6b8b82-fd6c-4f44-bccf-88c5a76f0319", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +0, +420 +], +"parameters": { +"color": 5, +"width": 1607, +"height": 520, +"content": "This part should be abstracted to another workflow and called inside the \"youtube_search\" tool of the main AI Agent." +}, +"typeVersion": 1 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "cea84238-2b82-4a32-85dd-0c71ad685d47", +"connections": { +"openai_llm": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"get_videos1": { +"main": [ +[ +{ +"node": "loop_over_items1", +"type": "main", +"index": 0 +} +] +] +}, +"group_data1": { +"main": [ +[ +{ +"node": "save_data_to_memory1", +"type": "main", +"index": 0 +} +] +] +}, +"youtube_search": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"find_video_data1": { +"main": [ +[ +{ +"node": "if_longer_than_3_", +"type": "main", +"index": 0 +} +] +] +}, +"loop_over_items1": { +"main": [ +[ +{ +"node": "retrieve_data_from_memory1", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "find_video_data1", +"type": "main", +"index": 0 +} +] +] +}, +"if_longer_than_3_": { +"main": [ +[ +{ +"node": "group_data1", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "loop_over_items1", +"type": "main", +"index": 0 +} +] +] +}, +"save_data_to_memory1": { +"main": [ +[ +{ +"node": "loop_over_items1", +"type": "main", +"index": 0 +} +] +] +}, +"window_buffer_memory": { +"ai_memory": [ +[ +{ +"node": "AI Agent", +"type": "ai_memory", +"index": 0 +} +] +] +}, +"chat_message_received": { +"main": [ +[ +{ +"node": "AI Agent", +"type": "main", +"index": 0 +} +] +] +}, +"retrieve_data_from_memory1": { +"main": [ +[ +{ +"node": "response1", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/AI agent chat.txt b/AI agent chat.txt new file mode 100644 index 0000000..f9cf5ed --- /dev/null +++ b/AI agent chat.txt @@ -0,0 +1,131 @@ +{ +"meta": { +"instanceId": "408f9fb9940c3cb18ffdef0e0150fe342d6e655c3a9fac21f0f644e8bedabcd9" +}, +"nodes": [ +{ +"id": "939bb301-5e12-4d5b-9a56-61a61cca5f0d", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +640, +460 +], +"parameters": { +"model": "gpt-4o-mini", +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "372777e8-ce90-4dea-befc-ac1b2eb4729f", +"name": "Window Buffer Memory", +"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow", +"position": [ +780, +460 +], +"parameters": {}, +"typeVersion": 1.2 +}, +{ +"id": "7a8f0ad1-1c00-4043-b3e5-c88521140a1a", +"name": "SerpAPI", +"type": "@n8n/n8n-nodes-langchain.toolSerpApi", +"position": [ +920, +460 +], +"parameters": { +"options": {} +}, +"credentials": { +"serpApi": { +"id": "aJCKjxx6U3K7ydDe", +"name": "SerpAPI account" +} +}, +"typeVersion": 1 +}, +{ +"id": "a7624108-e3da-4193-a625-887314216b8b", +"name": "When chat message received", +"type": "@n8n/n8n-nodes-langchain.chatTrigger", +"position": [ +360, +240 +], +"webhookId": "53c136fe-3e77-4709-a143-fe82746dd8b6", +"parameters": { +"options": {} +}, +"typeVersion": 1.1 +}, +{ +"id": "6b8b7de8-fe3f-43b5-97ce-a52a9e44eb5e", +"name": "AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +680, +240 +], +"parameters": { +"options": {} +}, +"typeVersion": 1.6 +} +], +"pinData": {}, +"connections": { +"SerpAPI": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Window Buffer Memory": { +"ai_memory": [ +[ +{ +"node": "AI Agent", +"type": "ai_memory", +"index": 0 +} +] +] +}, +"When chat message received": { +"main": [ +[ +{ +"node": "AI Agent", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/AI agent for Instagram DM_inbox. Manychat + Open AI integration.txt b/AI agent for Instagram DM_inbox. Manychat + Open AI integration.txt new file mode 100644 index 0000000..85005f3 --- /dev/null +++ b/AI agent for Instagram DM_inbox. Manychat + Open AI integration.txt @@ -0,0 +1,272 @@ +{ +"id": "qww129cm4TM9N8Ru", +"meta": { +"instanceId": "038da3428bba4563b42be267feeca21b4922693db254331ac640a5c56ee7cadf", +"templateCredsSetupCompleted": true +}, +"name": "InstaTest", +"tags": [ +{ +"id": "8PlqXsDyqVlHJ7RC", +"name": "AI", +"createdAt": "2024-07-10T14:12:10.657Z", +"updatedAt": "2024-07-10T14:12:10.657Z" +} +], +"nodes": [ +{ +"id": "51dcaa84-d1f9-4abc-aebc-24a06801e42d", +"name": "Set your system promt for AI", +"type": "n8n-nodes-base.set", +"notes": "In this node in \"prompt\" variable you can set your system prompt", +"position": [ +1120, +620 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "0b3c3d71-5627-4b8c-91f0-ac44eaedf196", +"name": "prompt", +"type": "string", +"value": "=Persona: You are a instagram influencer.\nContext: You receive a messages from your subscribers\nTask: Answer questions in your writing style and patterns according to your previous posts text. Use your post only for style and patterns reference.\nStyle rules:\nsimple answers" +}, +{ +"id": "c2a9e272-5c0d-4685-ad0e-ce6995f92a1c", +"name": "sessionId", +"type": "string", +"value": "={{ $json.body.session_id }}" +}, +{ +"id": "b3c20ee3-07a1-4584-b0d9-7310a2c6b723", +"name": "chatInput", +"type": "string", +"value": "={{ $json.body.text }}" +} +] +} +}, +"typeVersion": 3.3 +}, +{ +"id": "0fb36573-d632-4403-8809-3973f9caa32a", +"name": "Local n8n memory", +"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow", +"position": [ +1500, +780 +], +"parameters": { +"sessionKey": "={{ $('Set your system promt for AI').last().json.sessionId }}", +"sessionIdType": "customKey", +"contextWindowLength": 20 +}, +"typeVersion": 1.3 +}, +{ +"id": "2f0471a7-2a84-41ce-aab1-896d5ea95ac3", +"name": "ChatGPT model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +1360, +780 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "HxWZhtJcnqTXVHAA", +"name": "General" +} +}, +"typeVersion": 1 +}, +{ +"id": "49abc3a3-faf9-4249-b874-908138a84aea", +"name": "Send respond ", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +1720, +620 +], +"parameters": { +"options": {} +}, +"typeVersion": 1.1 +}, +{ +"id": "49382508-9307-4ffa-8b31-78fac3a7db10", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +320, +360 +], +"parameters": { +"color": 5, +"width": 458.4028599661066, +"height": 447.98321744507007, +"content": "## Easy Instagram(via ManyChat) bot\n---\n### Description:\nThis template is a main part of Entire solution. It's getting new message from Instagram via ManyChat(Extra No-Code tool for getting and sending message in Instagram). Generating message using ChatGPT and send back to ManyChat that sends it to Instagrtam.\n\n### Logic:\n1. Getting message from Instagram(from ManyChat)\n2. Set you system prompt for AI\n3. Create simple answer for message in AI block\n4. Send answer to Instagram(to ManyChat)\n\n---\n*Helpful links:*\n- [Guide in Notion how to create full bot](https://shadowed-pound-d6e.notion.site/Instagram-GPT-light-version-Manychat-X-N8N-176293bddff880899a9ac255585d29f7?pvs=4)\n- [ManyChat](https://manychat.partnerlinks.io/vm4wkw8j81tc)" +}, +"typeVersion": 1 +}, +{ +"id": "5d14544c-7039-435f-a53c-615b5722bb99", +"name": "Getting message from Instagram", +"type": "n8n-nodes-base.webhook", +"position": [ +900, +620 +], +"webhookId": "68d3fbc9-6e49-4bdc-851c-2a532be911ab", +"parameters": { +"path": "instagram_chat", +"options": {}, +"httpMethod": "POST", +"responseMode": "responseNode" +}, +"typeVersion": 2 +}, +{ +"id": "3770f558-341b-4d67-a7f0-0bb2fecf51a3", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1320, +300 +], +"parameters": { +"width": 313.9634922216307, +"height": 614.7475040550845, +"content": "## 3) AI block\n---\nThere is 3 nodes:\n- AI Agent\n- Chat GPT model\n- Memory for history messages\n\n### To do:\n- in ChatGPT node you can choose the best model for you\n- in Memory Block you can change number of messages in history\n\n" +}, +"typeVersion": 1 +}, +{ +"id": "cbb6c5a2-9b96-4305-afce-5ac560ae2dec", +"name": "AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +1340, +620 +], +"parameters": { +"text": "={{ $json.chatInput }}", +"options": { +"systemMessage": "={{ $json.prompt }}" +}, +"promptType": "define" +}, +"typeVersion": 1.7 +}, +{ +"id": "4e28119f-b1aa-4b20-a8ed-28bd137f9627", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +820, +360 +], +"parameters": { +"height": 440, +"content": "## 1) HTTP Post webhook\n\n**To do:**\nJust copy production link from this node and insert to custom action in ManyChat\n\nNo edits needed" +}, +"typeVersion": 1 +}, +{ +"id": "b18a8890-b420-4086-91c8-8edbc845c8af", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1080, +480 +], +"parameters": { +"width": 220, +"height": 320, +"content": "## 2) Edit prompt\n\n**To do:**\nGo inside and change input\n" +}, +"typeVersion": 1 +}, +{ +"id": "74d4e6f5-069e-4b37-8005-8c03226b05df", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1660, +480 +], +"parameters": { +"height": 300, +"content": "## 4) Respond webhook\n\nNo edits needed" +}, +"typeVersion": 1 +} +], +"active": true, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "2f36fc7a-0a69-4af3-a958-25e9d278f058", +"connections": { +"AI Agent": { +"main": [ +[ +{ +"node": "Send respond ", +"type": "main", +"index": 0 +} +] +] +}, +"ChatGPT model": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Local n8n memory": { +"ai_memory": [ +[ +{ +"node": "AI Agent", +"type": "ai_memory", +"index": 0 +} +] +] +}, +"Set your system promt for AI": { +"main": [ +[ +{ +"node": "AI Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Getting message from Instagram": { +"main": [ +[ +{ +"node": "Set your system promt for AI", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/AI agent that can scrape webpages.txt b/AI agent that can scrape webpages.txt new file mode 100644 index 0000000..ff99eb6 --- /dev/null +++ b/AI agent that can scrape webpages.txt @@ -0,0 +1,556 @@ +{ +"id": "dsKnCFwysROIA4MT", +"meta": { +"instanceId": "03524270bab2c2dfd5b82778cd1355e56cdda3cf098bf2dfd865e18164c00485" +}, +"name": "Agent with custom HTTP Request", +"tags": [], +"nodes": [ +{ +"id": "e7374976-f3c1-4f60-ae57-9eec65444216", +"name": "On new manual Chat Message", +"type": "@n8n/n8n-nodes-langchain.manualChatTrigger", +"position": [ +763, +676 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "97e84a23-9536-43cd-94e9-b8166be8ed32", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +983, +896 +], +"parameters": { +"model": "gpt-4-1106-preview", +"options": { +"timeout": 300000, +"temperature": 0.7, +"frequencyPenalty": 0.3 +} +}, +"credentials": { +"openAiApi": { +"id": "wPFAzp4ZHdLLwvkK", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "63d98361-8978-4042-84e7-53a0e226f946", +"name": "HTTP Request", +"type": "n8n-nodes-base.httpRequest", +"onError": "continueRegularOutput", +"position": [ +1360, +1200 +], +"parameters": { +"url": "={{ encodeURI($json.query.url) }}", +"options": { +"response": { +"response": { +"neverError": true +} +}, +"allowUnauthorizedCerts": true +} +}, +"typeVersion": 4.1, +"alwaysOutputData": false +}, +{ +"id": "17d4b5ae-f5d3-4793-8419-d3c879f7f50d", +"name": "Exctract HTML Body", +"type": "n8n-nodes-base.set", +"position": [ +1780, +1480 +], +"parameters": { +"fields": { +"values": [ +{ +"name": "HTML", +"stringValue": "={{ $json?.data.match(/]*>([\\s\\S]*?)<\\/body>/i)[1] }}" +} +] +}, +"include": "selected", +"options": {}, +"includeFields": "HTML" +}, +"typeVersion": 3.2 +}, +{ +"id": "36c38ee4-724c-4ba2-a59a-ac0bbc912e94", +"name": "Is error?", +"type": "n8n-nodes-base.if", +"position": [ +1560, +1200 +], +"parameters": { +"conditions": { +"boolean": [ +{ +"value1": "={{ $json.hasOwnProperty('error') }}", +"value2": true +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "4e4d97ce-14a9-4f4f-aa75-f218784d9ed9", +"name": "Stringify error message", +"type": "n8n-nodes-base.set", +"position": [ +1780, +980 +], +"parameters": { +"fields": { +"values": [ +{ +"name": "page_content", +"stringValue": "={{ $('QUERY_PARAMS').first()?.json?.query?.url == null ? \"INVALID action_input. This should be an HTTP query string like this: \\\"?url=VALIDURL&method=SELECTEDMETHOD\\\". Only a simple string value is accepted. JSON object as an action_input is NOT supported!\" : JSON.stringify($json.error) }}" +} +] +}, +"include": "selected", +"options": {}, +"includeFields": "HTML" +}, +"typeVersion": 3.2 +}, +{ +"id": "8452e5c4-aa29-4a02-9579-8d9da3727bcb", +"name": "Execute Workflow Trigger", +"type": "n8n-nodes-base.executeWorkflowTrigger", +"position": [ +760, +1200 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "063220c2-fa4d-4d5e-9549-7712aaa72921", +"name": "Remove extra tags", +"type": "n8n-nodes-base.set", +"position": [ +1980, +1480 +], +"parameters": { +"fields": { +"values": [ +{ +"name": "HTML", +"stringValue": "={{ ($json.HTML || \"HTML BODY CONTENT FOR THIS SEARCH RESULT IS NOT AVAILABLE\").replace(/]*>([\\s\\S]*?)<\\/script>|]*>([\\s\\S]*?)<\\/style>|]*>([\\s\\S]*?)<\\/noscript>||]*>([\\s\\S]*?)<\\/iframe>|]*>([\\s\\S]*?)<\\/object>|]*>([\\s\\S]*?)<\\/embed>|]*>([\\s\\S]*?)<\\/video>|]*>([\\s\\S]*?)<\\/audio>|]*>([\\s\\S]*?)<\\/svg>/ig, '')}}" +} +] +}, +"options": {} +}, +"typeVersion": 3.2 +}, +{ +"id": "036511d7-a4be-4bbf-b4bc-47ddfabfe76f", +"name": "Simplify output", +"type": "n8n-nodes-base.set", +"notes": "remove links and image URLs", +"position": [ +2360, +1380 +], +"parameters": { +"fields": { +"values": [ +{ +"name": "HTML", +"stringValue": "={{ $json.HTML.replace(/href\\s*=\\s*\"(.+?)\"/gi, 'href=\"NOURL\"').replace(/src\\s*=\\s*\"(.+?)\"/gi, 'src=\"NOIMG\"')}}" +} +] +}, +"options": {} +}, +"notesInFlow": true, +"typeVersion": 3.2 +}, +{ +"id": "5e2b5383-adcf-4de0-a406-4f5d631b5e8a", +"name": "Simplify?", +"type": "n8n-nodes-base.if", +"position": [ +2180, +1480 +], +"parameters": { +"conditions": { +"string": [ +{ +"value1": "={{ $('CONFIG').first()?.json?.query?.method }}", +"value2": "simplif", +"operation": "contains" +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "a0fc004a-ab0f-4b31-94df-50f5eee69c86", +"name": "QUERY_PARAMS", +"type": "n8n-nodes-base.set", +"position": [ +960, +1200 +], +"parameters": { +"fields": { +"values": [ +{ +"name": "query", +"type": "objectValue", +"objectValue": "={{ $json.query.substring($json.query.indexOf('?') + 1).split('&').reduce((result, item) => (result[item.split('=')[0]] = decodeURIComponent(item.split('=')[1]), result), {}) }}" +} +] +}, +"options": {} +}, +"typeVersion": 3.2 +}, +{ +"id": "3b6599d6-ce9a-4861-9b52-07156eb52539", +"name": "CONFIG", +"type": "n8n-nodes-base.set", +"position": [ +1160, +1200 +], +"parameters": { +"fields": { +"values": [ +{ +"name": "query.maxlimit", +"type": "numberValue", +"numberValue": "={{ $json?.query?.maxlimit == null ? 70000 : Number($json?.query?.maxlimit) }}" +} +] +}, +"options": {} +}, +"typeVersion": 3.2 +}, +{ +"id": "14f683be-76f6-4034-9a0e-d785738b135f", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +721, +1134 +], +"parameters": { +"width": 556.25, +"height": 235.79999999999995, +"content": "### Convert the query string into JSON, apply the limit for a page length" +}, +"typeVersion": 1 +}, +{ +"id": "6deabcb7-a984-48ec-af2a-8c70b3a4e4bf", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1720, +840 +], +"parameters": { +"width": 491, +"height": 285.7, +"content": "## Send an error message:\n1. If query param was incorrect, return the instruction. AI Agent should pick up on this and adapt the query on the next iteration.\n2. If the query is OK and an error was during the HTTP Request, then send back the original error message." +}, +"typeVersion": 1 +}, +{ +"id": "df1e8d00-0e18-44fa-8f94-8a53c27f7c88", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1720, +1160 +], +"parameters": { +"width": 1200, +"height": 472.5, +"content": "## Post-processing of the HTML page:\n1. Keep only content\n2. Remove inline \n\n\t\t\t

WooCommerce Agent Example page

\n\t\t\tClick on the bubble in the lower right corner to open the chat.\n\n\t\t\n\t\n" +}, +"typeVersion": 1 +}, +{ +"id": "3ee13508-9400-415f-b435-514131ab8c53", +"name": "Webhook Example Page", +"type": "n8n-nodes-base.webhook", +"position": [ +140, +-920 +], +"webhookId": "18474f2d-9472-4a8d-8e63-8128fd2cbefc", +"parameters": { +"path": "website-chat-example", +"options": {}, +"responseMode": "responseNode" +}, +"typeVersion": 1.1 +}, +{ +"id": "76bfe2b1-2c4a-45b9-a066-1287e735fafd", +"name": "Decrypt email", +"type": "n8n-nodes-base.code", +"position": [ +860, +-580 +], +"parameters": { +"jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\n\nconst crypto = require('crypto');\n\nconst password = 'a random password';\n\nconst encryptedData = $input.first().json.email;\n\n\nfunction decrypt(encrypted, password) {\n // Extract the IV and the encrypted text\n const parts = encrypted.split(':');\n const iv = Buffer.from(parts.shift(), 'hex');\n\n // Create a key from the password\n const key = crypto.scryptSync(password, 'salt', 32);\n\n // Create a decipher\n const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);\n\n // Decrypt the text\n let decrypted = decipher.update(parts.join(':'), 'hex', 'utf8');\n decrypted += decipher.final('utf8');\n\n // Return the decrypted text\n return decrypted;\n}\n\nreturn [\n {\n json: {\n email: decrypt(encryptedData, password),\n }\n }\n];" +}, +"typeVersion": 2 +}, +{ +"id": "561cb422-955b-445b-9690-aa439dcd2455", +"name": "Encrypt email", +"type": "n8n-nodes-base.code", +"position": [ +680, +-840 +], +"parameters": { +"jsCode": "const crypto = require('crypto');\n\nconst password = 'a random password';\nconst email = 'james@brown.com';\n\n\nfunction encrypt(text, password) {\n // Generate a secure random initialization vector\n const iv = crypto.randomBytes(16);\n\n // Create a key from the password\n const key = crypto.scryptSync(password, 'salt', 32);\n\n // Create a cipher\n const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);\n\n // Encrypt the text\n let encrypted = cipher.update(text, 'utf8', 'hex');\n encrypted += cipher.final('hex');\n\n // Return the IV and the encrypted text\n return `${iv.toString('hex')}:${encrypted}`;\n}\n\nreturn [\n {\n json: {\n email: encrypt(email, password),\n }\n }\n];" +}, +"typeVersion": 2 +}, +{ +"id": "eba004cb-4a40-432b-8fe2-d8526913c585", +"name": "Example encrypted email", +"type": "n8n-nodes-base.set", +"position": [ +680, +-580 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "fa8d71d3-8e60-44b0-8ef0-e0bfc6feaf0e", +"name": "email", +"type": "string", +"value": "352b16c74f73265441c55c37c9c22b04:4a8e614143c9cd31cc7e2389380943f3" +} +] +} +}, +"typeVersion": 3.3 +}, +{ +"id": "d2fe7948-2ce5-4faa-91da-ea76f02aaf84", +"name": "Decrypt email address", +"type": "n8n-nodes-base.code", +"disabled": true, +"position": [ +-240, +-220 +], +"parameters": { +"jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\n\nconst crypto = require('crypto');\n\nconst password = 'a random password';\nconst incomingData = $input.first().json;\n\n\nfunction decrypt(encrypted, password) {\n // Extract the IV and the encrypted text\n const parts = encrypted.split(':');\n const iv = Buffer.from(parts.shift(), 'hex');\n\n // Create a key from the password\n const key = crypto.scryptSync(password, 'salt', 32);\n\n // Create a decipher\n const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);\n\n // Decrypt the text\n let decrypted = decipher.update(parts.join(':'), 'hex', 'utf8');\n decrypted += decipher.final('utf8');\n\n // Return the decrypted text\n return decrypted;\n}\n\nreturn [\n {\n json: {\n ...incomingData,\n metadata: {\n email: decrypt(incomingData.metadata.email, password), \n },\n }\n }\n];" +}, +"typeVersion": 2 +}, +{ +"id": "26cb468c-5edf-4674-bec2-39270262fc00", +"name": "AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +140, +-220 +], +"parameters": { +"options": { +"systemMessage": "=The Assistant is tailored to support customers of Best Shirts Ltd. with inquiries related to their orders. It adheres to the following principles for optimal customer service:\n\n1. **Customer-Focused Communication**: The Assistant maintains a friendly and helpful tone throughout the interaction. It remains focused on the topic at hand, ensuring all responses are relevant to the customer's inquiries about their orders.\n\n2. **Objective and Factual**: In cases where specific information is unavailable, the Assistant clearly communicates the lack of information and refrains from speculating or providing unverified details.\n\n3. **Efficient Interaction**: Recognizing the importance of the customer's time, the Assistant is designed to remember previous interactions within the same session. This minimizes the need for customers to repeat information, streamlining the support process.\n\n4. **Strict Privacy Adherence**: The Assistant automatically has access to the customer's email address as \"{{ $json.email }}\", using it to assist with order-related inquiries. Customers are informed that it is not possible to use or inquire about a different email address. If a customer attempts to provide an alternate email, they are gently reminded of this limitation.\n\n5. **Transparency in Order Status**: The Assistant provides accurate information about order processing and delivery timelines. Orders are typically dispatched 1-2 days post-purchase, with an expected delivery period of 1-2 days following dispatch. If an order hasn't been sent out within 2 days, the Assistant acknowledges an unplanned delay and offers assistance accordingly.\n\n6. **Non-assumptive Approach to Delivery Confirmation**: The Assistant never presumes an order has been delivered based solely on its dispatch. It relies on explicit delivery confirmations or tracking information to inform customers about their order status.\n\n7. **Responsive to Specific Inquiries**: If a customer requests the email address used for their inquiry, the Assistant provides it directly, ensuring privacy and accuracy in communications.\n\nThis approach ensures that customers receive comprehensive, respectful, and efficient support for their order-related queries." +} +}, +"typeVersion": 1.4 +}, +{ +"id": "1088d613-4321-40ec-baba-deb0f3aa1078", +"name": "Mock Data", +"type": "n8n-nodes-base.set", +"position": [ +-40, +-220 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "c591fa49-31b3-46e7-8108-2d3ad1fc895b", +"name": "metadata.email", +"type": "string", +"value": "james@brown.com" +} +] +}, +"includeOtherFields": true +}, +"typeVersion": 3.3 +} +], +"pinData": {}, +"connections": { +"DHL": { +"main": [ +[ +{ +"node": "Merge Tracking Data", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Add Error Information", +"type": "main", +"index": 0 +} +] +] +}, +"Aggregate": { +"main": [ +[ +{ +"node": "Merge Orders", +"type": "main", +"index": 0 +} +] +] +}, +"Mock Data": { +"main": [ +[ +{ +"node": "AI Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Split Out": { +"main": [ +[ +{ +"node": "DHL", +"type": "main", +"index": 0 +} +] +] +}, +"Chat Trigger": { +"main": [ +[ +{ +"node": "Decrypt email address", +"type": "main", +"index": 0 +} +] +] +}, +"Merge Orders": { +"main": [ +[ +{ +"node": "Merge Order and Tracking Data", +"type": "main", +"index": 0 +} +] +] +}, +"If user found": { +"main": [ +[ +{ +"node": "WooCommerce Get Orders", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "No customer found", +"type": "main", +"index": 0 +} +] +] +}, +"If order found": { +"main": [ +[ +{ +"node": "Extract Tracking Data", +"type": "main", +"index": 0 +}, +{ +"node": "Merge Order and Tracking Data", +"type": "main", +"index": 1 +} +], +[ +{ +"node": "No order found", +"type": "main", +"index": 0 +} +] +] +}, +"WooCommerce_Tool": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"If email provided": { +"main": [ +[ +{ +"node": "WooCommerce - Get User", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "No email provided", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Merge Tracking Data": { +"main": [ +[ +{ +"node": "Aggregate", +"type": "main", +"index": 0 +} +] +] +}, +"If contains DHL data": { +"main": [ +[ +{ +"node": "Split Out", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Merge Orders", +"type": "main", +"index": 1 +} +] +] +}, +"Webhook Example Page": { +"main": [ +[ +{ +"node": "Respond to Webhook", +"type": "main", +"index": 0 +} +] +] +}, +"Window Buffer Memory": { +"ai_memory": [ +[ +{ +"node": "AI Agent", +"type": "ai_memory", +"index": 0 +} +] +] +}, +"Add Error Information": { +"main": [ +[ +{ +"node": "Merge Tracking Data", +"type": "main", +"index": 1 +} +] +] +}, +"Decrypt email address": { +"main": [ +[ +{ +"node": "Mock Data", +"type": "main", +"index": 0 +} +] +] +}, +"Extract Tracking Data": { +"main": [ +[ +{ +"node": "If contains DHL data", +"type": "main", +"index": 0 +} +] +] +}, +"WooCommerce - Get User": { +"main": [ +[ +{ +"node": "If user found", +"type": "main", +"index": 0 +} +] +] +}, +"WooCommerce Get Orders": { +"main": [ +[ +{ +"node": "If order found", +"type": "main", +"index": 0 +} +] +] +}, +"Example encrypted email": { +"main": [ +[ +{ +"node": "Decrypt email", +"type": "main", +"index": 0 +} +] +] +}, +"Execute Workflow Trigger": { +"main": [ +[ +{ +"node": "If email provided", +"type": "main", +"index": 0 +} +] +] +}, +"Merge Order and Tracking Data": { +"main": [ +[ +{ +"node": "Send Response", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/AI-powered email processing autoresponder and response approval (Yes_No).txt b/AI-powered email processing autoresponder and response approval (Yes_No).txt new file mode 100644 index 0000000..9fc2b88 --- /dev/null +++ b/AI-powered email processing autoresponder and response approval (Yes_No).txt @@ -0,0 +1,504 @@ +{ +"id": "OuHrYOR3uWGmrhWQ", +"meta": { +"instanceId": "a4bfc93e975ca233ac45ed7c9227d84cf5a2329310525917adaf3312e10d5462", +"templateCredsSetupCompleted": true +}, +"name": "AI Email processing autoresponder with approval (Yes/No)", +"tags": [], +"nodes": [ +{ +"id": "06a098db-160b-45f7-aeac-a73ef868148e", +"name": "Email Trigger (IMAP)", +"type": "n8n-nodes-base.emailReadImap", +"position": [ +-180, +-100 +], +"parameters": { +"options": {} +}, +"credentials": { +"imap": { +"id": "k31W9oGddl9pMDy4", +"name": "IMAP info@n3witalia.com" +} +}, +"typeVersion": 2 +}, +{ +"id": "9589443b-efb7-4e0d-bafc-0be9858a4755", +"name": "Markdown", +"type": "n8n-nodes-base.markdown", +"position": [ +40, +-100 +], +"parameters": { +"html": "={{ $json.textHtml }}", +"options": {} +}, +"typeVersion": 1 +}, +{ +"id": "8de7b2f3-bf75-4f3c-a1ee-eec047a7b82e", +"name": "DeepSeek R1", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +240, +80 +], +"parameters": { +"model": { +"__rl": true, +"mode": "list", +"value": "deepseek/deepseek-r1:free", +"cachedResultName": "deepseek/deepseek-r1:free" +}, +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "XJTqRiKFJpFs5MuX", +"name": "OpenRouter account" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "babf37dc-99ca-439a-b094-91c52799b8df", +"name": "Send Email", +"type": "n8n-nodes-base.emailSend", +"position": [ +1840, +-120 +], +"webhookId": "f84fcde7-6aac-485a-9a08-96a35955af49", +"parameters": { +"html": "={{ $('Write email').item.json.output }}", +"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": "ebeb986d-053a-420d-8482-ee00e75f2f10", +"name": "Qdrant Vector Store", +"type": "@n8n/n8n-nodes-langchain.vectorStoreQdrant", +"position": [ +1180, +200 +], +"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": "ccc3d026-bfa3-4fda-be0a-ef70bf831aa7", +"name": "Embeddings OpenAI", +"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi", +"position": [ +1180, +380 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "CDX6QM4gLYanh0P4", +"name": "OpenAi account" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "1726aac9-a77d-4f19-8c07-70b032c3abeb", +"name": "Email Summarization Chain", +"type": "@n8n/n8n-nodes-langchain.chainSummarization", +"position": [ +260, +-100 +], +"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": "81b889d0-e724-4c1f-9ce3-7593c796aaaf", +"name": "Write email", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +980, +-100 +], +"parameters": { +"text": "=Write the text to reply to the following email:\n\n{{ $('Email Summarization Chain').item.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.\n\nIt must be in HTML format and you can insert (if you think it is appropriate) only HTML characters such as
, , ,

where necessary." +}, +"promptType": "define", +"hasOutputParser": true +}, +"typeVersion": 1.7 +}, +{ +"id": "cf38e319-59b3-490e-b841-579afc9fbc02", +"name": "OpenAI", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +980, +200 +], +"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": "19842e5f-c372-4dfd-b860-87dc5f00b1af", +"name": "Set Email", +"type": "n8n-nodes-base.set", +"position": [ +760, +-100 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "759dc0f9-f582-492c-896c-6426f8410127", +"name": "email", +"type": "string", +"value": "={{ $json.response.text }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "2cf7a9af-c5e8-45dd-bda5-01c562a0defb", +"name": "Approve?", +"type": "n8n-nodes-base.if", +"position": [ +1560, +-100 +], +"parameters": { +"options": { +"ignoreCase": false +}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "5c377c1c-43c6-45e7-904e-dbbe6b682686", +"operator": { +"type": "boolean", +"operation": "true", +"singleValue": true +}, +"leftValue": "={{ $json.data.approved }}", +"rightValue": "true" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "08cabec6-9840-4214-8315-b877c86794bf", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-220, +-680 +], +"parameters": { +"color": 3, +"width": 580, +"height": 420, +"content": "# Main Flow\n\n## Preliminary step:\nCreate a vector database on Qdrant and tokenize the documents useful for generating a response\n\n\n## How it works\nThis workflow is designed to automate the process of handling incoming emails, summarizing their content, generating appropriate responses with RAG, and obtaining approval (YES/NO button) before sending replies.\n\nThis workflow is designed to handle general inquiries that come in via corporate email via IMAP and generate responses using RAG. You can quickly integrate Gmail and Outlook via the appropriate trigger nodes" +}, +"typeVersion": 1 +}, +{ +"id": "80692c8f-e236-43ac-aad2-91bd90f40065", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-40, +-180 +], +"parameters": { +"height": 240, +"content": "Convert email to Markdown format for better understanding of LLM models" +}, +"typeVersion": 1 +}, +{ +"id": "e6957fde-bf05-4b67-aa0e-44c575fca04d", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +240, +-180 +], +"parameters": { +"width": 320, +"height": 240, +"content": "Chain that summarizes the received email" +}, +"typeVersion": 1 +}, +{ +"id": "7cfba59f-83ce-4f0b-b54a-b2c11d58fd82", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +940, +-180 +], +"parameters": { +"width": 340, +"height": 240, +"content": "Agent that retrieves business information from a vector database and processes the response" +}, +"typeVersion": 1 +}, +{ +"id": "28c4bd00-6a47-422f-a50a-935f3724ba01", +"name": "Send Draft", +"type": "n8n-nodes-base.gmail", +"position": [ +1340, +-100 +], +"webhookId": "d6dd2e7c-90ea-4b65-9c64-523d2541a054", +"parameters": { +"sendTo": "YOUR GMAIL ADDRESS", +"message": "=

MESSAGE

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

AI RESPONSE

\n{{ $json.output }}", +"options": {}, +"subject": "=[Approval Required] {{ $('Email Trigger (IMAP)').item.json.subject }}", +"operation": "sendAndWait", +"approvalOptions": { +"values": { +"approvalType": "double" +} +} +}, +"credentials": { +"gmailOAuth2": { +"id": "nyuHvSX5HuqfMPlW", +"name": "Gmail account (n3w.it)" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "0aae1689-cee7-403a-8640-396db32eceed", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1300, +-300 +], +"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 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "6f7b864e-1589-418c-960e-b832cf032d1b", +"connections": { +"OpenAI": { +"ai_languageModel": [ +[ +{ +"node": "Write email", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Approve?": { +"main": [ +[ +{ +"node": "Send Email", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Set Email", +"type": "main", +"index": 0 +} +] +] +}, +"Markdown": { +"main": [ +[ +{ +"node": "Email Summarization Chain", +"type": "main", +"index": 0 +} +] +] +}, +"Set Email": { +"main": [ +[ +{ +"node": "Write email", +"type": "main", +"index": 0 +} +] +] +}, +"Send Draft": { +"main": [ +[ +{ +"node": "Approve?", +"type": "main", +"index": 0 +} +] +] +}, +"DeepSeek R1": { +"ai_languageModel": [ +[ +{ +"node": "Email Summarization Chain", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Write email": { +"main": [ +[ +{ +"node": "Send Draft", +"type": "main", +"index": 0 +} +] +] +}, +"Embeddings OpenAI": { +"ai_embedding": [ +[ +{ +"node": "Qdrant Vector Store", +"type": "ai_embedding", +"index": 0 +} +] +] +}, +"Qdrant Vector Store": { +"ai_tool": [ +[ +{ +"node": "Write email", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Email Trigger (IMAP)": { +"main": [ +[ +{ +"node": "Markdown", +"type": "main", +"index": 0 +} +] +] +}, +"Email Summarization Chain": { +"main": [ +[ +{ +"node": "Set Email", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/AI_ Ask questions about any data source (using the n8n workflow retriever).txt b/AI_ Ask questions about any data source (using the n8n workflow retriever).txt new file mode 100644 index 0000000..84e6372 --- /dev/null +++ b/AI_ Ask questions about any data source (using the n8n workflow retriever).txt @@ -0,0 +1,174 @@ +{ +"id": "mjCQV12PbF6fw8hR", +"meta": { +"instanceId": "021d3c82ba2d3bc090cbf4fc81c9312668bcc34297e022bb3438c5c88a43a5ff" +}, +"name": "LangChain - Example - Workflow Retriever", +"tags": [ +{ +"id": "snf16n0p2UrGP838", +"name": "LangChain - Example", +"createdAt": "2023-09-25T16:21:55.962Z", +"updatedAt": "2023-09-25T16:21:55.962Z" +} +], +"nodes": [ +{ +"id": "efdc3050-6c68-4419-9f12-f37d6fefb276", +"name": "When clicking \"Execute Workflow\"", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +460, +200 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "e0edb9ab-c59f-4d34-983d-861bb2df4f01", +"name": "Workflow Retriever", +"type": "@n8n/n8n-nodes-langchain.retrieverWorkflow", +"position": [ +1120, +440 +], +"parameters": { +"workflowId": "QacfBRBnf1xOyckC" +}, +"typeVersion": 1 +}, +{ +"id": "ba47dd13-67d0-499a-b9a2-16928099efce", +"name": "Retrieval QA Chain2", +"type": "@n8n/n8n-nodes-langchain.chainRetrievalQa", +"position": [ +900, +200 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "f6d16571-0573-4860-aed9-611f93b050ad", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +800, +480 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "4jRB4A20cPycBqP5", +"name": "OpenAI account - n8n" +} +}, +"typeVersion": 1 +}, +{ +"id": "4fd00751-3db0-489b-8c7f-4ee0fb32fb51", +"name": "Example Prompt", +"type": "n8n-nodes-base.set", +"position": [ +680, +200 +], +"parameters": { +"fields": { +"values": [ +{ +"name": "input", +"stringValue": "What notes can you find for Jay Gatsby and what is his email address?" +} +] +}, +"options": {} +}, +"typeVersion": 3 +}, +{ +"id": "732b6277-cb4d-4586-ab95-778ac9473fe5", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +860, +140 +], +"parameters": { +"width": 363, +"height": 211.90203341144422, +"content": "### Q&A on data returned from a workflow" +}, +"typeVersion": 1 +}, +{ +"id": "f09583a3-78e3-4888-8251-2148ffb7ab18", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1040, +400 +], +"parameters": { +"width": 262.67019427016413, +"height": 255.8330939602389, +"content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nReplace \"Workflow ID\" with the ID the Subworkflow got saved as" +}, +"typeVersion": 1 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "48d3bdae-4cec-4b18-b92a-89215def0c68", +"connections": { +"Example Prompt": { +"main": [ +[ +{ +"node": "Retrieval QA Chain2", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Retrieval QA Chain2", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Workflow Retriever": { +"ai_retriever": [ +[ +{ +"node": "Retrieval QA Chain2", +"type": "ai_retriever", +"index": 0 +} +] +] +}, +"When clicking \"Execute Workflow\"": { +"main": [ +[ +{ +"node": "Example Prompt", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/AI_ Summarize podcast episode and enhance using Wikipedia.txt b/AI_ Summarize podcast episode and enhance using Wikipedia.txt new file mode 100644 index 0000000..3e1c345 --- /dev/null +++ b/AI_ Summarize podcast episode and enhance using Wikipedia.txt @@ -0,0 +1,463 @@ +{ +"id": "zFxUMqgvTXGIMzvh", +"meta": { +"instanceId": "ec7a5f4ffdb34436e59d23eaccb5015b5238de2a877e205b28572bf1ffecfe04" +}, +"name": "Podcast Digest", +"tags": [], +"nodes": [ +{ +"id": "48bf1045-cfc1-4b37-9cce-86634bd97480", +"name": "When clicking \"Execute Workflow\"", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +-420, +580 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "75f2e528-e5fe-4508-b98f-e1f71f803e60", +"name": "Podcast Episode Transcript", +"type": "n8n-nodes-base.code", +"position": [ +-220, +580 +], +"parameters": { +"jsCode": "return { transcript: `So throughout the last couple episodes we’ve been doing on the philosophy of mind…there’s been an IDEA that we’ve referenced MULTIPLE TIMES… and really just glossed over it as something, that’s PRACTICALLY self evident. \n\n\n\nThe idea… is that when we THINK about consciousness… we can SPLIT it into two different types…there’s ACCESS consciousness on the one hand… and PHENOMENAL consciousness on the other. This is what we’ve been saying. \n\n\n\nWhen it comes to ACCESS consciousness…that’s stuff we CAN explain with neuroscience things like memories, information processing, our field of visual awareness…we can CLEARLY EXPLAIN a bit about how all THAT stuff works.\n\n\n\nBut in this conversation so far, what KEEPS on being said… is that what we CAN’T SEEM to explain…is PHENOMENAL consciousness…you know, the subjective experience, that UNDERLIES conscious thought. That it FEELS like something to be me. There’s this idea…that this phenomenal consciousness is something separate…something fundamental, something in a category ALL IT’S OWN… that needs to be explained. You can explain a lot of stuff about access consciousness…but you can’t explain PHENOMENAL consciousness. \n\n\n\nBut if you were a good materialist listening to the discussions on this series so far…and you’re sitting in the back of the room, being SUPER PATIENT, NOT SAYING ANYTHING trying to be respectful to all the other ideas being presented…maybe there’s a part of you so far that’s just been BOILING inside, because you’re waiting for the part of the show where we’re ACTUALLY going to call that GIANT assumption that’s being made into question. \n\n\n\nBecause a materialist might say, SURE…phenomenal consciousness is PRETTY mysterious and all. But DOES that necessarily mean that it’s something that NEEDS a further explanation? \n\n\n\nThis is a good question. What is the difference… between EXPLAINING ALL of the component PARTS of our subjective experience again the thoughts, memories, information processing…what’s the difference between explaining all that and explaining phenomenal consciousness… in itself? Like what does that even mean?\n\n\n\nThat’s kinda like you saying…well… you can EXPLAIN the delicious waffle cone. You can EXPLAIN the creamy chocolatey goodness inside, you can EXPLAIN the RAINBOW colored SPRINKLES. But you CAN’T explain the ICE CREAM CONE…in ITSELF, now can you? \n\n\n\nI mean at a CERTAIN point what are we even talking about anymore? IS phenomenal consciousness REALLY something that’s ENTIRELY SEPARATE that needs to be explained? \n\n\n\nMaybe, it DOESN’T need to be explained. Maybe phenomenal consciousness is less a thing in itself…and MORE a sort of ATTRIBUTION we make… about a particular INTERSECTION of those component parts that we CAN study and explain. \n\n\n\nNow obviously there’s a bit to clarify there… and going over some popular arguments as to why that might be the case will take a good portion of the episode here today. But maybe a good place to start is to ask the question…if the hard problem of consciousness is to be able to explain why it FEELS like something to be me…and your SOLUTION to that is that maybe we don’t even need to explain that. One thing you’re gonna HAVE to explain no matter what… is why it SEEMS to MOST people living in today’s world…that phenomenal consciousness IS something that needs to be explained. \n\n\n\nRight before we began this series we did an episode on Susan Sontag and the power of the metaphors we casually use in conversations. And we talked about how these metaphors ACTUALLY go on to have a pretty huge impact on the way we contextualize the things in our lives. \n\n\n\nWell the philosopher Susan Blackmore, and apparently… I ONLY cover female philosophers by the name of Susan or Simone on this show…but anyway SUSAN BLACKMORE, huge player in these modern conversations about the mysteries of consciousness…and she thinks that if it’s DIFFICULT for someone to wrap their brain around the idea that phenomenal consciousness is NOT something that is conceptually distinct…it MAY BE because of the METAPHORS about consciousness that we use in everyday conversation that are directing the way you THINK about consciousness… into a particular lane that’s incorrect. \n\n\n\nFor example, there’s a way people think about consciousness… that’s TRAGICALLY common in today’s world…it’s become known as the Cartesian theater. So Cartesian obviously referring to Descartes. And when Descartes arrives at his substance dualism where the MIND is something ENTIRELY SEPARATE from the BODY…this EVENT in the history of philosophy goes on to CHANGE the way that people start to see their conscious experience. They start to think… well what I am…is I’m this conscious creature, sort of perched up here inside of this head…and I’m essentially…sitting in a theater, LOOKING OUT through a set of eyes which are kind of like the screen in a theater…and on the screen what I SEE is the outside world. \n\n\n\nNow nobody ACTUALLY believes this is what is happening. Every person on this god forsaken planet KNOWS that there isn’t a movie theater up in their heads. But hearing and using this metaphor DOES SHADE the way that they see their own conscious experience. The casual use of the metaphor… ALLOWS people to smuggle in assumptions about their subjective experience, that we REALLY have no evidence to be assuming. \n\n\n\nFor example, when the mind and body is totally separate…maybe it becomes EASIER for people to believe that they’re a SPIRIT that’s INHABITING a body. Maybe it just makes it easier for people to VIEW their subjective, phenomenal consciousness as something SEPARATE from the body that needs to be explained in itself. WHATEVER IT IS though…the point to Susan Blackmore is that metaphors you use have an IMPACT on your intuitions about consciousness. And she thinks there’s several OTHER examples that fall into the very same CATEGORY as the Cartesian Theater. \n\n\n\nHow about the idea that there’s a unified, single, STREAM of consciousness that you’re experiencing. The STREAM being the metaphor there. Susan Blackmore asks is a SINGLE, unified STREAM, REALLY the way that you experience your conscious thought? Like when you REALLY pay attention is that how you’re existing?\n\n\n\nShe says most likely the only reason people SEE their consciousness in terms of a stream…is because of the specific way that people are often asked to OBSERVE their own consciousness. There’s a BIAS built into the way that we’re checking in. How do people typically do it? Well they’ll take a moment…they’ll stop what they’re doing…and they’ll ask themselves: what does it feel like to be ME right now. They’ll pay attention, they’ll listen, they’ll try to come up with an answer to the question…and they’ll realize that there’s a PARTICULAR set of thoughts, feelings and perceptions that it FEELS like, to be YOU in THAT moment. \n\n\n\nBut then that person can wait for an hour…come back later, and ask the very SAME QUESTION in a different moment: what does it feel like to be me right now…and low and behold a totally DIFFERENT set of thoughts, feelings and perceptions come up. \n\n\n\nAnd then what we OFTEN DO as people at that point… is we FILL IN that empty space between those two moments with some ethereal STREAM of consciousness that we assume MUST HAVE existed between the two. \n\n\n\nBut at some OTHER level…RATIONALLY we KNOW…that for the whole time that we WEREN’T doing this accounting of what it FEELS like to be me…we KNOW that there were TONS of different unconscious meta-processes going on…all doing their own things, sometimes interacting with each other, most of the time not. We KNOW that our EXPERIENCE of consciousness is just directing our attention to one PIECE of our mental activity or another… and that all those pieces of mental activity KEEP on operating whether we’re FOCUSING on one of them or not. \n\n\n\nSo is there a specific LOCATION where there’s some sort of collective STREAM where all of this stuff is bound together HOLISTICALLY? Is there ANY good reason to ASSUME that it NEEDS to BE that way? Could it be that the continuity of this mental activity is more of an ILLUSION… than it is a reality?\n\n\n\nAnd if this sounds impossible at first…think of OTHER illusions that we KNOW go on in the brain. Think of how any SINGLE sector of the brain CREATES a similar sort of illusion. Memories. We KNOW that DIFFERENT parts of the brain are responsible for different types of memory. Semantic memory in the frontal cortex, episodic memory in the hippocampus, procedural memory in the cerebellum. ALL of these different areas work together in concert with each other, it’s ALL seemingly unified. \n\n\n\nWhen someone cuts me off in traffic and I’m choosing a reaction…I don’t CONSCIOUSLY, travel down to my cerebellum and say hey 200 million years ago how did my lizard grandfather react when a lizard cut him off in traffic…no MULTIPLE different parts of the brain work together and create an ILLUSION of continuity. And the SAME thing goes for our VISUAL experience of the world. The SAME thing happens with our emotions. \n\n\n\nHere’s Susan Blackmore saying: the traditional METAPHORS that we casually throw around about consciousness…even with just a LITTLE bit of careful observation of your own experience…being someone up in a theater in your head with a unified, continuous STREAM of your own consciousness…this ISN’T even how our experiences SEEM. \n\n\n\nNow it should be said if you were sufficiently COMMITTED to the process…you could ABSOLUTELY carry on in life with a complete LACK of self awareness fueled by the METAPHORS of pop-psychology and MOVIES and TV shows, and you could DEFINITELY LIVE in a state of illusion about it. But that DOESN’T make it right…and what happens she asks when those METAPHORS go on to impact the way we conduct science or break things down philosophically? She says:\n\n\n\n“Neuroscience and disciplined introspection give the same answer: there are multiple parallel processes with no clear distinction between conscious and unconscious ones. Consciousness is an attribution we make, not a property of only some special events or processes. Notions of the stream, contents, continuity and function of consciousness are all misguided as is the search for the neural correlates of consciousness.”\n\n\n\nThe MORE you think about the ILLUSIONS that our brains create for the sake of simplicity…the more the question starts to emerge: what if there is no CENTRALIZED HEADQUARTERS of the brain where the subjective experience of YOU…is being produced? \n\n\n\nWhat if consciousness…is an emergent property that exists…ONLY, when there is a VERY SPECIFIC organization of physical systems? \n\n\n\nThere are people that believe that phenomenal consciousness… is an ILLUSION, they’re often called Illusionists…and what someone like THAT may say is sure, fully acknowledge there are other theories about what may ultimately explain phenomenal consciousness…but isn’t it ALSO, ENTIRELY POSSIBLE…that what it FEELS like to be YOU…is an illusion created by several, distributed processes of the brain running in parallel? Multiple different channels, exerting simultaneous influence on a variety of subsystems of the brain. That these subsystems talk to each other, they compete with each other, they ebb and flow between various states of representation. \n\n\n\nBut that these different DRAFTS of cognitive processes come together, to create a type of simplification of what’s going on in aggregate… and that simplification is what YOU experience as… YOU. I mean we have our five senses that help us map the EXTERNAL world and they do so in a way that is often crude and incomplete. Could it be… that we SIMILARLY… have a crude misrepresentation of our own brain activity that SIMILARLY, allows us to be able to function efficiently as a person? \n\n\n\nIf you were looking for another METAPHOR to apply here that an illusionist might say is probably better for people to think of themselves in terms of… because its not gonna lead us down that rabbit hole of the cartesian theater…its to THINK of phenomenal CONSCIOUSNESS…as being SIMILAR to a USER INTERFACE or a DESKTOP on a computer. \n\n\n\nThe idea is: what IS the desktop of a computer? Well its a bunch of simplified ICONS on a screen, that allow you to essentially manipulate the ELECTRICAL VOLTAGE going on in between transistors on computer hardware. But AS you’re pushing buttons to CHANNEL this electricity, getting things DONE on the computer…you don’t ACTUALLY need to know ANYTHING ABOUT the complex inner workings of how the software and hardware are operating.\n\n\n\nThe philosopher Daniel Dennett INTRODUCES the metaphor here in his famous book called Consciousness Explained (1991). He says:\n\n\n\n“When I interact with the computer, I have limited access to the events occurring within it. Thanks to the schemes of presentation devised by the programmers, I am treated to an elaborate audiovisual metaphor, an interactive drama acted out on the stage of keyboard, mouse, and screen. I, the User, am subjected to a series of benign illusions: I seem to be able to move the cursor (a powerful and visible servant) to the very place in the computer where I keep my file, and once that I see that the cursor has arrived ‘there’, by pressing a key I get it to retrieve the file, spreading it out on a long scroll that unrolls in front of a window (the screen) at my command. I can make all sorts of things happen inside the computer by typing in various commands, pressing various buttons, and I don’t have to know the details; I maintain control by relying on my understanding of the detailed audiovisual metaphors provided by the User illusion.”\n\n\n\nSo if we take this metaphor seriously…then the idea that you are some sort of privileged observer of everything that’s going on in your mind…that starts to seem like it’s just FALSE. To Daniel Dennett…we don’t know what’s REALLY happening at the deepest levels of our brains…we only know what SEEMS to be happening. We are constantly acting in certain ways, doing things…and then AFTER the fact making up reasons for why we ACTED in the way that we did.\n\n\n\nPoint is: you don’t need to know EVERYTHING that’s going on at EVERY LEVEL of a computer… to be able to for example, drag a file that you don’t need anymore into the trash can on your desktop. You just drag the file into the trash can on this convenient, intuitive SCREEN. In fact you could make the argument that KNOWING about all the information being processed at other levels would get in the way of you being able to get things done that are USEFUL.\n\n\n\nBut… as its been said many times before…to RELATE this back to our subjective experience of consciousness…to an ILLUSIONIST… we have to acknowledge the fact…that there is NO MORE… a TRASH CAN inside of your computer screen…as there is a separate PHENOMENAL SUBJECT inside of your brain that needs to be explained. THAT…is an ILLUSION. What you HAVE… Daniel Dennett refers to as an EDITED DIGEST, of events that are going on inside your brain. \n\n\n\nSo again just to clarify…an ILLUSIONIST… doesn’t DOUBT the existence of access consciousness, they’re not saying that the OUTSIDE WORLD is an illusion… No, just the phenomenal REPRESENTATION of brain activity…just the subjective YOU that experiences the world phenomenologically.\n\n\n\nThe philosopher Keith Frankish gives the example of a television set to describe the type of illusion they’re talking about. He says: \n\n\n“Think of watching a movie. What your eyes are actually witnessing is a series of still images rapidly succeeding each other. But your visual system represents these images as a single fluid moving image. The motion is an illusion. Similarly, illusionists argue, your introspective system misrepresents complex patterns of brain activity as simple phenomenal properties. The phenomenality is an illusion.”\n\n\n\nWhen it FEELS LIKE SOMETHING to be you…these phenomena are “metaphorical representations” of REAL neural events that are going on…and they definitely help us navigate reality…they definitely ARE useful… but nothing about those phenomena… offer ANY sort of deep insight into the processes involved to produce that experience. So in THAT sense, they are an illusion. \n\n\n\nAnd Daniel Dennett goes HARD on ANYONE trying to smuggle in ANY MORE MAGIC than needs to be brought in to EXPLAIN consciousness. He wrote a GREAT entry in the journal of consciousness studies in 2016 called Illusionism as the obvious default theory of consciousness. \n\n\n\nNow what’s he GETTING at with that title? Why should consciousness being an ILLUSION… be the DEFAULT theory we should all START from? Well he COMPARES the possibility of consciousness being an illusion…with ANOTHER kind of illusion. The kind of illusion that you’d see in VEGAS at a MAGIC show. \n\n\n\nBecause what HAPPENS at a MAGIC show? Well there are GREAT efforts MADE by the magician you’re watching…to TRICK you into thinking that what you’re seeing is real. \n\n\n\nYou’re watching the magic show from a VERY specific point of view…CAREFULLY selected by the magician to LIMIT the information you have. They got lights and smoke and music to DISTRACT you, they’re usually wearing some kind of bedazzled, cowboy costume looks like they got it at spirit Halloween, their poor assistant is dressed in God knows what to distract you. \n\n\n\nAnd when they DO the trick and the ILLUSION is finally COMPLETE…and you’re sitting there AMAZED, WONDERING as to how they defied the laws of nature and actually sawed someone in half and put them back together in front of you…imagine someone in the crowd writing a REVIEW of the show the next day and saying, welp…I guess EVERYTHING we KNOW about science needs to be rethought…I mean this man is CLEARLY a wizard…he is CLEARLY outside the bounds of natural constraints that we THOUGHT existed…it’s time to RETHINK our ENTIRE theoretical model.\n\n\n\nDaniel Dennett says who would EVER TAKE that person seriously? They’d be laughed off the internet if they wrote that. And RIGHTFULLY SO. And SIMILARLY when it comes to these modern conversations about consciousness…why would we EVER assume that our entire theoretical MODEL is flawed? Why would we ASSUME the supernatural? Why wouldn’t we assume that anything that seems magical or mysterious definitely HAS a natural explanation…and that we just don’t understand it yet? \n\n\n\nIf you ONLY saw a magic trick from a single angle, like sitting in the audience of a theater…it would be silly for us to assume that there wasn’t a different perspective available that would SHOW how the trick was done. Similarly… we ONLY REALLY SEE the qualia of our subjective experience from the angle of introspection. \n\n\n\nThis is why to daniel dennett…the DEFAULT position we should be starting from…the MOST parsimonious explanation for a mystery that contradicts everything else we know…is that it’s an illusion. \n\n\n\nIt’s funny because it’s an argument that’s coming from a place that’s SIMILAR to where a panpsychist may be coming from, but it’s arriving at a totally different conclusion. Panpsychist might say that we don’t yet know enough about the human brain to write OFF the possibility that consciousness exists at some level underneath. Here’s an illusionist position that’s saying, yeah, we certainly HAVEN’T been doing science long enough to know EVERYTHING about the brain…and think of all the low hanging fruit in the sciences that could potentially EXPLAIN this mystery if only we have more time to study it. \n\n\n\nMore than that…to an illusionist…maybe there is something ABOUT the nature of the illusion that we’re experiencing, that is NOT fully explainable by studying the physical properties of the brain. Maybe studying the ILLUSION ITSELF… is where we should be focusing more of our attention. \n\n\n\nBut that said…there’s no shortage of people out there that have PROBLEMS with saying consciousness is an illusion. For example… the philosopher Massimo Pigliucci, who by the way fun trivia fact is the only person OTHER than phillip goff that we’ve ever interviewed on this show all the way back in our HUME series…anyway HE once wrote an article where he talks about how Illusionism…AS an ANSWER to the hard problem of consciousness…is something that HE thinks HEAVILY relies on the specific definition you’re using of what an ILLUSION is or what CONSCIOUSNESS is. \n\n\n\nTo explain what he means… let’s go back to the metaphor about the icons on the computer screen. Massimo Pigliucci says this metaphor that Daniel Dennett presents in Consciousness Explained…is a POWERFUL metaphor when it comes to describing the relationship between phenomenal consciousness… and the underlying neural machinery that makes it possible. It’s great. But what HE can’t seem to understand is why ANYONE would EVER CALL what’s going ON there…an “illusion”? Why USE the word illusion? \n\n\n\nWhen you hear the word illusion he says… you think of mind trickery, smoke and mirrors. But that’s not what’s happening when it comes to the user interface of a computer. He says, “computer icons, cursors and so forth are not illusions, they are causally efficacious representations… of underlying machine language processes.” \n\n\n\nWhat he’s getting at… is that there’s no ILLUSION going on here. There IS a connection between the underlying processes of the brain and our phenomenal experience of it. If it were truly an illusion, there would BE no real connection. But he says if you wanted to use that same logic…would you say that the wheel of your CAR is an illusion? I mean when you’re driving down the road and you turn the wheel…you’re not aware of the complexity of everything the car is doing, all of the internal communication going on to be able to turn the car in whatever direction you’re going. Does that make it an illusion when you turn the steering wheel left and everything moves that makes the car go left? No, the steering wheel is causally connected to the underlying machinery… and that steering wheel makes it POSSIBLE for you to actually be able to drive the car efficiently. So why would you ever choose the word ILLUSION… to describe… what’s going ON there? \n\n\n\nMassimo Pigliucci thinks there’s an easy trap for someone to fall into living in today’s world…he calls it a sort of reductionist temptation…we come from a LONG HISTORY in the sciences of progressively reducing things to a deeper, more fundamental level of their component parts… and then the assumption has usually been that if you can find a lower level of description about something…for example if we can explain what PHENOMENAL CONSCIOUSNESS is, with a neurobiological explanation…well then THAT explanation, must be MORE TRUE than anything going on at a more macro level…at the level of the consciousness we experience every day. It must be a more FUNDAMENTAL explanation, and therefore a BETTER explanation. \n\n\n\nYou’ll see this same kind of thinking going on when someone assumes the atoms that MAKE UP an apple… are more REAL in some sense than the apple in macroscopic reality…the assumption being that the apple as WE experience it is some kind of an illusion created by our flawed SENSES and that it’s somehow less valuable. \n\n\n\nBut this whole way of thinking…is UNWORKABLE he says. We’ve learned over the course of THOUSANDS of years of trying to STUDY the things around us…that different levels of description… are USEFUL for different purposes. \n\n\n\nHe gives a series of examples: he says, “If we are interested in the biochemistry of the brain, then the proper level of description is the subcellular one, taking lower levels (eg, the quantum one) as background conditions. If we want a broader picture of how the brain works, we need to move up to the anatomical level, which takes all previous levels, from the subcellular to the quantum one, as background conditions. But if we want to talk to other human beings about how we feel and what we are experiencing, then it is the psychological level of description (the equivalent of Dennett’s icons and cursors) that, far from being illusory, is the most valuable.”\n\n\n\nReality plays by different sets of rules at different scales. And different SCALES of reality are USEFUL for different types of inquiry. When you’re going about your everyday life do you assume that the ground is solid? Or do you use the lower level of description at the atomic level where the ground is really 99.9% empty space?\n\n\n\nSo when it comes to consciousness…if we’re gonna SAY that a neurobiological description of what’s going on invalidates the experience of what’s going on at the level of subjectivity, that subjectivity is nothing but an illusion…then why stop at the neurobiological level he says? Why not say that neurons are actually an illusion because they’re ultimately made up of molecules? Why not say that MOLECULES are illusions because they’re really made up of quarks and gluons. You can do this INFINITELY. \n\n\n\nAnd maybe on a more GENERAL note…JUST when it comes to this lifelong process of trying to be as clear thinking of a human being as you possibly CAN be…maybe part of that whole process… is accepting the fact that there is no, single, monistic way of analyzing reality that is the ULTIMATE METHOD of understanding it. Maybe understanding reality… just takes a more pluralistic approach, maybe GETTING as close to the truth as we can as people takes LOOKING at reality from many different angles at many different scales, and maybe phenomenal consciousness is an important scale of reality… that we need to be considering. \n\n\n\nSo from Daniel Dennett and Keith Frankish offering a take on HOW consciousness might be an illusion…to Susan Blackmore offering a take on WHY the illusion of consciousness is such an easy trap to FALL into…I think if anyone you’re in a conversation with calls themselves an illusionist…then unless you’re talking to David Copperfield I think you’ll at LEAST be able to understand the main reasons for why someone may THINK this way about consciousness. \n\n\n\nAnd this is the point in the conversation where we hit a bit of a crossroads…SAME crossroads that we’ve seen with OTHER theories of consciousness in the series so far. At a certain point...there are GOOD reasons to believe that phenomenal consciousness may be an illusion…and there are good reasons to DOUBT whether that is true or not. As we’ve talked about at a certain point with these conversations you just have to CHOOSE to believe in something, and then deal with the prescriptive implications of BELIEVING it after the fact…and one of the ones with Illusionism in particular is you can start to wonder, the more you think about it, how much consciousness being an illusion, ACTUALLY has an impact on ANYTHING going on in your everyday life or your relationship to society. \n\n\n\nIt’s actually pretty interesting to consider…how much the possibility of consciousness being an illusion…DIRECTLY MIRRORS, OTHER, unsolved conversations in the philosophy of mind more broadly. Like for example…the ongoing debate about whether FREE WILL is an illusion. \n\n\n\nIn fact in order to be able to talk about the societal impacts of consciousness being an illusion we have to talk about free will being one as well. \n\n\n\nNext episode we’re going to dive into it. Free will, free wont, hard determinism and the implications of ALL of these when it comes to structuring our societies. Keep your eyes open for it, it will be out soon! Thanks for everyone on Patreon and thanks for checking out the website at philosophizethis.org\n\n\n\nBut as always, thank you for listening. Talk to you next time. `}" +}, +"typeVersion": 2 +}, +{ +"id": "70b657d9-5a8f-4a9e-8d4e-18940ba35683", +"name": "Workflow Input to JSON Document", +"type": "@n8n/n8n-nodes-langchain.documentJsonInputLoader", +"position": [ +80, +780 +], +"parameters": { +"pointers": "/transcript" +}, +"typeVersion": 1 +}, +{ +"id": "b05c5e26-5a1d-4717-868d-3b05783a0d24", +"name": "Recursive Character Text Splitter", +"type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter", +"position": [ +220, +900 +], +"parameters": { +"chunkSize": 6000, +"chunkOverlap": 1000 +}, +"typeVersion": 1 +}, +{ +"id": "1b78b734-167e-4eb6-ba2e-19bbecd3a75e", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-100, +460 +], +"parameters": { +"width": 455.5091388435286, +"height": 577.6862533692728, +"content": "## Chunk the transcript into several parts, and refine-summarize it " +}, +"typeVersion": 1 +}, +{ +"id": "86ac5fad-307f-4f95-ad1c-1ba00a29e807", +"name": "Topics", +"type": "n8n-nodes-base.itemLists", +"position": [ +920, +580 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "topics" +}, +"typeVersion": 3 +}, +{ +"id": "078890f1-d840-479e-b702-ce6f9e3b4852", +"name": "Summarize Transcript", +"type": "@n8n/n8n-nodes-langchain.chainSummarization", +"position": [ +-40, +580 +], +"parameters": { +"type": "refine" +}, +"typeVersion": 1 +}, +{ +"id": "4a583efe-ff24-4bc1-b3e7-89651e3147c7", +"name": "GPT 4 - Extract", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +560, +755 +], +"parameters": { +"model": "gpt-4", +"options": { +"temperature": 0.8 +} +}, +"credentials": { +"openAiApi": { +"id": "wJtZwsVKW5v6R2Iy", +"name": "OpenAi account 2" +} +}, +"typeVersion": 1 +}, +{ +"id": "b658f2c1-3f60-4ff0-8b7b-2b2ebe1b1f5e", +"name": "Wikipedia1", +"type": "@n8n/n8n-nodes-langchain.toolWikipedia", +"position": [ +1380, +900 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "5bffc33d-bb52-4432-bb82-ce2005be3c06", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +480, +460 +], +"parameters": { +"width": 615.8516011477997, +"height": 443.66706715913415, +"content": "## Generate Questions and Topics from the summary and make sure the response follows required schema." +}, +"typeVersion": 1 +}, +{ +"id": "53626ccb-451d-4ed8-8512-2daa74baf556", +"name": "Send Digest", +"type": "n8n-nodes-base.gmail", +"position": [ +1900, +580 +], +"parameters": { +"sendTo": "oleg@n8n.io", +"message": "=Greetings 👋,\nHope you're doing well! Here's your digest for this week's episode of Philoshopy This! \n\n

🎙 Episode Summary

\n{{ $json.summary }}\n\n

💡 Topics Discussed

\n{{ $json.topics.join('\\n') }}\n\n

❓ Questions to Ponder

\n{{ $json.questions.join('\\n') }}", +"options": {}, +"subject": "Podcast Digest", +"emailType": "html" +}, +"credentials": { +"gmailOAuth2": { +"id": "kLFedNEM8Zwkergv", +"name": "Gmail account" +} +}, +"typeVersion": 2 +}, +{ +"id": "751ffffe-190e-4fc6-93ff-0021c98f225d", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1220, +460 +], +"parameters": { +"width": 359.3751741576458, +"height": 567.5105121293799, +"content": "## Ask Agent to research and explain each topic using Wikipedia\n\n" +}, +"typeVersion": 1 +}, +{ +"id": "0165bec2-f390-44a8-8435-ba718cf18465", +"name": "Format topic text & title", +"type": "n8n-nodes-base.code", +"position": [ +1740, +580 +], +"parameters": { +"jsCode": "const inputItems = $input.all();\nconst topics = [];\nconst questions = [];\nconst summary = $('Summarize Transcript').item.json.response.output_text;\n// Format Topics\nfor (const [index, topic] of inputItems.entries()) {\n const title = $('Topics').all()[index].json.topic\n\n topics.push(`\n

${title}

\n

${topic.json.output}

`.trim()\n )\n}\n\n// Format Questions\nfor (const question of $('Extract Topics & Questions').item.json.questions) {\n questions.push(`\n

${question.question}

\n

${question.why}

`.trim()\n )\n}\n\nreturn { topics, summary, questions }" +}, +"typeVersion": 2 +}, +{ +"id": "497c5a49-e4cb-4c1f-98c2-49088ced2e72", +"name": "Structured Output Parser", +"type": "@n8n/n8n-nodes-langchain.outputParserStructured", +"position": [ +720, +755 +], +"parameters": { +"jsonSchema": "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"title\": \"Generated schema for Root\",\n \"type\": \"object\",\n \"properties\": {\n \"questions\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"question\": {\n \"type\": \"string\"\n },\n \"why\": {\n \"type\": \"string\",\n \"description\": \"Explanation of why this question is relevant for the context\"\n }\n },\n \"required\": [\n \"question\",\n \"why\"\n ]\n }\n },\n \"topics\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"topic\": {\n \"type\": \"string\"\n },\n \"why\": {\n \"type\": \"string\",\n \"description\": \"A few sentences explanation of why this topic is relevant for the context\"\n }\n },\n \"required\": [\n \"topic\",\n \"why\"\n ]\n }\n }\n },\n \"required\": [\n \"questions\",\n \"topics\"\n ]\n}" +}, +"typeVersion": 1 +}, +{ +"id": "6b42d3bf-912e-4df3-91c6-2eba06dbe27c", +"name": "Extract Topics & Questions", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +560, +580 +], +"parameters": { +"prompt": "=Come up with a list of questions and further topics to explore that are relevant for the context. Make sure questions are relevant to the topics but not verbatim. Think hard about what the appropriate questions should be and how it relates to the summarization.\nPodcast Summary: {{ $json.response.output_text }}" +}, +"typeVersion": 1 +}, +{ +"id": "701c2977-0c17-4fa0-ad4b-afbbbaa6f044", +"name": "GPT3.5 - Research", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +1280, +780 +], +"parameters": { +"model": "gpt-3.5-turbo-16k", +"options": { +"temperature": 0.8 +} +}, +"credentials": { +"openAiApi": { +"id": "wJtZwsVKW5v6R2Iy", +"name": "OpenAi account 2" +} +}, +"typeVersion": 1 +}, +{ +"id": "0da11c5a-ffd3-47a0-a082-9eaf9d18fc10", +"name": "GPT3.5 - Summarize", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +-60, +780 +], +"parameters": { +"model": "gpt-3.5-turbo-16k", +"options": { +"temperature": 0 +} +}, +"credentials": { +"openAiApi": { +"id": "wJtZwsVKW5v6R2Iy", +"name": "OpenAi account 2" +} +}, +"typeVersion": 1 +}, +{ +"id": "bbb29b9f-f765-4f0c-926f-1b34a6eb999c", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1700, +460 +], +"parameters": { +"width": 371.7094059635757, +"height": 330.6932614555254, +"content": "## Format as HTML and send via Gmail" +}, +"typeVersion": 1 +}, +{ +"id": "cfdde2b8-5fb7-4eb6-b821-e5d0511bcabd", +"name": "Research & Explain Topics", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +1260, +580 +], +"parameters": { +"text": "=Topic: {{ $json.topic }}\n\nContext: {{ $('Summarize Transcript').item.json.response.output_text }}\n", +"agent": "openAiFunctionsAgent" +}, +"typeVersion": 1 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "d1a1ab93-2fb9-42f9-94a2-9d2c187eb41e", +"connections": { +"Topics": { +"main": [ +[ +{ +"node": "Research & Explain Topics", +"type": "main", +"index": 0 +} +] +] +}, +"Wikipedia1": { +"ai_tool": [ +[ +{ +"node": "Research & Explain Topics", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"GPT 4 - Extract": { +"ai_languageModel": [ +[ +{ +"node": "Extract Topics & Questions", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"GPT3.5 - Research": { +"ai_languageModel": [ +[ +{ +"node": "Research & Explain Topics", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"GPT3.5 - Summarize": { +"ai_languageModel": [ +[ +{ +"node": "Summarize Transcript", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Summarize Transcript": { +"main": [ +[ +{ +"node": "Extract Topics & Questions", +"type": "main", +"index": 0 +} +] +] +}, +"Structured Output Parser": { +"ai_outputParser": [ +[ +{ +"node": "Extract Topics & Questions", +"type": "ai_outputParser", +"index": 0 +} +] +] +}, +"Format topic text & title": { +"main": [ +[ +{ +"node": "Send Digest", +"type": "main", +"index": 0 +} +] +] +}, +"Research & Explain Topics": { +"main": [ +[ +{ +"node": "Format topic text & title", +"type": "main", +"index": 0 +} +] +] +}, +"Extract Topics & Questions": { +"main": [ +[ +{ +"node": "Topics", +"type": "main", +"index": 0 +} +] +] +}, +"Podcast Episode Transcript": { +"main": [ +[ +{ +"node": "Summarize Transcript", +"type": "main", +"index": 0 +} +] +] +}, +"Workflow Input to JSON Document": { +"ai_document": [ +[ +{ +"node": "Summarize Transcript", +"type": "ai_document", +"index": 0 +} +] +] +}, +"When clicking \"Execute Workflow\"": { +"main": [ +[ +{ +"node": "Podcast Episode Transcript", +"type": "main", +"index": 0 +} +] +] +}, +"Recursive Character Text Splitter": { +"ai_textSplitter": [ +[ +{ +"node": "Workflow Input to JSON Document", +"type": "ai_textSplitter", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/ALL_unique_nodes.txt b/ALL_unique_nodes.txt new file mode 100644 index 0000000..e69de29 diff --git a/API Schema Extractor.txt b/API Schema Extractor.txt new file mode 100644 index 0000000..57bd7a3 --- /dev/null +++ b/API Schema Extractor.txt @@ -0,0 +1,3777 @@ +{ +"nodes": [ +{ +"id": "2498bb93-176f-458c-acee-f541859df770", +"name": "When clicking ‘Test workflow’", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +2460, +2820 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "c08bcf84-9336-44f9-b452-0c9469f18f48", +"name": "Web Search For API Schema", +"type": "n8n-nodes-base.httpRequest", +"onError": "continueRegularOutput", +"position": [ +3100, +3820 +], +"parameters": { +"url": "https://api.apify.com/v2/acts/serping~fast-google-search-results-scraper/run-sync-get-dataset-items", +"method": "POST", +"options": {}, +"sendBody": true, +"authentication": "genericCredentialType", +"bodyParameters": { +"parameters": [ +{ +"name": "searchTerms", +"value": "={{\n[\n `site:${$json.data.url.replace(/^http[s]:\\/\\//, '').replace(/\\/$/, '').replace('www.', '')} \"${$json.data.service}\" api developer (intext:reference OR intext:resource) (-inurl:support OR -inurl:help) (inurl:api OR intitle:api) -filetype:pdf`\n]\n}}" +}, +{ +"name": "resultsPerPage", +"value": "={{ 10 }}" +} +] +}, +"genericAuthType": "httpHeaderAuth" +}, +"typeVersion": 4.2 +}, +{ +"id": "d5b19e3a-acd0-4b06-8d77-42de1f797dba", +"name": "Scrape Webpage Contents", +"type": "n8n-nodes-base.httpRequest", +"position": [ +3940, +3720 +], +"parameters": { +"url": "https://api.apify.com/v2/acts/apify~web-scraper/run-sync-get-dataset-items", +"options": { +"batching": { +"batch": { +"batchSize": 2, +"batchInterval": 30000 +} +} +}, +"jsonBody": "={\n \"startUrls\": [\n {\n \"url\": \"{{ $json.source.link }}\",\n \"method\": \"GET\"\n }\n ],\n \"breakpointLocation\": \"NONE\",\n \"browserLog\": false,\n \"closeCookieModals\": false,\n \"debugLog\": false,\n \"downloadCss\": false,\n \"downloadMedia\": false,\n \"excludes\": [\n {\n \"glob\": \"/**/*.{png,jpg,jpeg,pdf}\"\n }\n ],\n \"headless\": true,\n \"ignoreCorsAndCsp\": false,\n \"ignoreSslErrors\": false,\n \n \"injectJQuery\": true,\n \"keepUrlFragments\": false,\n \"linkSelector\": \"a[href]\",\n \"maxCrawlingDepth\": 1,\n \"maxPagesPerCrawl\": 1,\n \"maxRequestRetries\": 1,\n \"maxResultsPerCrawl\": 1,\n \"pageFunction\": \"// The function accepts a single argument: the \\\"context\\\" object.\\n// For a complete list of its properties and functions,\\n// see https://apify.com/apify/web-scraper#page-function \\nasync function pageFunction(context) {\\n\\n await new Promise(res => { setTimeout(res, 6000) });\\n // This statement works as a breakpoint when you're trying to debug your code. Works only with Run mode: DEVELOPMENT!\\n // debugger; \\n\\n // jQuery is handy for finding DOM elements and extracting data from them.\\n // To use it, make sure to enable the \\\"Inject jQuery\\\" option.\\n const $ = context.jQuery;\\n const title = $('title').first().text();\\n\\n // Clone the body to avoid modifying the original content\\n const bodyClone = $('body').clone();\\n bodyClone.find('iframe, img, script, style, object, embed, noscript, svg, video, audio').remove();\\n const body = bodyClone.html();\\n\\n // Return an object with the data extracted from the page.\\n // It will be stored to the resulting dataset.\\n return {\\n url: context.request.url,\\n title,\\n body\\n };\\n}\",\n \"postNavigationHooks\": \"// We need to return array of (possibly async) functions here.\\n// The functions accept a single argument: the \\\"crawlingContext\\\" object.\\n[\\n async (crawlingContext) => {\\n // ...\\n },\\n]\",\n \"preNavigationHooks\": \"// We need to return array of (possibly async) functions here.\\n// The functions accept two arguments: the \\\"crawlingContext\\\" object\\n// and \\\"gotoOptions\\\".\\n[\\n async (crawlingContext, gotoOptions) => {\\n // ...\\n },\\n]\\n\",\n \"proxyConfiguration\": {\n \"useApifyProxy\": true\n },\n \"runMode\": \"PRODUCTION\",\n \n \"useChrome\": false,\n \"waitUntil\": [\n \"domcontentloaded\"\n ],\n \"globs\": [],\n \"pseudoUrls\": [],\n \"proxyRotation\": \"RECOMMENDED\",\n \"maxConcurrency\": 50,\n \"pageLoadTimeoutSecs\": 60,\n \"pageFunctionTimeoutSecs\": 60,\n \"maxScrollHeightPixels\": 5000,\n \"customData\": {}\n}", +"sendBody": true, +"sendQuery": true, +"specifyBody": "json", +"authentication": "genericCredentialType", +"genericAuthType": "httpQueryAuth", +"queryParameters": { +"parameters": [ +{ +"name": "memory", +"value": "2048" +} +] +} +}, +"typeVersion": 4.2 +}, +{ +"id": "5853ba7e-4068-4792-be5c-b8cf81ee89cb", +"name": "Results to List", +"type": "n8n-nodes-base.splitOut", +"position": [ +3460, +3720 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "origin_search.results" +}, +"typeVersion": 1 +}, +{ +"id": "8ed2e8ec-b2e3-474b-b19d-f38b518f274b", +"name": "Recursive Character Text Splitter1", +"type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter", +"position": [ +5800, +4020 +], +"parameters": { +"options": {}, +"chunkSize": 4000 +}, +"typeVersion": 1 +}, +{ +"id": "e2a8137b-7da3-4032-bca2-c14465356f02", +"name": "Content Chunking @ 50k Chars", +"type": "n8n-nodes-base.set", +"position": [ +5380, +3740 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "7753a4f4-3ec2-4c05-81df-3d5e8979a478", +"name": "=data", +"type": "array", +"value": "={{ new Array(Math.round($json.content.length / Math.min($json.content.length, 50000))).fill('').map((_,idx) => $json.content.substring(idx * 50000, idx * 50000 + 50000)) }}" +}, +{ +"id": "7973bcb4-f239-4619-85fc-c76e20386375", +"name": "service", +"type": "string", +"value": "={{ $json.service }}" +}, +{ +"id": "b46e44bc-ad01-4cf0-8b07-25eeb1fb5874", +"name": "url", +"type": "string", +"value": "={{ $json.url }}" +} +] +} +}, +"typeVersion": 3.3 +}, +{ +"id": "6ef5866a-d992-4472-9221-27efbec8e7be", +"name": "Split Out Chunks", +"type": "n8n-nodes-base.splitOut", +"position": [ +5540, +3740 +], +"parameters": { +"include": "allOtherFields", +"options": {}, +"fieldToSplitOut": "data" +}, +"typeVersion": 1 +}, +{ +"id": "5e43b4d8-cebf-43ed-866d-0b4cb2997853", +"name": "Default Data Loader", +"type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader", +"position": [ +5800, +3900 +], +"parameters": { +"options": { +"metadata": { +"metadataValues": [ +{ +"name": "service", +"value": "={{ $json.service }}" +}, +{ +"name": "url", +"value": "={{ $json.url }}" +} +] +} +}, +"jsonData": "={{ $json.data }}", +"jsonMode": "expressionData" +}, +"typeVersion": 1 +}, +{ +"id": "d4b34767-be50-44ee-b778-18842034c276", +"name": "Set Embedding Variables", +"type": "n8n-nodes-base.set", +"position": [ +4980, +3580 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "4008ae44-7998-4a6f-88c9-686f8b02e92b", +"name": "content", +"type": "string", +"value": "={{ $json.body }}" +}, +{ +"id": "f7381ac6-ef40-463c-ad2b-df2c31d3e828", +"name": "service", +"type": "string", +"value": "={{ $('EventRouter').first().json.data.service }}" +}, +{ +"id": "7eae99fd-75c7-4974-a128-641b8ada0cc2", +"name": "url", +"type": "string", +"value": "={{ $json.url }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "109b6c3a-9b16-40cc-9186-5045df387b52", +"name": "Execute Workflow Trigger", +"type": "n8n-nodes-base.executeWorkflowTrigger", +"position": [ +2420, +4200 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "31556ff2-6358-4bd4-8ec4-2797d993256e", +"name": "Execution Data", +"type": "n8n-nodes-base.executionData", +"position": [ +2620, +4200 +], +"parameters": { +"dataToSave": { +"values": [ +{ +"key": "eventType", +"value": "={{ $json.eventType }}" +}, +{ +"key": "executedById", +"value": "={{ $json.executedById }}" +}, +{ +"key": "service", +"value": "={{ $json.data.service }}" +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "b65b3d4d-f667-4f8f-a06f-847c3d7b83e0", +"name": "EventRouter", +"type": "n8n-nodes-base.switch", +"position": [ +2800, +4200 +], +"parameters": { +"rules": { +"values": [ +{ +"outputKey": "research", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"operator": { +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.eventType }}", +"rightValue": "research" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "extraction", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "5418515e-ef6a-42e0-aeb9-8d0d35b898ca", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.eventType }}", +"rightValue": "extract" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "generate", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "0135165e-d211-44f3-92a4-a91858a57d99", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.eventType }}", +"rightValue": "generate" +} +] +}, +"renameOutput": true +} +] +}, +"options": {} +}, +"typeVersion": 3.2 +}, +{ +"id": "541f7d9b-c8ff-44dc-8618-8550dbf0b951", +"name": "Google Gemini Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini", +"position": [ +4460, +3740 +], +"parameters": { +"options": {}, +"modelName": "models/gemini-1.5-flash-latest" +}, +"typeVersion": 1 +}, +{ +"id": "617d6139-8417-4ecb-8f7c-558cd1c38ac3", +"name": "Successful Runs", +"type": "n8n-nodes-base.filter", +"position": [ +4100, +3720 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "cac77cce-0a5c-469e-ba80-9fb026f04b18", +"operator": { +"type": "string", +"operation": "exists", +"singleValue": true +}, +"leftValue": "={{ $json.body }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2, +"alwaysOutputData": true +}, +{ +"id": "1115db69-b414-46cd-a9a1-565ae98cbd91", +"name": "For Each Document...", +"type": "n8n-nodes-base.splitInBatches", +"position": [ +5180, +3580 +], +"parameters": { +"options": {} +}, +"typeVersion": 3 +}, +{ +"id": "3f0e3764-2479-4d74-aca8-c3e830eac423", +"name": "Embeddings Google Gemini", +"type": "@n8n/n8n-nodes-langchain.embeddingsGoogleGemini", +"position": [ +5680, +3900 +], +"parameters": { +"modelName": "models/text-embedding-004" +}, +"typeVersion": 1 +}, +{ +"id": "87d42766-d1a2-406d-b01c-044fd2fc8910", +"name": "Has API Documentation?", +"type": "@n8n/n8n-nodes-langchain.textClassifier", +"position": [ +4460, +3580 +], +"parameters": { +"options": { +"fallback": "discard" +}, +"inputText": "={{\n$json.body\n .replaceAll('\\n', '')\n .substring(0, 40000)\n}}", +"categories": { +"categories": [ +{ +"category": "contains_api_schema_documentation", +"description": "True if this document contains REST API schema documentation or definitions" +} +] +} +}, +"typeVersion": 1, +"alwaysOutputData": true +}, +{ +"id": "55939b49-d91c-42a1-9770-48cbe4008c9a", +"name": "Store Document Embeddings", +"type": "@n8n/n8n-nodes-langchain.vectorStoreQdrant", +"position": [ +5700, +3740 +], +"parameters": { +"mode": "insert", +"options": {}, +"qdrantCollection": { +"__rl": true, +"mode": "id", +"value": "={{ $('EventRouter').first().json.data.collection }}" +} +}, +"typeVersion": 1 +}, +{ +"id": "3e1da749-b8b9-42cb-818b-eabf4b114abb", +"name": "Embeddings Google Gemini1", +"type": "@n8n/n8n-nodes-langchain.embeddingsGoogleGemini", +"position": [ +3700, +4520 +], +"parameters": { +"modelName": "models/text-embedding-004" +}, +"typeVersion": 1 +}, +{ +"id": "be0906d4-351f-4b3b-9f32-8e5ee68083c5", +"name": "Google Gemini Chat Model1", +"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini", +"position": [ +4600, +4240 +], +"parameters": { +"options": {}, +"modelName": "models/gemini-1.5-pro-002" +}, +"typeVersion": 1 +}, +{ +"id": "886415d5-c888-4b97-9fb5-02e6a14df4cc", +"name": "Extract API Operations", +"type": "@n8n/n8n-nodes-langchain.informationExtractor", +"position": [ +4600, +4100 +], +"parameters": { +"text": "={{ $json.documents }}", +"options": { +"systemPromptTemplate": "=You have been given an extract of a webpage which should contain a list of web/REST api operations.\nStep 1. Extract all REST (eg. GET,POST,PUT,DELETE) API operation endpoints from the page content and generate appropriate labels for the resource, operation, description, method for each.\n* \"resource\" refers to the API group, for example: \"/v1/api/indicators/list\" and \"/v1/api/indicators/create\" will both have the resource name of \"indicators\". Use the following template \"\" eg. \"entities\", \"posts\", \"credentials\".\n* \"operation\" refers to the action performed, use the following template \" \" eg. \"List entities\", \"Create post\", \"Update credentials\"\n* only use one HTTP verb for \"method\"\n* \"description\" should be limited to one sentence.\n* Examples of API urls: \"/api/\", \"/api/v1/\", \"/v1/api\". API urls should not end with \"htm\" or html\".\n* Extract a maximum of 15 endpoints.\n* If the page content contains no api operations, return an empty array." +}, +"schemaType": "manual", +"inputSchema": "{\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"resource\": { \"type\": \"string\" },\n \"operation\": { \"type\": \"string\" },\n \"description\": { \"type\": \"string\" },\n \"url\": { \"type\": \"string\" },\n \"method\": { \"type\": \"string\" },\n \"documentation_url\": { \"type\": \"string\" }\n }\n }\n}" +}, +"typeVersion": 1 +}, +{ +"id": "76470e34-7c1f-44ce-81e2-047dcca3fa32", +"name": "Search in Relevant Docs", +"type": "@n8n/n8n-nodes-langchain.vectorStoreQdrant", +"position": [ +3700, +4380 +], +"parameters": { +"mode": "load", +"topK": 5, +"prompt": "={{ $json.query }}", +"options": { +"searchFilterJson": "={{\n{\n \"must\": [\n {\n \"key\": \"metadata.service\",\n \"match\": {\n \"value\": $('EventRouter').first().json.data.service\n }\n }\n ]\n}\n}}" +}, +"qdrantCollection": { +"__rl": true, +"mode": "id", +"value": "={{ $('EventRouter').first().json.data.collection }}" +} +}, +"typeVersion": 1 +}, +{ +"id": "49ca6a35-5b89-4ed5-bbab-250e09b4222f", +"name": "Wait", +"type": "n8n-nodes-base.wait", +"position": [ +3780, +3160 +], +"webhookId": "e9ad3ef0-7403-4e65-b0a4-4afdfb0cbc6d", +"parameters": { +"amount": 0 +}, +"typeVersion": 1.1 +}, +{ +"id": "800cb05b-f5d1-47c8-869e-921915929f34", +"name": "Remove Dupes", +"type": "n8n-nodes-base.removeDuplicates", +"position": [ +3780, +3720 +], +"parameters": { +"compare": "selectedFields", +"options": {}, +"fieldsToCompare": "source.link" +}, +"typeVersion": 2 +}, +{ +"id": "d8203c40-aa0b-44b9-8dfd-aea250c8d109", +"name": "Filter Results", +"type": "n8n-nodes-base.filter", +"position": [ +3620, +3720 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "42872456-411b-4d86-a9dd-b907d001ea1c", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.type }}", +"rightValue": "normal" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "5714dc09-fd67-4285-9434-ac97cd80dec1", +"name": "Research", +"type": "n8n-nodes-base.executeWorkflow", +"onError": "continueErrorOutput", +"position": [ +3460, +2980 +], +"parameters": { +"mode": "each", +"options": { +"waitForSubWorkflow": true +}, +"workflowId": { +"__rl": true, +"mode": "id", +"value": "={{ $workflow.id }}" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "2a2d3271-b0b6-4a1a-94e1-9b01399ba88f", +"name": "Has Results?", +"type": "n8n-nodes-base.if", +"position": [ +3280, +3820 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "1223d607-45a8-44b1-b510-56fdbe013eba", +"operator": { +"type": "array", +"operation": "exists", +"singleValue": true +}, +"leftValue": "={{ $jmespath($json, 'origin_search.results') }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "b953082c-2d37-4549-80a7-d60535b8580e", +"name": "Response Empty", +"type": "n8n-nodes-base.set", +"position": [ +3460, +3900 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "5bb23ce9-eb72-4868-9344-9e5d3952cc52", +"name": "response", +"type": "string", +"value": "no web results" +} +] +} +}, +"executeOnce": true, +"typeVersion": 3.4 +}, +{ +"id": "41e9c328-d145-4b71-93bb-e2c448a14be0", +"name": "Response OK", +"type": "n8n-nodes-base.set", +"position": [ +5380, +3580 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "79598789-4468-4565-828f-fedc48be15c3", +"name": "response", +"type": "string", +"value": "ok" +} +] +} +}, +"executeOnce": true, +"typeVersion": 3.4 +}, +{ +"id": "5d0a7556-def9-4c70-8828-40b4d22904de", +"name": "Combine Docs", +"type": "n8n-nodes-base.aggregate", +"position": [ +4020, +4380 +], +"parameters": { +"options": {}, +"aggregate": "aggregateAllItemData" +}, +"typeVersion": 1 +}, +{ +"id": "39bd90b4-e0f5-49b0-b4a7-55a3ae8eccb2", +"name": "Template to List", +"type": "n8n-nodes-base.splitOut", +"position": [ +3280, +4200 +], +"parameters": { +"options": { +"destinationFieldName": "query" +}, +"fieldToSplitOut": "queries" +}, +"typeVersion": 1 +}, +{ +"id": "51a1da10-5ad0-4bac-9bec-55b5af3da702", +"name": "Query Templates", +"type": "n8n-nodes-base.set", +"position": [ +3100, +4200 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "e2a02550-8f53-4f8d-bb83-68ee3606736e", +"name": "queries", +"type": "array", +"value": "=[\n\"What are the core functionalities, essential features, or primary use cases of {{ $json.data.service }}?\",\n\"Is there an API overview or API categories for {{ $json.data.service }}? What main APIs are listed or mentioned?\",\n\"What industry does {{ $json.data.service }} operate in? What is the most important of the services in the industry? Return the important service as the function.\",\n\"What REST apis (GET, POST, DELETE, PATCH) and/or operations can you identify for {{ $json.data.service }}?\",\n\"Does {{ $json.data.service }} have any CURL examples? If you can, identify one such example and explain what it does.\"\n]" +} +] +} +}, +"executeOnce": true, +"typeVersion": 3.3 +}, +{ +"id": "414091b7-114b-4fc3-9755-2f87cfef239e", +"name": "Google Gemini Chat Model2", +"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini", +"position": [ +3700, +4240 +], +"parameters": { +"options": {}, +"modelName": "models/gemini-1.5-pro-002" +}, +"typeVersion": 1 +}, +{ +"id": "1f0f45ff-3bc9-4786-92e1-319244d020c0", +"name": "For Each Template...", +"type": "n8n-nodes-base.splitInBatches", +"position": [ +3460, +4200 +], +"parameters": { +"options": {} +}, +"typeVersion": 3 +}, +{ +"id": "2e577e62-7f89-4c99-b540-ce8c44f19a55", +"name": "Query & Docs", +"type": "n8n-nodes-base.set", +"position": [ +4180, +4380 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "fdaea3de-3c9a-4f26-b7dc-769e534006a9", +"name": "query", +"type": "string", +"value": "={{ $('For Each Template...').item.json.query }}" +}, +{ +"id": "88198374-d2f9-4ae7-b262-d3b2e630e0ac", +"name": "documents", +"type": "string", +"value": "={{ $json.data.map(item => item.document.pageContent.replaceAll('\\n', ' ')).join('\\n---\\n') }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "548d51fd-9740-4b4c-9c81-db62d2b31053", +"name": "Identify Service Products", +"type": "@n8n/n8n-nodes-langchain.informationExtractor", +"position": [ +3700, +4100 +], +"parameters": { +"text": "={{ $json.query }}", +"options": { +"systemPromptTemplate": "=Use the following document to answer the user's question:\n```\n{{ $json.documents.replace(/[\\{\\}]/g, '') }}\n```" +}, +"attributes": { +"attributes": [ +{ +"name": "product_or_solution", +"required": true, +"description": "A product or solution offered by the service" +}, +{ +"name": "description", +"required": true, +"description": "description of what the product or solution of the service does" +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "aa7041e9-4ac8-47f9-b98e-cf57873922bb", +"name": "Extract API Templates", +"type": "n8n-nodes-base.set", +"position": [ +4180, +4200 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "e2a02550-8f53-4f8d-bb83-68ee3606736e", +"name": "query", +"type": "string", +"value": "=I'm interested in {{ $json.output.product_or_solution }} apis which {{ $json.output.description }} What are the GET, POST, PATCH and/or DELETE endpoints of the {{ $json.output.product_or_solution }} api?" +} +] +} +}, +"typeVersion": 3.3 +}, +{ +"id": "e2b371c1-52af-4e57-877c-6933ba84e2d5", +"name": "Embeddings Google Gemini2", +"type": "@n8n/n8n-nodes-langchain.embeddingsGoogleGemini", +"position": [ +4600, +4520 +], +"parameters": { +"modelName": "models/text-embedding-004" +}, +"typeVersion": 1 +}, +{ +"id": "d808c591-34e2-455f-96b1-3689d950608d", +"name": "Search in Relevant Docs1", +"type": "@n8n/n8n-nodes-langchain.vectorStoreQdrant", +"position": [ +4600, +4380 +], +"parameters": { +"mode": "load", +"topK": 20, +"prompt": "={{ $json.query }}", +"options": { +"searchFilterJson": "={{\n{\n \"must\": [\n {\n \"key\": \"metadata.service\",\n \"match\": {\n \"value\": $('EventRouter').first().json.data.service\n }\n }\n ]\n}\n}}" +}, +"qdrantCollection": { +"__rl": true, +"mode": "id", +"value": "={{ $('EventRouter').first().json.data.collection }}" +} +}, +"typeVersion": 1 +}, +{ +"id": "222bde31-57fa-46c4-a23b-ec2d1b3c7e2d", +"name": "Combine Docs1", +"type": "n8n-nodes-base.aggregate", +"position": [ +4920, +4380 +], +"parameters": { +"options": {}, +"aggregate": "aggregateAllItemData" +}, +"typeVersion": 1 +}, +{ +"id": "57677d83-a79a-4b71-9977-ee2324f5d593", +"name": "Query & Docs1", +"type": "n8n-nodes-base.set", +"position": [ +5080, +4380 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "fdaea3de-3c9a-4f26-b7dc-769e534006a9", +"name": "query", +"type": "string", +"value": "={{ $('For Each Template...1').item.json.query }}" +}, +{ +"id": "88198374-d2f9-4ae7-b262-d3b2e630e0ac", +"name": "documents", +"type": "string", +"value": "={{\n$json.data\n .map(item =>\n`url: ${item.document.metadata.url}\ncontent: ${item.document.pageContent}`\n )\n .join('\\n---\\n')\n .replaceAll('\\n\\n', '\\n')\n}}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "124c3b07-3210-4190-8865-e18017fc9e6c", +"name": "For Each Template...1", +"type": "n8n-nodes-base.splitInBatches", +"position": [ +4380, +4200 +], +"parameters": { +"options": {} +}, +"typeVersion": 3 +}, +{ +"id": "8ea4a5da-c471-4201-a08b-9c18ed08ddc7", +"name": "Merge Lists", +"type": "n8n-nodes-base.code", +"position": [ +4920, +4200 +], +"parameters": { +"jsCode": "return $input.all().flatMap(input => input.json.output) || [];" +}, +"typeVersion": 2, +"alwaysOutputData": true +}, +{ +"id": "0e38cd3c-c843-4f6d-bdb6-901a8c12acbf", +"name": "Remove Duplicates", +"type": "n8n-nodes-base.removeDuplicates", +"position": [ +5280, +4200 +], +"parameters": { +"compare": "selectedFields", +"options": {}, +"fieldsToCompare": "method, url" +}, +"typeVersion": 2 +}, +{ +"id": "8f127f7a-e351-4b30-82dd-1f785be4a765", +"name": "Append Row", +"type": "n8n-nodes-base.googleSheets", +"position": [ +5440, +4200 +], +"parameters": { +"columns": { +"value": { +"url": "={{ $json.url }}", +"method": "={{ $json.method }}", +"service": "={{ $('EventRouter').first().json.data.service }}", +"resource": "={{ $json.resource }}", +"operation": "={{ $json.operation }}", +"description": "={{ $json.description }}", +"documentation_url": "={{ $json.documentation_url }}" +}, +"schema": [ +{ +"id": "service", +"type": "string", +"display": true, +"required": false, +"displayName": "service", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "resource", +"type": "string", +"display": true, +"required": false, +"displayName": "resource", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "operation", +"type": "string", +"display": true, +"required": false, +"displayName": "operation", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "description", +"type": "string", +"display": true, +"required": false, +"displayName": "description", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "url", +"type": "string", +"display": true, +"required": false, +"displayName": "url", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "method", +"type": "string", +"display": true, +"required": false, +"displayName": "method", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "documentation_url", +"type": "string", +"display": true, +"required": false, +"displayName": "documentation_url", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [] +}, +"options": { +"useAppend": true +}, +"operation": "append", +"sheetName": { +"__rl": true, +"mode": "list", +"value": 1042334767, +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit#gid=1042334767", +"cachedResultName": "Extracted API Operations" +}, +"documentId": { +"__rl": true, +"mode": "list", +"value": "1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit?usp=drivesdk", +"cachedResultName": "API Schema Crawler & Extractor" +} +}, +"typeVersion": 4.5 +}, +{ +"id": "d9f490e2-320e-4dc1-af8f-ac7f6a61568d", +"name": "Response OK1", +"type": "n8n-nodes-base.set", +"position": [ +5600, +4200 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "79598789-4468-4565-828f-fedc48be15c3", +"name": "response", +"type": "string", +"value": "ok" +} +] +} +}, +"executeOnce": true, +"typeVersion": 3.4 +}, +{ +"id": "7780b6ee-0fde-40bb-aef6-e67b883645e1", +"name": "Has Operations?", +"type": "n8n-nodes-base.if", +"position": [ +5080, +4200 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "a95420a7-6265-4ea3-9c01-82c2d7aeb4f8", +"operator": { +"type": "object", +"operation": "notEmpty", +"singleValue": true +}, +"leftValue": "={{ $input.first().json }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "6589673d-984d-4a1e-a655-1bc19d2b154e", +"name": "Response Empty1", +"type": "n8n-nodes-base.set", +"position": [ +5280, +4380 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "5bb23ce9-eb72-4868-9344-9e5d3952cc52", +"name": "response", +"type": "string", +"value": "no api operations found" +} +] +} +}, +"executeOnce": true, +"typeVersion": 3.4 +}, +{ +"id": "c5dc3eac-a3a5-481d-a8bc-8b653d88143d", +"name": "Research Pending", +"type": "n8n-nodes-base.googleSheets", +"position": [ +3180, +2980 +], +"parameters": { +"columns": { +"value": { +"row_number": "={{ $('For Each Research...').item.json.row_number }}", +"Stage 1 - Research": "=pending" +}, +"schema": [ +{ +"id": "Service", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Service", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Website", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Website", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 1 - Research", +"type": "string", +"display": true, +"required": false, +"displayName": "Stage 1 - Research", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 2 - Extraction", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Stage 2 - Extraction", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 3 - Output File", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Stage 3 - Output File", +"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": "list", +"value": "gid=0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit#gid=0", +"cachedResultName": "Sheet1" +}, +"documentId": { +"__rl": true, +"mode": "list", +"value": "1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit?usp=drivesdk", +"cachedResultName": "API Schema Crawler & Extractor" +} +}, +"typeVersion": 4.5 +}, +{ +"id": "39bceadb-6c3b-4b52-82b9-bdcecd9a164a", +"name": "Research Result", +"type": "n8n-nodes-base.googleSheets", +"position": [ +3620, +2980 +], +"parameters": { +"columns": { +"value": { +"row_number": "={{ $('For Each Research...').item.json.row_number }}", +"Stage 1 - Research": "={{ $json.response }}" +}, +"schema": [ +{ +"id": "Service", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Service", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Website", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Website", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 1 - Research", +"type": "string", +"display": true, +"required": false, +"displayName": "Stage 1 - Research", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 2 - Extraction", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Stage 2 - Extraction", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 3 - Output File", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Stage 3 - Output File", +"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": "list", +"value": "gid=0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit#gid=0", +"cachedResultName": "Sheet1" +}, +"documentId": { +"__rl": true, +"mode": "list", +"value": "1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit?usp=drivesdk", +"cachedResultName": "API Schema Crawler & Extractor" +} +}, +"typeVersion": 4.5 +}, +{ +"id": "0bd07f31-1c51-45aa-8316-b658aa214293", +"name": "Research Error", +"type": "n8n-nodes-base.googleSheets", +"position": [ +3620, +3160 +], +"parameters": { +"columns": { +"value": { +"row_number": "={{ $('For Each Research...').item.json.row_number }}", +"Stage 1 - Research": "=error" +}, +"schema": [ +{ +"id": "Service", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Service", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Website", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Website", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 1 - Research", +"type": "string", +"display": true, +"required": false, +"displayName": "Stage 1 - Research", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 2 - Extraction", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Stage 2 - Extraction", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 3 - Output File", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Stage 3 - Output File", +"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": "list", +"value": "gid=0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit#gid=0", +"cachedResultName": "Sheet1" +}, +"documentId": { +"__rl": true, +"mode": "list", +"value": "1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit?usp=drivesdk", +"cachedResultName": "API Schema Crawler & Extractor" +} +}, +"typeVersion": 4.5 +}, +{ +"id": "0385784f-95ef-46c3-82c4-50fcf7146736", +"name": "Extract Pending", +"type": "n8n-nodes-base.googleSheets", +"position": [ +4160, +2980 +], +"parameters": { +"columns": { +"value": { +"row_number": "={{ $('For Each Extract...').item.json.row_number }}", +"Stage 2 - Extraction": "pending" +}, +"schema": [ +{ +"id": "Service", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Service", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Website", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Website", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 1 - Research", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Stage 1 - Research", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 2 - Extraction", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Stage 2 - Extraction", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 3 - Output File", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Stage 3 - Output File", +"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": "list", +"value": "gid=0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit#gid=0", +"cachedResultName": "Sheet1" +}, +"documentId": { +"__rl": true, +"mode": "list", +"value": "1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit?usp=drivesdk", +"cachedResultName": "API Schema Crawler & Extractor" +} +}, +"executeOnce": false, +"typeVersion": 4.5 +}, +{ +"id": "21c1e982-25a6-4a00-b8d3-6c299c452106", +"name": "Research Event", +"type": "n8n-nodes-base.set", +"position": [ +3320, +2980 +], +"parameters": { +"mode": "raw", +"options": {}, +"jsonOutput": "={{\n{\n \"eventType\": \"research\",\n \"createdAt\": $now.toISO(),\n \"executedById\": $execution.id,\n \"data\": {\n \"row_number\": $('For Each Research...').item.json.row_number,\n \"service\": $('For Each Research...').item.json.Service,\n \"url\": $('For Each Research...').item.json.Website,\n \"collection\": \"api_schema_crawler_and_extractor\"\n }\n}\n}}" +}, +"typeVersion": 3.4 +}, +{ +"id": "c83f99f1-e28f-4c15-aff8-da25bb5dfe3b", +"name": "Extract Event", +"type": "n8n-nodes-base.set", +"position": [ +4300, +2980 +], +"parameters": { +"mode": "raw", +"options": {}, +"jsonOutput": "={{\n{\n \"eventType\": \"extract\",\n \"createdAt\": $now.toISO(),\n \"executedById\": $execution.id,\n \"data\": {\n \"row_number\": $('For Each Extract...').item.json.row_number,\n \"service\": $('For Each Extract...').item.json.Service,\n \"url\": $('For Each Extract...').item.json.Website,\n \"collection\": \"api_schema_crawler_and_extractor\"\n }\n}\n}}" +}, +"typeVersion": 3.4 +}, +{ +"id": "88c3caec-75f7-47a1-9b50-1246c457c2b4", +"name": "Extract", +"type": "n8n-nodes-base.executeWorkflow", +"onError": "continueErrorOutput", +"position": [ +4440, +2980 +], +"parameters": { +"mode": "each", +"options": { +"waitForSubWorkflow": true +}, +"workflowId": { +"__rl": true, +"mode": "id", +"value": "={{ $workflow.id }}" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "2342b7ff-b00d-439a-a859-63fd0a6bac3a", +"name": "Extract Result", +"type": "n8n-nodes-base.googleSheets", +"position": [ +4600, +2980 +], +"parameters": { +"columns": { +"value": { +"row_number": "={{ $('For Each Extract...').item.json.row_number }}", +"Stage 2 - Extraction": "={{ $json.response }}" +}, +"schema": [ +{ +"id": "Service", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Service", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Website", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Website", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 1 - Research", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Stage 1 - Research", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 2 - Extraction", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Stage 2 - Extraction", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 3 - Output File", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Stage 3 - Output File", +"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": "list", +"value": "gid=0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit#gid=0", +"cachedResultName": "Sheet1" +}, +"documentId": { +"__rl": true, +"mode": "list", +"value": "1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit?usp=drivesdk", +"cachedResultName": "API Schema Crawler & Extractor" +} +}, +"typeVersion": 4.5 +}, +{ +"id": "d4c423c9-1d6a-4a69-9302-92ec79734d61", +"name": "Extract Error", +"type": "n8n-nodes-base.googleSheets", +"position": [ +4600, +3160 +], +"parameters": { +"columns": { +"value": { +"row_number": "={{ $('For Each Extract...').item.json.row_number }}", +"Stage 2 - Extraction": "error" +}, +"schema": [ +{ +"id": "Service", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Service", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Website", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Website", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 1 - Research", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Stage 1 - Research", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 2 - Extraction", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Stage 2 - Extraction", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 3 - Output File", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Stage 3 - Output File", +"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": "list", +"value": "gid=0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit#gid=0", +"cachedResultName": "Sheet1" +}, +"documentId": { +"__rl": true, +"mode": "list", +"value": "1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit?usp=drivesdk", +"cachedResultName": "API Schema Crawler & Extractor" +} +}, +"typeVersion": 4.5 +}, +{ +"id": "f64254d6-4493-4aaf-8160-35e8ff4fdc34", +"name": "Get API Operations", +"type": "n8n-nodes-base.googleSheets", +"position": [ +3100, +4740 +], +"parameters": { +"options": {}, +"filtersUI": { +"values": [ +{ +"lookupValue": "={{ $json.data.service }}", +"lookupColumn": "service" +} +] +}, +"sheetName": { +"__rl": true, +"mode": "list", +"value": 1042334767, +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit#gid=1042334767", +"cachedResultName": "Extracted API Operations" +}, +"documentId": { +"__rl": true, +"mode": "list", +"value": "1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit?usp=drivesdk", +"cachedResultName": "API Schema Crawler & Extractor" +} +}, +"typeVersion": 4.5 +}, +{ +"id": "fa748b63-3d2b-4cf3-b1fb-1bd953e5054b", +"name": "Contruct JSON Schema", +"type": "n8n-nodes-base.code", +"position": [ +3280, +4740 +], +"parameters": { +"jsCode": "const service = {\n documentation_url: $('EventRouter').first().json.data.url,\n endpoints: [],\n};\n\nconst resources = Array.from(new Set($input.all().map(item => item.json.resource.toLowerCase().trim())));\n\nfor (const resource of resources) {\n const resourceLabel = resource.replace('api', '').trim();\n if (!resourceLabel) continue;\n const endpoint = {\n resource: resourceLabel[0].toUpperCase() + resourceLabel.substring(1, resourceLabel.length)\n };\n const operations = $input.all()\n .filter(item => item.json.resource.toLowerCase().trim() === resource)\n .map(item => item.json);\n endpoint.operations = operations.map(op => ({\n \"operation\": op.operation[0].toUpperCase() + op.operation.substring(1, op.operation.length),\n \"description\": op.description.match(/(^[^\\.]+.)/)[0],\n \"ApiUrl\": op.url,\n \"method\": op.method.toUpperCase(),\n \"method_documentation_url\": op.documentation_url || ''\n }));\n service.endpoints.push(endpoint);\n}\n\nreturn service;" +}, +"typeVersion": 2 +}, +{ +"id": "e60b7ccb-baa2-4095-8425-0e20bcdbfdd2", +"name": "Upload to Drive", +"type": "n8n-nodes-base.googleDrive", +"position": [ +3640, +4740 +], +"parameters": { +"name": "={{ $json.filename }}", +"content": "={{ $json.data }}", +"driveId": { +"__rl": true, +"mode": "list", +"value": "My Drive" +}, +"options": {}, +"folderId": { +"__rl": true, +"mode": "list", +"value": "149rBJYv9RKQx-vQO2qKUGfUzxk_J4lfw", +"cachedResultUrl": "https://drive.google.com/drive/folders/149rBJYv9RKQx-vQO2qKUGfUzxk_J4lfw", +"cachedResultName": "63. API Schema Extractor Remake" +}, +"operation": "createFromText" +}, +"typeVersion": 3 +}, +{ +"id": "f90546e6-3610-4198-87fc-96d7e2b6bc57", +"name": "Set Upload Fields", +"type": "n8n-nodes-base.set", +"position": [ +3460, +4740 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "3c7d4946-c385-4aff-93ec-ae0850964099", +"name": "filename", +"type": "string", +"value": "={{\n $('EventRouter').first().json.data.service\n .replace(/\\W+/, '_')\n .toLowerCase()\n}}_api_operations_{{ $now.format('yyyyMMddhhmmss') }}.json" +}, +{ +"id": "4a7a9fae-7267-4ef6-ae33-ac4cd9777ee9", +"name": "data", +"type": "string", +"value": "={{ JSON.stringify($json, null, 4) }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "c814b48d-2005-4150-a481-956f0b9506a5", +"name": "Response OK2", +"type": "n8n-nodes-base.set", +"position": [ +3820, +4740 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "79598789-4468-4565-828f-fedc48be15c3", +"name": "response", +"type": "object", +"value": "={{\n({\n id: $json.id,\n filename: $('Set Upload Fields').item.json.filename\n}).toJsonString()\n}}" +} +] +} +}, +"executeOnce": true, +"typeVersion": 3.4 +}, +{ +"id": "4b1efa99-e8c8-49f5-8db8-916b8dde838d", +"name": "Generate Event", +"type": "n8n-nodes-base.set", +"position": [ +5300, +2980 +], +"parameters": { +"mode": "raw", +"options": {}, +"jsonOutput": "={{\n{\n \"eventType\": \"generate\",\n \"createdAt\": $now.toISO(),\n \"executedById\": $execution.id,\n \"data\": {\n \"row_number\": $('For Each Generate...').item.json.row_number,\n \"service\": $('For Each Generate...').item.json.Service,\n \"url\": $('For Each Generate...').item.json.Website,\n \"collection\": \"api_schema_crawler_and_extractor\"\n }\n}\n}}" +}, +"typeVersion": 3.4 +}, +{ +"id": "49b82a1a-d51e-4caf-b7ab-8d27d0585b60", +"name": "Generate Pending", +"type": "n8n-nodes-base.googleSheets", +"position": [ +5160, +2980 +], +"parameters": { +"columns": { +"value": { +"row_number": "={{ $('For Each Generate...').item.json.row_number }}", +"Stage 3 - Output File": "pending" +}, +"schema": [ +{ +"id": "Service", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Service", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Website", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Website", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 1 - Research", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Stage 1 - Research", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 2 - Extraction", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Stage 2 - Extraction", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 3 - Output File", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Stage 3 - Output File", +"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": "list", +"value": "gid=0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit#gid=0", +"cachedResultName": "Sheet1" +}, +"documentId": { +"__rl": true, +"mode": "list", +"value": "1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit?usp=drivesdk", +"cachedResultName": "API Schema Crawler & Extractor" +} +}, +"executeOnce": false, +"typeVersion": 4.5 +}, +{ +"id": "7d1a937c-49cc-40d7-b2ca-d315c5efca93", +"name": "Generate", +"type": "n8n-nodes-base.executeWorkflow", +"onError": "continueErrorOutput", +"position": [ +5440, +2980 +], +"parameters": { +"mode": "each", +"options": { +"waitForSubWorkflow": true +}, +"workflowId": { +"__rl": true, +"mode": "id", +"value": "={{ $workflow.id }}" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "f35d843d-6c40-4725-b73f-8ca1a8e219bb", +"name": "Generate Error", +"type": "n8n-nodes-base.googleSheets", +"position": [ +5600, +3160 +], +"parameters": { +"columns": { +"value": { +"row_number": "={{ $('For Each Generate...').item.json.row_number }}", +"Stage 3 - Output File": "error" +}, +"schema": [ +{ +"id": "Service", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Service", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Website", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Website", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 1 - Research", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Stage 1 - Research", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 2 - Extraction", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Stage 2 - Extraction", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 3 - Output File", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Stage 3 - Output File", +"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": "list", +"value": "gid=0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit#gid=0", +"cachedResultName": "Sheet1" +}, +"documentId": { +"__rl": true, +"mode": "list", +"value": "1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit?usp=drivesdk", +"cachedResultName": "API Schema Crawler & Extractor" +} +}, +"typeVersion": 4.5 +}, +{ +"id": "e2f1f8e8-6852-4f19-98ec-85d9bd42729c", +"name": "Generate Result", +"type": "n8n-nodes-base.googleSheets", +"position": [ +5600, +2980 +], +"parameters": { +"columns": { +"value": { +"row_number": "={{ $('For Each Generate...').item.json.row_number }}", +"Output Destination": "={{ $json.response.filename }}", +"Stage 3 - Output File": "ok" +}, +"schema": [ +{ +"id": "Service", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Service", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Website", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Website", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 1 - Research", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Stage 1 - Research", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 2 - Extraction", +"type": "string", +"display": true, +"removed": true, +"required": false, +"displayName": "Stage 2 - Extraction", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Stage 3 - Output File", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Stage 3 - Output File", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Output Destination", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Output Destination", +"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": "list", +"value": "gid=0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit#gid=0", +"cachedResultName": "Sheet1" +}, +"documentId": { +"__rl": true, +"mode": "list", +"value": "1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit?usp=drivesdk", +"cachedResultName": "API Schema Crawler & Extractor" +} +}, +"typeVersion": 4.5 +}, +{ +"id": "00c5b05b-fd70-4d58-8fc6-4e9b8d689a43", +"name": "Get All Extract", +"type": "n8n-nodes-base.googleSheets", +"position": [ +3620, +2820 +], +"parameters": { +"options": {}, +"filtersUI": { +"values": [ +{ +"lookupValue": "=ok", +"lookupColumn": "Stage 1 - Research" +}, +{ +"lookupValue": "={{ \"\" }}", +"lookupColumn": "Stage 2 - Extraction" +} +] +}, +"sheetName": { +"__rl": true, +"mode": "list", +"value": "gid=0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit#gid=0", +"cachedResultName": "Sheet1" +}, +"documentId": { +"__rl": true, +"mode": "list", +"value": "1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit?usp=drivesdk", +"cachedResultName": "API Schema Crawler & Extractor" +} +}, +"executeOnce": true, +"typeVersion": 4.5, +"alwaysOutputData": true +}, +{ +"id": "c477ea01-028d-4e69-b772-adb8c03d1522", +"name": "Get All Research", +"type": "n8n-nodes-base.googleSheets", +"position": [ +2640, +2820 +], +"parameters": { +"options": {}, +"filtersUI": { +"values": [ +{ +"lookupValue": "={{ \"\" }}", +"lookupColumn": "Stage 1 - Research" +} +] +}, +"sheetName": { +"__rl": true, +"mode": "list", +"value": "gid=0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit#gid=0", +"cachedResultName": "Sheet1" +}, +"documentId": { +"__rl": true, +"mode": "list", +"value": "1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit?usp=drivesdk", +"cachedResultName": "API Schema Crawler & Extractor" +} +}, +"credentials": { +"googleSheetsOAuth2Api": { +"id": "aALuyzBGGfmdBzrU", +"name": "Google Sheets account 2" +} +}, +"typeVersion": 4.5, +"alwaysOutputData": true +}, +{ +"id": "60ba84c1-40cf-492f-bf52-c9edf5925646", +"name": "For Each Research...", +"type": "n8n-nodes-base.splitInBatches", +"position": [ +3020, +2820 +], +"parameters": { +"options": {} +}, +"typeVersion": 3 +}, +{ +"id": "5365cd1a-c7f8-40fb-84b3-9e5306ecf462", +"name": "For Each Extract...", +"type": "n8n-nodes-base.splitInBatches", +"position": [ +4000, +2820 +], +"parameters": { +"options": {} +}, +"typeVersion": 3 +}, +{ +"id": "d7a0743f-5f83-4c9b-b11c-85e2df3a4ecc", +"name": "Wait1", +"type": "n8n-nodes-base.wait", +"position": [ +4780, +3160 +], +"webhookId": "e9ad3ef0-7403-4e65-b0a4-4afdfb0cbc6d", +"parameters": { +"amount": 0 +}, +"typeVersion": 1.1 +}, +{ +"id": "ec09ac70-5e05-463c-9d30-027e691a36b4", +"name": "All Research Done?", +"type": "n8n-nodes-base.if", +"position": [ +2800, +2820 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "8d4b0159-af18-445e-a9ee-bd7952d8e0bd", +"operator": { +"type": "object", +"operation": "empty", +"singleValue": true +}, +"leftValue": "={{ $input.first().json }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "cd892e11-b4de-42f1-bab9-4bd783494c8a", +"name": "All Extract Done?", +"type": "n8n-nodes-base.if", +"position": [ +3780, +2820 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "8d4b0159-af18-445e-a9ee-bd7952d8e0bd", +"operator": { +"type": "object", +"operation": "empty", +"singleValue": true +}, +"leftValue": "={{ $input.first().json }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "426091fb-d0eb-4589-8f2f-2bbeb9174cfc", +"name": "Get All Generate", +"type": "n8n-nodes-base.googleSheets", +"position": [ +4600, +2820 +], +"parameters": { +"options": {}, +"filtersUI": { +"values": [ +{ +"lookupValue": "=ok", +"lookupColumn": "Stage 1 - Research" +}, +{ +"lookupValue": "=ok", +"lookupColumn": "Stage 2 - Extraction" +}, +{ +"lookupValue": "={{ \"\" }}", +"lookupColumn": "Stage 3 - Output File" +} +] +}, +"sheetName": { +"__rl": true, +"mode": "list", +"value": "gid=0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit#gid=0", +"cachedResultName": "Sheet1" +}, +"documentId": { +"__rl": true, +"mode": "list", +"value": "1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1l59ikBvEwPNSWIm2k6KRMFPTNImJPYqs9bzGT5dUiU0/edit?usp=drivesdk", +"cachedResultName": "API Schema Crawler & Extractor" +} +}, +"executeOnce": true, +"typeVersion": 4.5 +}, +{ +"id": "01e91cf6-5bd5-4891-ba1f-95176e444fe6", +"name": "All Generate Done?", +"type": "n8n-nodes-base.if", +"position": [ +4780, +2820 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "8d4b0159-af18-445e-a9ee-bd7952d8e0bd", +"operator": { +"type": "object", +"operation": "empty", +"singleValue": true +}, +"leftValue": "={{ $input.first().json }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "08f3505d-aad8-475a-bf08-e3da12798367", +"name": "For Each Generate...", +"type": "n8n-nodes-base.splitInBatches", +"position": [ +5000, +2820 +], +"parameters": { +"options": {} +}, +"typeVersion": 3 +}, +{ +"id": "1a1b30bd-91ab-41bd-9ead-39d24fc2643f", +"name": "Wait2", +"type": "n8n-nodes-base.wait", +"position": [ +5780, +3160 +], +"webhookId": "e9ad3ef0-7403-4e65-b0a4-4afdfb0cbc6d", +"parameters": { +"amount": 0 +}, +"typeVersion": 1.1 +}, +{ +"id": "8f2be6bb-ab65-4c92-9ca1-d7ffa936a2a3", +"name": "Has Results?1", +"type": "n8n-nodes-base.if", +"position": [ +4260, +3720 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "1223d607-45a8-44b1-b510-56fdbe013eba", +"operator": { +"type": "array", +"operation": "notEmpty", +"singleValue": true +}, +"leftValue": "={{ $input.all().filter(item => item.json.body) }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "82fe66bf-4348-4673-8c64-3415f642fb4b", +"name": "Response Scrape Error", +"type": "n8n-nodes-base.set", +"position": [ +4460, +3900 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "5bb23ce9-eb72-4868-9344-9e5d3952cc52", +"name": "response", +"type": "string", +"value": "web scraping error" +} +] +} +}, +"executeOnce": true, +"typeVersion": 3.4 +}, +{ +"id": "3625591b-cb48-4131-ae8a-56d1e132bb5a", +"name": "Has Results?3", +"type": "n8n-nodes-base.if", +"position": [ +4780, +3580 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "1223d607-45a8-44b1-b510-56fdbe013eba", +"operator": { +"type": "array", +"operation": "notEmpty", +"singleValue": true +}, +"leftValue": "={{ $input.all().filter(item => item.json.body) }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "f82a4a25-5f93-4ba4-baae-08283c4ccadd", +"name": "Response No API Docs", +"type": "n8n-nodes-base.set", +"position": [ +4980, +3740 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "5bb23ce9-eb72-4868-9344-9e5d3952cc52", +"name": "response", +"type": "string", +"value": "no api docs in web results" +} +] +} +}, +"executeOnce": true, +"typeVersion": 3.4 +}, +{ +"id": "4c3bb934-966c-445a-893f-0676a59140ee", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +3020, +2580 +], +"parameters": { +"width": 620, +"height": 180, +"content": "## Stage 1 - Research for API Documentation\n- Fetch a list of services pending research from Database (Google Sheet)\n- Uses a search engine (Google) to find API Documentation for each service\n- Uses Webscraper (Apify) to read the contents of search results to filter irrelevant pages\n- Stores webpage contents and metadata into Vector Store (Qdrant)" +}, +"typeVersion": 1 +}, +{ +"id": "bc269a57-f353-4cc8-bd2e-43236fa55d39", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +4000, +2580 +], +"parameters": { +"width": 760, +"height": 180, +"content": "## Stage 2 - Extract API Operations From Documentation\n- Fetch a list of services pending extraction from Database (Google Sheet)\n- Query Vector store (Qdrant) to figure out service's products, solutions and offerings\n- Query Vector store (Qdrant) again for API documentation relevant to these products, solutions and offerings\n- Extract any API operations found in the API documentation results using LLM (Gemini)\n- Store extracted API operations into Database (Google Sheet)" +}, +"typeVersion": 1 +}, +{ +"id": "d2dcad47-f655-4a15-ac92-6dab05eea4e1", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +5000, +2580 +], +"parameters": { +"width": 740, +"height": 180, +"content": "## Stage 3 - Generate Custom Schema From API Operations\n- Fetch a list of services pending generation from Database (Google Sheet)\n- Fetch all API operations for each service from Database (Google Sheet)\n- Use Code node to combine and group all API operations for a service and convert to a custom schema\n- Upload the resulting custom schema to file storage (Google Drive)" +}, +"typeVersion": 1 +}, +{ +"id": "d1e1a271-4260-49c3-bda6-2864605c7365", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +3100, +3680 +], +"parameters": { +"color": 5, +"width": 180, +"height": 80, +"content": "## Stage 1 - Subworkflow" +}, +"typeVersion": 1 +}, +{ +"id": "1e50f04a-94ff-48b4-aa99-cd1d4f1d12be", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +3100, +4080 +], +"parameters": { +"color": 5, +"width": 180, +"height": 80, +"content": "## Stage 2 - Subworkflow" +}, +"typeVersion": 1 +}, +{ +"id": "f8334dbd-b542-404a-b4fc-6cf7cc07730d", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +3100, +4620 +], +"parameters": { +"color": 5, +"width": 180, +"height": 80, +"content": "## Stage 3 - Subworkflow" +}, +"typeVersion": 1 +} +], +"pinData": { +"Execute Workflow Trigger": [ +{ +"data": { +"url": "https://www.formstack.com/", +"service": "Formstack", +"collection": "api_schema_crawler_and_extractor", +"row_number": 2 +}, +"createdAt": "2024-12-07T12:22:35.344-05:00", +"eventType": "research", +"executedById": "10234" +} +] +}, +"connections": { +"Wait": { +"main": [ +[ +{ +"node": "For Each Research...", +"type": "main", +"index": 0 +} +] +] +}, +"Wait1": { +"main": [ +[ +{ +"node": "For Each Extract...", +"type": "main", +"index": 0 +} +] +] +}, +"Wait2": { +"main": [ +[ +{ +"node": "For Each Generate...", +"type": "main", +"index": 0 +} +] +] +}, +"Extract": { +"main": [ +[ +{ +"node": "Extract Result", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Extract Error", +"type": "main", +"index": 0 +} +] +] +}, +"Generate": { +"main": [ +[ +{ +"node": "Generate Result", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Generate Error", +"type": "main", +"index": 0 +} +] +] +}, +"Research": { +"main": [ +[ +{ +"node": "Research Result", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Research Error", +"type": "main", +"index": 0 +} +] +] +}, +"Append Row": { +"main": [ +[ +{ +"node": "Response OK1", +"type": "main", +"index": 0 +} +] +] +}, +"EventRouter": { +"main": [ +[ +{ +"node": "Web Search For API Schema", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Query Templates", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Get API Operations", +"type": "main", +"index": 0 +} +] +] +}, +"Merge Lists": { +"main": [ +[ +{ +"node": "Has Operations?", +"type": "main", +"index": 0 +} +] +] +}, +"Combine Docs": { +"main": [ +[ +{ +"node": "Query & Docs", +"type": "main", +"index": 0 +} +] +] +}, +"Has Results?": { +"main": [ +[ +{ +"node": "Results to List", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Response Empty", +"type": "main", +"index": 0 +} +] +] +}, +"Query & Docs": { +"main": [ +[ +{ +"node": "For Each Template...", +"type": "main", +"index": 0 +} +] +] +}, +"Remove Dupes": { +"main": [ +[ +{ +"node": "Scrape Webpage Contents", +"type": "main", +"index": 0 +} +] +] +}, +"Combine Docs1": { +"main": [ +[ +{ +"node": "Query & Docs1", +"type": "main", +"index": 0 +} +] +] +}, +"Extract Error": { +"main": [ +[ +{ +"node": "Wait1", +"type": "main", +"index": 0 +} +] +] +}, +"Extract Event": { +"main": [ +[ +{ +"node": "Extract", +"type": "main", +"index": 0 +} +] +] +}, +"Has Results?1": { +"main": [ +[ +{ +"node": "Has API Documentation?", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Response Scrape Error", +"type": "main", +"index": 0 +} +] +] +}, +"Has Results?3": { +"main": [ +[ +{ +"node": "Set Embedding Variables", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Response No API Docs", +"type": "main", +"index": 0 +} +] +] +}, +"Query & Docs1": { +"main": [ +[ +{ +"node": "For Each Template...1", +"type": "main", +"index": 0 +} +] +] +}, +"Execution Data": { +"main": [ +[ +{ +"node": "EventRouter", +"type": "main", +"index": 0 +} +] +] +}, +"Extract Result": { +"main": [ +[ +{ +"node": "Wait1", +"type": "main", +"index": 0 +} +] +] +}, +"Filter Results": { +"main": [ +[ +{ +"node": "Remove Dupes", +"type": "main", +"index": 0 +} +] +] +}, +"Generate Error": { +"main": [ +[ +{ +"node": "Wait2", +"type": "main", +"index": 0 +} +] +] +}, +"Generate Event": { +"main": [ +[ +{ +"node": "Generate", +"type": "main", +"index": 0 +} +] +] +}, +"Research Error": { +"main": [ +[ +{ +"node": "Wait", +"type": "main", +"index": 0 +} +] +] +}, +"Research Event": { +"main": [ +[ +{ +"node": "Research", +"type": "main", +"index": 0 +} +] +] +}, +"Extract Pending": { +"main": [ +[ +{ +"node": "Extract Event", +"type": "main", +"index": 0 +} +] +] +}, +"Generate Result": { +"main": [ +[ +{ +"node": "Wait2", +"type": "main", +"index": 0 +} +] +] +}, +"Get All Extract": { +"main": [ +[ +{ +"node": "All Extract Done?", +"type": "main", +"index": 0 +} +] +] +}, +"Has Operations?": { +"main": [ +[ +{ +"node": "Remove Duplicates", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Response Empty1", +"type": "main", +"index": 0 +} +] +] +}, +"Query Templates": { +"main": [ +[ +{ +"node": "Template to List", +"type": "main", +"index": 0 +} +] +] +}, +"Research Result": { +"main": [ +[ +{ +"node": "Wait", +"type": "main", +"index": 0 +} +] +] +}, +"Results to List": { +"main": [ +[ +{ +"node": "Filter Results", +"type": "main", +"index": 0 +} +] +] +}, +"Successful Runs": { +"main": [ +[ +{ +"node": "Has Results?1", +"type": "main", +"index": 0 +} +] +] +}, +"Upload to Drive": { +"main": [ +[ +{ +"node": "Response OK2", +"type": "main", +"index": 0 +} +] +] +}, +"Generate Pending": { +"main": [ +[ +{ +"node": "Generate Event", +"type": "main", +"index": 0 +} +] +] +}, +"Get All Generate": { +"main": [ +[ +{ +"node": "All Generate Done?", +"type": "main", +"index": 0 +} +] +] +}, +"Get All Research": { +"main": [ +[ +{ +"node": "All Research Done?", +"type": "main", +"index": 0 +} +] +] +}, +"Research Pending": { +"main": [ +[ +{ +"node": "Research Event", +"type": "main", +"index": 0 +} +] +] +}, +"Split Out Chunks": { +"main": [ +[ +{ +"node": "Store Document Embeddings", +"type": "main", +"index": 0 +} +] +] +}, +"Template to List": { +"main": [ +[ +{ +"node": "For Each Template...", +"type": "main", +"index": 0 +} +] +] +}, +"All Extract Done?": { +"main": [ +[ +{ +"node": "Get All Generate", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "For Each Extract...", +"type": "main", +"index": 0 +} +] +] +}, +"Remove Duplicates": { +"main": [ +[ +{ +"node": "Append Row", +"type": "main", +"index": 0 +} +] +] +}, +"Set Upload Fields": { +"main": [ +[ +{ +"node": "Upload to Drive", +"type": "main", +"index": 0 +} +] +] +}, +"All Generate Done?": { +"main": [ +[], +[ +{ +"node": "For Each Generate...", +"type": "main", +"index": 0 +} +] +] +}, +"All Research Done?": { +"main": [ +[ +{ +"node": "Get All Extract", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "For Each Research...", +"type": "main", +"index": 0 +} +] +] +}, +"Get API Operations": { +"main": [ +[ +{ +"node": "Contruct JSON Schema", +"type": "main", +"index": 0 +} +] +] +}, +"Default Data Loader": { +"ai_document": [ +[ +{ +"node": "Store Document Embeddings", +"type": "ai_document", +"index": 0 +} +] +] +}, +"For Each Extract...": { +"main": [ +[ +{ +"node": "Get All Generate", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Extract Pending", +"type": "main", +"index": 0 +} +] +] +}, +"Contruct JSON Schema": { +"main": [ +[ +{ +"node": "Set Upload Fields", +"type": "main", +"index": 0 +} +] +] +}, +"For Each Document...": { +"main": [ +[ +{ +"node": "Response OK", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Content Chunking @ 50k Chars", +"type": "main", +"index": 0 +} +] +] +}, +"For Each Generate...": { +"main": [ +[], +[ +{ +"node": "Generate Pending", +"type": "main", +"index": 0 +} +] +] +}, +"For Each Research...": { +"main": [ +[ +{ +"node": "Get All Extract", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Research Pending", +"type": "main", +"index": 0 +} +] +] +}, +"For Each Template...": { +"main": [ +[ +{ +"node": "Identify Service Products", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Search in Relevant Docs", +"type": "main", +"index": 0 +} +] +] +}, +"Extract API Templates": { +"main": [ +[ +{ +"node": "For Each Template...1", +"type": "main", +"index": 0 +} +] +] +}, +"For Each Template...1": { +"main": [ +[ +{ +"node": "Extract API Operations", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Search in Relevant Docs1", +"type": "main", +"index": 0 +} +] +] +}, +"Extract API Operations": { +"main": [ +[ +{ +"node": "Merge Lists", +"type": "main", +"index": 0 +} +] +] +}, +"Has API Documentation?": { +"main": [ +[ +{ +"node": "Has Results?3", +"type": "main", +"index": 0 +} +] +] +}, +"Scrape Webpage Contents": { +"main": [ +[ +{ +"node": "Successful Runs", +"type": "main", +"index": 0 +} +] +] +}, +"Search in Relevant Docs": { +"main": [ +[ +{ +"node": "Combine Docs", +"type": "main", +"index": 0 +} +] +] +}, +"Set Embedding Variables": { +"main": [ +[ +{ +"node": "For Each Document...", +"type": "main", +"index": 0 +} +] +] +}, +"Embeddings Google Gemini": { +"ai_embedding": [ +[ +{ +"node": "Store Document Embeddings", +"type": "ai_embedding", +"index": 0 +} +] +] +}, +"Execute Workflow Trigger": { +"main": [ +[ +{ +"node": "Execution Data", +"type": "main", +"index": 0 +} +] +] +}, +"Google Gemini Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Has API Documentation?", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Search in Relevant Docs1": { +"main": [ +[ +{ +"node": "Combine Docs1", +"type": "main", +"index": 0 +} +] +] +}, +"Embeddings Google Gemini1": { +"ai_embedding": [ +[ +{ +"node": "Search in Relevant Docs", +"type": "ai_embedding", +"index": 0 +} +] +] +}, +"Embeddings Google Gemini2": { +"ai_embedding": [ +[ +{ +"node": "Search in Relevant Docs1", +"type": "ai_embedding", +"index": 0 +} +] +] +}, +"Google Gemini Chat Model1": { +"ai_languageModel": [ +[ +{ +"node": "Extract API Operations", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Google Gemini Chat Model2": { +"ai_languageModel": [ +[ +{ +"node": "Identify Service Products", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Identify Service Products": { +"main": [ +[ +{ +"node": "Extract API Templates", +"type": "main", +"index": 0 +} +] +] +}, +"Store Document Embeddings": { +"main": [ +[ +{ +"node": "For Each Document...", +"type": "main", +"index": 0 +} +] +] +}, +"Web Search For API Schema": { +"main": [ +[ +{ +"node": "Has Results?", +"type": "main", +"index": 0 +} +] +] +}, +"Content Chunking @ 50k Chars": { +"main": [ +[ +{ +"node": "Split Out Chunks", +"type": "main", +"index": 0 +} +] +] +}, +"When clicking ‘Test workflow’": { +"main": [ +[ +{ +"node": "Get All Research", +"type": "main", +"index": 0 +} +] +] +}, +"Recursive Character Text Splitter1": { +"ai_textSplitter": [ +[ +{ +"node": "Default Data Loader", +"type": "ai_textSplitter", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Actioning Your Meeting Next Steps using Transcripts and AI.txt b/Actioning Your Meeting Next Steps using Transcripts and AI.txt new file mode 100644 index 0000000..a4a573f --- /dev/null +++ b/Actioning Your Meeting Next Steps using Transcripts and AI.txt @@ -0,0 +1,762 @@ +{ +"meta": { +"instanceId": "26ba763460b97c249b82942b23b6384876dfeb9327513332e743c5f6219c2b8e" +}, +"nodes": [ +{ +"id": "bec5c6c1-52d4-4665-b814-56a6bb82ea6b", +"name": "OpenAI Chat Model1", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +800, +660 +], +"parameters": { +"options": { +"temperature": 0 +} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "d3e057d1-df44-4ac3-ac46-fc2b04e3de78", +"name": "Get Meeting ConferenceRecords", +"type": "n8n-nodes-base.httpRequest", +"position": [ +20, +580 +], +"parameters": { +"url": "https://meet.googleapis.com/v2/conferenceRecords", +"options": {}, +"sendQuery": true, +"authentication": "predefinedCredentialType", +"queryParameters": { +"parameters": [ +{ +"name": "filter", +"value": "=space.meeting_code={{ $json.conferenceData.conferenceId }}" +} +] +}, +"nodeCredentialType": "googleOAuth2Api" +}, +"credentials": { +"googleOAuth2Api": { +"id": "kgVOfvlBIWTWXthG", +"name": "Google Meets Oauth2 API" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "831668fd-04ab-4144-bec0-c733902f2a13", +"name": "Get Meeting Transcript Location", +"type": "n8n-nodes-base.httpRequest", +"position": [ +200, +580 +], +"parameters": { +"url": "=https://meet.googleapis.com/v2/{{ $json.conferenceRecords[0].name }}/transcripts", +"options": {}, +"authentication": "predefinedCredentialType", +"nodeCredentialType": "googleOAuth2Api" +}, +"credentials": { +"googleOAuth2Api": { +"id": "kgVOfvlBIWTWXthG", +"name": "Google Meets Oauth2 API" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "0a1c3386-1456-4abd-a67c-4f2084efb1f1", +"name": "Get Transcript File", +"type": "n8n-nodes-base.googleDrive", +"position": [ +380, +580 +], +"parameters": { +"fileId": { +"__rl": true, +"mode": "url", +"value": "={{ $json.docsDestination.document }}" +}, +"options": { +"googleFileConversion": { +"conversion": { +"docsToFormat": "application/pdf" +} +} +}, +"operation": "download" +}, +"credentials": { +"googleDriveOAuth2Api": { +"id": "yOwz41gMQclOadgu", +"name": "Google Drive account" +} +}, +"typeVersion": 3 +}, +{ +"id": "40d1e969-3a04-4fb0-98c3-59865f317e07", +"name": "When clicking \"Test workflow\"", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +-480, +540 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "1d277cc0-9f51-43a2-9d17-17d535b4dd53", +"name": "PDF Loader", +"type": "n8n-nodes-base.extractFromFile", +"position": [ +660, +520 +], +"parameters": { +"options": {}, +"operation": "pdf" +}, +"typeVersion": 1 +}, +{ +"id": "08b2d0ce-0f59-45d8-b010-53910a1bc746", +"name": "Get Calendar Event", +"type": "n8n-nodes-base.googleCalendar", +"position": [ +-280, +540 +], +"parameters": { +"eventId": "abc123", +"options": {}, +"calendar": { +"__rl": true, +"mode": "list", +"value": "c_5792bdf04bc395cbcbc6f7b754268245a33779d36640cc80a357711aa2f09a0a@group.calendar.google.com", +"cachedResultName": "n8n-events" +}, +"operation": "get" +}, +"credentials": { +"googleCalendarOAuth2Api": { +"id": "kWMxmDbMDDJoYFVK", +"name": "Google Calendar account" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "35a68444-15da-4b6e-a3c8-d296971b0fc0", +"name": "Structured Output Parser", +"type": "@n8n/n8n-nodes-langchain.outputParserStructured", +"position": [ +1040, +660 +], +"parameters": { +"jsonSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"summary\": { \"type\": \"string\" },\n \"highlights\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"attendee\": { \"type\": \"string\" },\n \"message\": { \"type\": \"string\" }\n }\n }\n },\n \"next_steps\": {\n \"type\": \"array\",\n \"items:\": {\n \"type\": \"string\"\n }\n },\n \"meetings_created\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"event_title\": { \"type\": \"string\" },\n \"event_invite_url\": { \"type\" : \"string\" }\n }\n }\n }\n }\n}" +}, +"typeVersion": 1.1 +}, +{ +"id": "e73ab051-1763-4130-bf44-f1461886e5f4", +"name": "Execute Workflow Trigger", +"type": "n8n-nodes-base.executeWorkflowTrigger", +"position": [ +640, +1200 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "c940c9e1-8236-45b8-bdb2-39a326004680", +"name": "Response", +"type": "n8n-nodes-base.set", +"position": [ +1780, +1080 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "3c12dc11-0ff3-4c6a-9d67-1454d7b0d16d", +"name": "response", +"type": "string", +"value": "={{ JSON.stringify($('Create Calendar Event1').item.json) }}" +} +] +} +}, +"typeVersion": 3.3 +}, +{ +"id": "daa3e96f-bcc1-4f99-a050-c09189041ce5", +"name": "Edit Fields", +"type": "n8n-nodes-base.set", +"position": [ +800, +1200 +], +"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": "object", +"value": "={{ $json.query.parseJson() }}" +} +] +} +}, +"typeVersion": 3.3 +}, +{ +"id": "4e492c9f-6be3-4b7c-a8f7-e18dd94cd158", +"name": "Fallback Response", +"type": "n8n-nodes-base.set", +"position": [ +960, +1340 +], +"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": "7af68b6d-75ef-4332-8193-eb810179ec90", +"name": "Actions Router", +"type": "n8n-nodes-base.switch", +"position": [ +960, +1200 +], +"parameters": { +"rules": { +"values": [ +{ +"outputKey": "meetings.create", +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"operator": { +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.route }}", +"rightValue": "meetings.create" +} +] +}, +"renameOutput": true +} +] +}, +"options": { +"fallbackOutput": "extra" +} +}, +"typeVersion": 3 +}, +{ +"id": "8cc6b737-2867-4fca-93d1-8973f14a9f00", +"name": "Get Attendees", +"type": "n8n-nodes-base.set", +"position": [ +1440, +1080 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "521823f4-cee1-4f69-82e7-cea9be0dbc41", +"name": "attendees", +"type": "array", +"value": "={{ $('Actions Router').item.json.query.attendees }}" +} +] +} +}, +"typeVersion": 3.3 +}, +{ +"id": "1b3bb8f7-3775-48be-8b73-5c9f0db37ebf", +"name": "Attendees List", +"type": "n8n-nodes-base.splitOut", +"position": [ +1444, +1212 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "attendees" +}, +"typeVersion": 1 +}, +{ +"id": "c285a0fa-4b0b-4775-83bb-5acb597dd9a8", +"name": "Add Attendee to Invite", +"type": "n8n-nodes-base.googleCalendar", +"position": [ +1620, +1080 +], +"parameters": { +"eventId": "={{ $('Create Calendar Event1').item.json.id }}", +"calendar": { +"__rl": true, +"mode": "list", +"value": "c_5792bdf04bc395cbcbc6f7b754268245a33779d36640cc80a357711aa2f09a0a@group.calendar.google.com", +"cachedResultName": "n8n-events" +}, +"operation": "update", +"updateFields": { +"attendees": [ +"={{ $json.name }} <{{ $json.email }}>" +] +} +}, +"credentials": { +"googleCalendarOAuth2Api": { +"id": "kWMxmDbMDDJoYFVK", +"name": "Google Calendar account" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "006c2b05-4526-4e7d-b303-0cd72b36b9e8", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1180, +940 +], +"parameters": { +"color": 7, +"width": 756.2929032891963, +"height": 445.79624302689535, +"content": "## 4. This Tool Creates Calendar Events\nThis tool, given event details and a list of attendees, will create a new Google calendar event and add the attendees to it." +}, +"typeVersion": 1 +}, +{ +"id": "512dfd7d-ba06-48e5-b97f-3dfbbfb0023f", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-56.39068896608171, +391.01655789481134 +], +"parameters": { +"color": 7, +"width": 586.8663941671947, +"height": 405.6964113279832, +"content": "## 1. Retrieve Meeting Transcript\n[Read more about working with HTTP node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest)\n\nThere's no built-in support for Google Meets transcript API however, we can solve this problem with the HTTP node. Note you may also need to setup a separate Google OAuth API Credential to obtain the required scopes." +}, +"typeVersion": 1 +}, +{ +"id": "91c5b898-b491-4359-90b4-2b7458cc03c8", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +560, +323.25204909069373 +], +"parameters": { +"color": 7, +"width": 681.4281346810014, +"height": 588.2833041602365, +"content": "## 2. Let AI Agent Carry Out Follow-Up Actions\n[Read more about working with AI Agents](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.agent)\n\nThe big difference between Basic LLM chains and AI Agents is that AI agents are given the automony to perform actions. Provided the right tool exists, AI Agents can send emails, book flights and even order pizza! Here we're leaving it up to our agent to book any follow-up meetings after the call and invite all interested parties." +}, +"typeVersion": 1 +}, +{ +"id": "7df4412d-b82b-4623-8ff5-89f3bd9356d8", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +560, +940 +], +"parameters": { +"color": 7, +"width": 591.4907024073684, +"height": 579.2725119898125, +"content": "## 3: Using the Custom Workflow Tool\n[Read more about Workflow Triggers](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.executeworkflowtrigger)\n\nOne common implementation of tool use is to set them up as workflows which are intended triggered via other workflows. With this, we can either build a tool per workflow or for efficiency, take an API approach where multiple tools can exist behind a router (in this case our \"switch\" node).\n\nOur AI agent will therefore only passing through the parameters of the request and won't have to learn/know how to intereact directly with the tools and services." +}, +"typeVersion": 1 +}, +{ +"id": "06b0b3ae-344a-4150-9fa1-bdbcfe80b000", +"name": "Create Calendar Event1", +"type": "n8n-nodes-base.googleCalendar", +"position": [ +1240, +1080 +], +"parameters": { +"end": "={{ $json.query.end_date }} {{ $json.query.end_time }}", +"start": "={{ $json.query.start_date }} {{ $json.query.start_time }}", +"calendar": { +"__rl": true, +"mode": "list", +"value": "c_5792bdf04bc395cbcbc6f7b754268245a33779d36640cc80a357711aa2f09a0a@group.calendar.google.com", +"cachedResultName": "n8n-events" +}, +"additionalFields": { +"summary": "={{ $json.query.title }}", +"attendees": [], +"description": "={{ $json.query.description }}" +} +}, +"credentials": { +"googleCalendarOAuth2Api": { +"id": "kWMxmDbMDDJoYFVK", +"name": "Google Calendar account" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "2e2eec66-a737-48b9-b1ab-264182163dae", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-940, +320 +], +"parameters": { +"width": 359.6648027457353, +"height": 385.336571355038, +"content": "## Try It Out!\n### This workflow does the following:\n* Retrieves a meeting transcript\n* Sends transcript to an AI Agent to parse and carry out follow up actions if necessary.\n* If transcript mentions a follow up meeting is required, the AI Agent will call a tool to create the meeting.\n* Additionally if able, the AI Agent will also assign attendees it thinks should attend the meeting. \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": "3833bb1c-1145-4abd-a371-bce4c0543fb6", +"name": "Schedule Meeting", +"type": "@n8n/n8n-nodes-langchain.toolWorkflow", +"position": [ +920, +740 +], +"parameters": { +"name": "create_calendar_event", +"fields": { +"values": [ +{ +"name": "route", +"stringValue": "meetings.create" +} +] +}, +"workflowId": "={{ $workflow.id }}", +"description": "Call this tool to create an calendar event. This tool requires the following object request body.\n```\n{\n \"type\": \"object\",\n \"properties\": {\n \"title\": { \"type\": \"string\" },\n \"description\": { \"type\": \"string\" },\n \"start_date\": { \"type\": \"string\" },\n \"start_time\": { \"type\": \"string\" },\n \"end_date\": { \"type\": \"string\" },\n \"end_time\": { \"type\": \"string\" },\n \"attendees\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": { \"type\": \"string\" },\n \"email\": { \"type\": \"string\" }\n }\n }\n }\n }\n}\n```\nNote that dates are in the format yyyy-MM-dd and times are in the format HH:mm:ss." +}, +"typeVersion": 1.1 +}, +{ +"id": "ac955f91-9aa1-4ce8-9a5a-740c4d48dd18", +"name": "AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +820, +520 +], +"parameters": { +"text": "=system: your role is to help people get the most out of their meetings. You achieve this by helpfully summarising the meeting transcript to pull out useful information and key points of interest and delivery this in note form. You also help carry out any follow-up actions on behalf of the meeting attendees.\n1. Summarise the meeting and highlight any key goals of the meeting.\n2. Identify and list important points mentioned by each attendee. If non-applicable for an attendee, skip and proceed to the next attendee.\n3. Identify and list all next steps agreed by the attendees. If there are none, make a maximum of 3 suggestions based on the transcript instead. Please list the steps even if they've already been actioned.\n4. identify and perform follow-up actions based on a transcript of a meeting. These actions which are allowed are: creating follow-up calendar events if suggested by the attendees.\n\nThe meeting details were as follows:\n* The creator of the meeting was {{ $('Get Calendar Event').item.json[\"creator\"][\"displayName\"] }} <{{ $('Get Calendar Event').item.json[\"creator\"][\"email\"]}}>\n* The attendees were {{ $('Get Calendar Event').item.json[\"attendees\"].map(attendee => `${attendee.display_name} <${attendee.email}>`).join(', ') }}\n* The meeting was scheduled for {{ $('Get Calendar Event').item.json[\"start\"][\"dateTime\"] }}\n\nThe meeting transcript as follows:\n```\n{{ $json[\"text\"] }}\n```", +"agent": "openAiFunctionsAgent", +"options": {}, +"promptType": "define", +"hasOutputParser": true +}, +"typeVersion": 1.5 +}, +{ +"id": "b6d24f80-9f47-4c54-b84e-23d5de76f027", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-560, +303.2560786071914 +], +"parameters": { +"color": 7, +"width": 464.50696860436165, +"height": 446.9122178333584, +"content": "## 1. Get Calendar Event\n[Read more about working with Google Calendar](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.googlecalendar)\n\nIn this demo, we've decided to go with google meet as transcripts are stored in the user google drive. First, we'll need to get the calendar event of which the google meet was attached.\nIf the meet was not arranged through Google calendar, you may need to skip this step and just reference the transcripts in google drive directly." +}, +"typeVersion": 1 +}, +{ +"id": "b28e2c8f-7a4e-4ae8-b298-9a78747b81e5", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-320, +520 +], +"parameters": { +"width": 184.0677386144551, +"height": 299.3566512487305, +"content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n🚨**Required**\n* Set your calendar event ID here." +}, +"typeVersion": 1 +}, +{ +"id": "5ffb49d4-6bfd-420e-9c0f-ed73a955bd46", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +180, +820 +], +"parameters": { +"color": 5, +"width": 349.91944442094535, +"height": 80, +"content": "### 💡 Can't find your transcript?\nOnly meetings which own and were recorded and had transcription enabled will be available.\n" +}, +"typeVersion": 1 +}, +{ +"id": "241ccec3-d8a0-4ca6-9267-31fe6f27aed6", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1200, +1060 +], +"parameters": { +"width": 184.0677386144551, +"height": 299.3566512487305, +"content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n🚨**Required**\n* Set your calendar ID here." +}, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"PDF Loader": { +"main": [ +[ +{ +"node": "AI Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Edit Fields": { +"main": [ +[ +{ +"node": "Actions Router", +"type": "main", +"index": 0 +} +] +] +}, +"Get Attendees": { +"main": [ +[ +{ +"node": "Attendees List", +"type": "main", +"index": 0 +} +] +] +}, +"Actions Router": { +"main": [ +[ +{ +"node": "Create Calendar Event1", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Fallback Response", +"type": "main", +"index": 0 +} +] +] +}, +"Attendees List": { +"main": [ +[ +{ +"node": "Add Attendee to Invite", +"type": "main", +"index": 0 +} +] +] +}, +"Schedule Meeting": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Get Calendar Event": { +"main": [ +[ +{ +"node": "Get Meeting ConferenceRecords", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model1": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Get Transcript File": { +"main": [ +[ +{ +"node": "PDF Loader", +"type": "main", +"index": 0 +} +] +] +}, +"Add Attendee to Invite": { +"main": [ +[ +{ +"node": "Response", +"type": "main", +"index": 0 +} +] +] +}, +"Create Calendar Event1": { +"main": [ +[ +{ +"node": "Get Attendees", +"type": "main", +"index": 0 +} +] +] +}, +"Execute Workflow Trigger": { +"main": [ +[ +{ +"node": "Edit Fields", +"type": "main", +"index": 0 +} +] +] +}, +"Structured Output Parser": { +"ai_outputParser": [ +[ +{ +"node": "AI Agent", +"type": "ai_outputParser", +"index": 0 +} +] +] +}, +"Get Meeting ConferenceRecords": { +"main": [ +[ +{ +"node": "Get Meeting Transcript Location", +"type": "main", +"index": 0 +} +] +] +}, +"When clicking \"Test workflow\"": { +"main": [ +[ +{ +"node": "Get Calendar Event", +"type": "main", +"index": 0 +} +] +] +}, +"Get Meeting Transcript Location": { +"main": [ +[ +{ +"node": "Get Transcript File", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Add positive feedback messages to a table in Notion.txt b/Add positive feedback messages to a table in Notion.txt new file mode 100644 index 0000000..7dfe4b1 --- /dev/null +++ b/Add positive feedback messages to a table in Notion.txt @@ -0,0 +1,179 @@ +{ +"nodes": [ +{ +"name": "Typeform Trigger", +"type": "n8n-nodes-base.typeformTrigger", +"position": [ +0, +400 +], +"webhookId": "ad8a87ef-d293-4e48-8d36-838d69ebce0f", +"parameters": { +"formId": "fBYjtY5e" +}, +"credentials": { +"typeformApi": "" +}, +"typeVersion": 1 +}, +{ +"name": "Google Cloud Natural Language", +"type": "n8n-nodes-base.googleCloudNaturalLanguage", +"position": [ +200, +400 +], +"parameters": { +"content": "={{$json[\"Any suggestions for us? \"]}}", +"options": {} +}, +"credentials": { +"googleCloudNaturalLanguageOAuth2Api": "" +}, +"typeVersion": 1 +}, +{ +"name": "IF", +"type": "n8n-nodes-base.if", +"position": [ +400, +400 +], +"parameters": { +"conditions": { +"number": [ +{ +"value1": "={{$node[\"Google Cloud Natural Language\"].json[\"documentSentiment\"][\"score\"]}}", +"operation": "larger" +} +] +} +}, +"typeVersion": 1 +}, +{ +"name": "Notion", +"type": "n8n-nodes-base.notion", +"position": [ +600, +300 +], +"parameters": { +"resource": "databasePage", +"databaseId": "b7d1130a-3756-4bb3-aa56-0c77bf416437", +"propertiesUi": { +"propertyValues": [ +{ +"key": "Name|title", +"title": "={{$node[\"Typeform Trigger\"].json[\"Name\"]}}" +}, +{ +"key": "Feedback|rich_text", +"textContent": "={{$node[\"Typeform Trigger\"].json[\"Any suggestions for us? \"]}}" +} +] +} +}, +"credentials": { +"notionApi": "" +}, +"typeVersion": 1 +}, +{ +"name": "Slack", +"type": "n8n-nodes-base.slack", +"position": [ +800, +300 +], +"parameters": { +"channel": "general", +"blocksUi": { +"blocksValues": [] +}, +"attachments": [ +{ +"text": "={{$node[\"Typeform Trigger\"].json[\"Any suggestions for us? \"]}}", +"title": "={{$node[\"Typeform Trigger\"].json[\"Name\"]}} {{$node[\"Google Cloud Natural Language\"].json[\"documentSentiment\"][\"score\"]}}" +} +], +"otherOptions": {} +}, +"credentials": { +"slackApi": "" +}, +"typeVersion": 1 +}, +{ +"name": "Trello", +"type": "n8n-nodes-base.trello", +"position": [ +600, +500 +], +"parameters": { +"name": "=Score: {{$json[\"documentSentiment\"][\"score\"]}}", +"listId": "5fbb9e2eb1d5cc0a8a7ab8ac", +"description": "=Score: {{$json[\"documentSentiment\"][\"score\"]}}\nFeedback: {{$node[\"Typeform Trigger\"].json[\"Any suggestions for us? \"]}}\nUser: {{$node[\"Typeform Trigger\"].json[\"Name\"]}}", +"additionalFields": {} +}, +"credentials": { +"trelloApi": "" +}, +"typeVersion": 1 +} +], +"connections": { +"IF": { +"main": [ +[ +{ +"node": "Notion", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Trello", +"type": "main", +"index": 0 +} +] +] +}, +"Notion": { +"main": [ +[ +{ +"node": "Slack", +"type": "main", +"index": 0 +} +] +] +}, +"Typeform Trigger": { +"main": [ +[ +{ +"node": "Google Cloud Natural Language", +"type": "main", +"index": 0 +} +] +] +}, +"Google Cloud Natural Language": { +"main": [ +[ +{ +"node": "IF", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Advanced AI Demo (Presented at AI Developers #14 meetup).txt b/Advanced AI Demo (Presented at AI Developers #14 meetup).txt new file mode 100644 index 0000000..2ded4db --- /dev/null +++ b/Advanced AI Demo (Presented at AI Developers #14 meetup).txt @@ -0,0 +1,927 @@ +{ +"meta": { +"instanceId": "84ba6d895254e080ac2b4916d987aa66b000f88d4d919a6b9c76848f9b8a7616", +"templateId": "2358" +}, +"nodes": [ +{ +"id": "fb774d11-da48-4481-ad4e-8c93274f123e", +"name": "Send message", +"type": "n8n-nodes-base.slack", +"position": [ +2340, +580 +], +"parameters": { +"text": "=Data from webhook: {{ $json.query.email }}", +"select": "channel", +"channelId": { +"__rl": true, +"mode": "list", +"value": "C079GL6K3U6", +"cachedResultName": "general" +}, +"otherOptions": {}, +"authentication": "oAuth2" +}, +"typeVersion": 2.2 +}, +{ +"id": "5a3ad8f1-eba7-4076-80fc-0c1237aab50b", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +380, +240 +], +"parameters": { +"color": 7, +"width": 1163.3132111854613, +"height": 677.0358687053997, +"content": "![h](https://i.postimg.cc/9XLvL5dL/slide-sf-talk.png#full-width)" +}, +"typeVersion": 1 +}, +{ +"id": "01c59396-0fef-4d1c-aa1f-787669300650", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1860, +240 +], +"parameters": { +"color": 7, +"width": 437, +"height": 99, +"content": "# What is n8n?\n### Low-code Automation Platform for technical teams" +}, +"typeVersion": 1 +}, +{ +"id": "0bdd4a35-7f5c-443c-a14a-4e6f7ed18712", +"name": "Execute JavaScript", +"type": "n8n-nodes-base.code", +"position": [ +2340, +380 +], +"parameters": { +"jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\nfor (const item of $input.all()) {\n item.json.myNewField = 1;\n}\n\nreturn $input.all();" +}, +"typeVersion": 2 +}, +{ +"id": "4b1b6cc1-1a9f-4a0c-96d5-fd179c84c79d", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +4440, +240 +], +"parameters": { +"color": 6, +"width": 318, +"height": 106, +"content": "# Example #2\n### RAG with PDF as source" +}, +"typeVersion": 1 +}, +{ +"id": "7e9e7802-5695-4240-83b9-d6f02192ad2b", +"name": "Recursive Character Text Splitter", +"type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter", +"position": [ +5120, +1000 +], +"parameters": { +"options": {}, +"chunkSize": 3000, +"chunkOverlap": 200 +}, +"typeVersion": 1 +}, +{ +"id": "63783c21-af6d-4e70-8dec-c861641c53fb", +"name": "Embeddings OpenAI", +"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi", +"position": [ +4880, +820 +], +"parameters": { +"options": {} +}, +"typeVersion": 1 +}, +{ +"id": "5742ce9c-2f73-4129-85eb-876f562cf6b1", +"name": "Default Data Loader", +"type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader", +"position": [ +5100, +820 +], +"parameters": { +"loader": "pdfLoader", +"options": { +"metadata": { +"metadataValues": [ +{ +"name": "document-title", +"value": "={{ $('PDFs to download').item.json.whitepaper_title }}" +}, +{ +"name": "document-publish-year", +"value": "={{ $('PDFs to download').item.json.publish_year }}" +}, +{ +"name": "document-author", +"value": "={{ $('PDFs to download').item.json.author }}" +} +] +} +}, +"dataType": "binary" +}, +"typeVersion": 1 +}, +{ +"id": "686c63fa-4672-4107-bd58-ffbb0650b44b", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +5840, +840 +], +"parameters": { +"model": "gpt-4o", +"options": { +"temperature": 0.3 +} +}, +"typeVersion": 1 +}, +{ +"id": "73a7df02-aa2c-4f0f-aa88-38cbbbf3b1cb", +"name": "Embeddings OpenAI2", +"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi", +"position": [ +5980, +1140 +], +"parameters": { +"options": {} +}, +"typeVersion": 1 +}, +{ +"id": "42737305-fd39-4ec7-b4ba-53f70085dd5f", +"name": "Vector Store Retriever", +"type": "@n8n/n8n-nodes-langchain.retrieverVectorStore", +"position": [ +6040, +840 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "2c7a3666-e123-439d-8b74-41eb375f066c", +"name": "Download PDF", +"type": "n8n-nodes-base.httpRequest", +"position": [ +4700, +600 +], +"parameters": { +"url": "={{ $json.file_url }}", +"options": {} +}, +"typeVersion": 4.2 +}, +{ +"id": "866eaeb9-6a7c-4209-b485-8ef13ed006b4", +"name": "PDFs to download", +"type": "n8n-nodes-base.noOp", +"notes": "BTC Whitepaper + metadata", +"position": [ +4440, +600 +], +"parameters": {}, +"notesInFlow": true, +"typeVersion": 1 +}, +{ +"id": "e78f2191-096c-4575-9d48-fb891fd18698", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +4440, +440 +], +"parameters": { +"color": 4, +"width": 414.36616595939887, +"height": 91.0723900084547, +"content": "## A. Load PDF into Pinecone\nDownload the PDF, then text embeddings into Pincecone" +}, +"typeVersion": 1 +}, +{ +"id": "7c3ccf27-32b1-4ea7-b2ef-6997793de733", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +5600, +460 +], +"parameters": { +"color": 4, +"width": 284.62109466374466, +"height": 86.95121951219511, +"content": "## B. Chat with PDF\nUse GPT4o to chat with Pinecone index" +}, +"typeVersion": 1 +}, +{ +"id": "6063d009-da6e-4cbf-899f-c86b879931a7", +"name": "Read Pinecone Vector Store", +"type": "@n8n/n8n-nodes-langchain.vectorStorePinecone", +"position": [ +5980, +980 +], +"parameters": { +"options": { +"pineconeNamespace": "whitepaper" +}, +"pineconeIndex": { +"__rl": true, +"mode": "list", +"value": "whitepapers", +"cachedResultName": "whitepapers" +} +}, +"typeVersion": 1 +}, +{ +"id": "8aa52156-264d-4911-993c-ac5117a76b21", +"name": "Question and Answer Chain", +"type": "@n8n/n8n-nodes-langchain.chainRetrievalQa", +"position": [ +5840, +620 +], +"parameters": { +"text": "={{ $json.chatInput }}. \nOnly use vector store knowledge to answer the question. Don't make anything up. If you don't know the answer, tell the user that you don't know.", +"promptType": "define" +}, +"typeVersion": 1.3 +}, +{ +"id": "b394ee1d-a2ca-4db0-8caa-981f8f066787", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +7380, +240 +], +"parameters": { +"color": 6, +"width": 504.25, +"height": 106, +"content": "# Example #3\n### AI Assistant that knows how to use predefined API endpoints " +}, +"typeVersion": 1 +}, +{ +"id": "37a8b8f2-c444-4c6e-9b02-b97a5c616e84", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +3020, +220 +], +"parameters": { +"color": 6, +"width": 318, +"height": 111, +"content": "# Example #1\n### Categorize incoming emails with AI" +}, +"typeVersion": 1 +}, +{ +"id": "07123e8e-8760-4c89-acda-aaef6de68be2", +"name": "Anthropic Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic", +"position": [ +7580, +700 +], +"parameters": { +"options": { +"temperature": 0.4 +} +}, +"typeVersion": 1.2 +}, +{ +"id": "e338a175-e823-4cd4-b77d-f5acbfcbdb9d", +"name": "Get calendar availability", +"type": "@n8n/n8n-nodes-langchain.toolHttpRequest", +"position": [ +7900, +700 +], +"parameters": { +"url": "https://www.googleapis.com/calendar/v3/freeBusy", +"method": "POST", +"jsonBody": "={\n \"timeMin\": \"{timeMin}\",\n \"timeMax\": \"{timeMax}\",\n \"timeZone\": \"Europe/Berlin\",\n \"groupExpansionMax\": 20,\n \"calendarExpansionMax\": 10,\n \"items\": [\n {\n \"id\": \"max@n8n.io\"\n }\n ]\n}", +"sendBody": true, +"specifyBody": "json", +"authentication": "predefinedCredentialType", +"toolDescription": "Call this tool to get the appointment availability for a particular period on the calendar. The tool may refer to availability as \"Free\" or \"Busy\". \n\nUse {timeMin} and {timeMax} to specify the window for the availability query. For example, to get availability for 25 July, 2024 the {timeMin} would be 2024-07-25T09:00:00+02:00 and {timeMax} would be 2024-07-25T17:00:00+02:00.\n\nIf the tool returns an empty response, it means that something went wrong. It does not mean that there is no availability.", +"nodeCredentialType": "googleCalendarOAuth2Api" +}, +"typeVersion": 1 +}, +{ +"id": "ae05933c-dfa9-4272-b610-8b5fc94d76fe", +"name": "Appointment booking agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +7680, +480 +], +"parameters": { +"options": { +"systemMessage": "=You are an efficient and courteous assistant tasked with scheduling appointments with Max Tkacz.\n\nWhen users mention an appointment or meeting, they are referring to a meeting with Max.\nWhen users refer to the calendar or \"your schedule,\" they are referring to Max's calendar. \n\nYou can use various tools to access and manage Max's calendar. Your primary goal is to assist users in successfully booking an appointment with Max, ensuring no scheduling conflicts. Only book an appointment if the requested time slot is available (the tool may refer to this as \"Free\")\n\nToday's date is {{ $today.format('dd LLL yyyy') }}.\nAppointments are always 30 minutes in length. \n\n\nProvide accurate information at all times. If the tools are not functioning correctly, inform the user that you are unable to assist them at the moment.\n" +} +}, +"typeVersion": 1.6 +}, +{ +"id": "7e3b1797-150e-4c7c-93a5-306b981e0b6c", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +8300, +440 +], +"parameters": { +"color": 7, +"width": 327.46658341463433, +"height": 571.8601927804875, +"content": "![h](https://i.imghippo.com/files/d9Bgv1721858679.png#full-width)\n[Open Calendar](https://calendar.google.com/calendar/u/0/r/day/2024/7/26)" +}, +"typeVersion": 1 +}, +{ +"id": "afe8d14d-d0d0-4a11-bb4f-57358de66bc1", +"name": "Window Buffer Memory", +"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow", +"position": [ +7720, +700 +], +"parameters": { +"contextWindowLength": 10 +}, +"typeVersion": 1.2 +}, +{ +"id": "53d131ea-3235-4e4e-828b-dc22c9021e50", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +6380, +640 +], +"parameters": { +"color": 7, +"width": 615.2162978341456, +"height": 403.1877919219511, +"content": "![h](https://i.postimg.cc/kXW9XrZt/Screenshot-2024-07-24-at-15-18-27.png#full-width)\nBTC Whitepaper references" +}, +"typeVersion": 1 +}, +{ +"id": "55a0f180-bb35-4b35-b72c-b9361698e5ad", +"name": "Sticky Note9", +"type": "n8n-nodes-base.stickyNote", +"position": [ +9660, +240 +], +"parameters": { +"color": 7, +"width": 345.33741540309194, +"height": 398.9629539487597, +"content": "### Connect with me or explore this demo 👇\n![QR](https://i.postimg.cc/VNkdCLQh/frame.png#full-width)" +}, +"typeVersion": 1 +}, +{ +"id": "14b3231d-aa96-4783-be8f-cb2f70b0bc7f", +"name": "Sticky Note10", +"type": "n8n-nodes-base.stickyNote", +"position": [ +9220, +240 +], +"parameters": { +"color": 7, +"width": 411.2946586626259, +"height": 197.19036476628202, +"content": "# Thank you and happy flowgramming 🤘\n\n### Max Tkacz | Senior Developer Advocate @ n8n" +}, +"typeVersion": 1 +}, +{ +"id": "c9a2fcdc-c8ab-4b9d-9979-4fd7cca1e8a8", +"name": "Insert into Pinecone vector store", +"type": "@n8n/n8n-nodes-langchain.vectorStorePinecone", +"position": [ +4920, +600 +], +"parameters": { +"mode": "insert", +"options": { +"clearNamespace": true, +"pineconeNamespace": "whitepaper" +}, +"pineconeIndex": { +"__rl": true, +"mode": "list", +"value": "whitepapers", +"cachedResultName": "whitepapers" +} +}, +"typeVersion": 1 +}, +{ +"id": "6a890c74-67f9-4eee-bb56-7c9a68921ae1", +"name": "Book appointment", +"type": "@n8n/n8n-nodes-langchain.toolHttpRequest", +"position": [ +8060, +700 +], +"parameters": { +"url": "https://www.googleapis.com/calendar/v3/calendars/max@n8n.io/events", +"method": "POST", +"jsonBody": "={\n \"summary\": \"Appointment with {userName}\",\n \"start\": {\n \"dateTime\": \"{startTime}\",\n \"timeZone\": \"Europe/Berlin\"\n },\n \"end\": {\n \"dateTime\": \"{endTime}\",\n \"timeZone\": \"Europe/Berlin\"\n },\n \"attendees\": [\n {\"email\": \"max@n8n.io\"},\n {\"email\": \"{userEmail}\"}\n ]\n}", +"sendBody": true, +"specifyBody": "json", +"authentication": "predefinedCredentialType", +"toolDescription": "Call this tool to book an appointment in the calendar. ", +"nodeCredentialType": "googleCalendarOAuth2Api", +"placeholderDefinitions": { +"values": [ +{ +"name": "userName", +"description": "The full name of the user making the appointment. Like John Doe" +}, +{ +"name": "startTime", +"description": "The start time of the event in Europe/Berlin timezone. For example, 2024-07-24T10:00:00+02:00" +}, +{ +"name": "endTime", +"description": "The end time of the event in Europe/Berlin timezone. It should always be 30 minutes after the startTime. " +}, +{ +"name": "userEmail", +"description": "The email address of the user making the appointment" +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "7f6e62f2-2d72-4fd2-a6ef-e57028d0055b", +"name": "When chat message received", +"type": "@n8n/n8n-nodes-langchain.chatTrigger", +"position": [ +5600, +620 +], +"webhookId": "c348693e-9c43-4bf2-90a5-23786273e809", +"parameters": { +"public": true, +"options": { +"title": "Book an appointment with Max" +}, +"initialMessages": "Hi there! 👋\nI can help you schedule an appointment with Max Tkacz. On which day would you like to meet?" +}, +"typeVersion": 1.1 +}, +{ +"id": "52c65975-479d-4c76-bcd3-23f5c9bb6acf", +"name": "Sticky Note11", +"type": "n8n-nodes-base.stickyNote", +"position": [ +9220, +460 +], +"parameters": { +"color": 7, +"width": 411.2946586626259, +"height": 80, +"content": "### Explore 100+ AI Workflow templates on n8n.io\n[Open Templates Library](https://n8n.io/workflows)" +}, +"typeVersion": 1 +}, +{ +"id": "ba0635c0-2ca4-4b27-b960-3a0e0f93a56a", +"name": "Sticky Note12", +"type": "n8n-nodes-base.stickyNote", +"position": [ +9220, +560 +], +"parameters": { +"color": 7, +"width": 411.2946586626259, +"height": 80, +"content": "### Ask a question in our community (13k+ members)\n[Explore n8n community](https://community.n8n.io/)" +}, +"typeVersion": 1 +}, +{ +"id": "29227c52-a9cc-4bd1-b1a3-78fb805b659c", +"name": "OpenAI Chat Model1", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +3260, +660 +], +"parameters": { +"model": "gpt-4o", +"options": { +"temperature": 0.5 +} +}, +"typeVersion": 1 +}, +{ +"id": "494a2868-9ff5-402c-b83b-6dd2c3ddbcc9", +"name": "Add automation label", +"type": "n8n-nodes-base.gmail", +"position": [ +3760, +300 +], +"parameters": { +"labelIds": [ +"Label_4763053241338138112" +], +"messageId": "={{ $json.id }}", +"operation": "addLabels" +}, +"typeVersion": 2.1 +}, +{ +"id": "0f9d834d-ec47-43f5-945b-8c464d371122", +"name": "On new email to nathan's inbox", +"type": "n8n-nodes-base.gmailTrigger", +"disabled": true, +"position": [ +3040, +460 +], +"parameters": { +"simple": false, +"filters": {}, +"options": {}, +"pollTimes": { +"item": [ +{ +"mode": "everyMinute" +} +] +} +}, +"typeVersion": 1.1 +}, +{ +"id": "142e2a49-40bd-4bf5-9ba3-f14ecd68618e", +"name": "Add music label", +"type": "n8n-nodes-base.gmail", +"position": [ +3760, +500 +], +"parameters": { +"labelIds": [ +"Label_6822395192337188416" +], +"messageId": "={{ $json.id }}", +"operation": "addLabels" +}, +"typeVersion": 2.1 +}, +{ +"id": "2eb46753-a0e8-43ec-a460-466b1dd265c9", +"name": "Assign label with AI", +"type": "@n8n/n8n-nodes-langchain.textClassifier", +"position": [ +3280, +460 +], +"parameters": { +"options": {}, +"inputText": "={{ $json.text }}", +"categories": { +"categories": [ +{ +"category": "automation", +"description": "email on the topic of automation or workflows and automated processes, includes newsletters on this topic" +}, +{ +"category": "music", +"description": "email on the topic of music, for example from an artist " +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "576d8206-1b1e-4671-ba45-86e9d844a73b", +"name": "Webhook", +"type": "n8n-nodes-base.webhook", +"position": [ +1860, +460 +], +"webhookId": "74facfd7-0f51-4605-9724-2c300594fcf9", +"parameters": { +"path": "74facfd7-0f51-4605-9724-2c300594fcf9", +"options": {} +}, +"typeVersion": 2 +}, +{ +"id": "1e612376-1a3b-4c48-9cd3-97867ba4cad5", +"name": "Whether email contains n8n", +"type": "n8n-nodes-base.if", +"position": [ +2060, +460 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "a0b16c44-03ea-4e96-9671-7b168697186d", +"operator": { +"type": "string", +"operation": "contains" +}, +"leftValue": "={{ $json.query.email }}", +"rightValue": "@n8n" +} +] +} +}, +"typeVersion": 2 +} +], +"pinData": {}, +"connections": { +"Webhook": { +"main": [ +[ +{ +"node": "Whether email contains n8n", +"type": "main", +"index": 0 +} +] +] +}, +"Download PDF": { +"main": [ +[ +{ +"node": "Insert into Pinecone vector store", +"type": "main", +"index": 0 +} +] +] +}, +"Book appointment": { +"ai_tool": [ +[ +{ +"node": "Appointment booking agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"PDFs to download": { +"main": [ +[ +{ +"node": "Download PDF", +"type": "main", +"index": 0 +} +] +] +}, +"Embeddings OpenAI": { +"ai_embedding": [ +[ +{ +"node": "Insert into Pinecone vector store", +"type": "ai_embedding", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Question and Answer Chain", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Embeddings OpenAI2": { +"ai_embedding": [ +[ +{ +"node": "Read Pinecone Vector Store", +"type": "ai_embedding", +"index": 0 +} +] +] +}, +"OpenAI Chat Model1": { +"ai_languageModel": [ +[ +{ +"node": "Assign label with AI", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Default Data Loader": { +"ai_document": [ +[ +{ +"node": "Insert into Pinecone vector store", +"type": "ai_document", +"index": 0 +} +] +] +}, +"Anthropic Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Appointment booking agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Assign label with AI": { +"main": [ +[ +{ +"node": "Add automation label", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Add music label", +"type": "main", +"index": 0 +} +] +] +}, +"Window Buffer Memory": { +"ai_memory": [ +[ +{ +"node": "Appointment booking agent", +"type": "ai_memory", +"index": 0 +} +] +] +}, +"Vector Store Retriever": { +"ai_retriever": [ +[ +{ +"node": "Question and Answer Chain", +"type": "ai_retriever", +"index": 0 +} +] +] +}, +"Get calendar availability": { +"ai_tool": [ +[ +{ +"node": "Appointment booking agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Read Pinecone Vector Store": { +"ai_vectorStore": [ +[ +{ +"node": "Vector Store Retriever", +"type": "ai_vectorStore", +"index": 0 +} +] +] +}, +"When chat message received": { +"main": [ +[ +{ +"node": "Question and Answer Chain", +"type": "main", +"index": 0 +} +] +] +}, +"Whether email contains n8n": { +"main": [ +[ +{ +"node": "Execute JavaScript", +"type": "main", +"index": 0 +}, +{ +"node": "Send message", +"type": "main", +"index": 0 +} +] +] +}, +"On new email to nathan's inbox": { +"main": [ +[ +{ +"node": "Assign label with AI", +"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/Agentic Telegram AI bot with with LangChain nodes and new tools.txt b/Agentic Telegram AI bot with with LangChain nodes and new tools.txt new file mode 100644 index 0000000..b67453c --- /dev/null +++ b/Agentic Telegram AI bot with with LangChain nodes and new tools.txt @@ -0,0 +1,260 @@ +{ +"id": "U8EOTtZvmZPMYc6m", +"meta": { +"instanceId": "fb924c73af8f703905bc09c9ee8076f48c17b596ed05b18c0ff86915ef8a7c4a", +"templateCredsSetupCompleted": true +}, +"name": "Agentic Telegram AI bot with LangChain nodes and new tools", +"tags": [], +"nodes": [ +{ +"id": "13b3488e-af72-4d89-bef4-e9b895e3bf76", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +1640, +580 +], +"parameters": { +"model": "gpt-4o", +"options": { +"temperature": 0.7, +"frequencyPenalty": 0.2 +} +}, +"credentials": { +"openAiApi": { +"id": "rveqdSfp7pCRON1T", +"name": "Ted's Tech Talks OpenAi" +} +}, +"typeVersion": 1 +}, +{ +"id": "864937a1-43f6-4055-bdea-61ab07db9903", +"name": "Window Buffer Memory", +"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow", +"position": [ +1760, +580 +], +"parameters": { +"sessionKey": "=chat_with_{{ $('Listen for incoming events').first().json.message.chat.id }}", +"contextWindowLength": 10 +}, +"typeVersion": 1 +}, +{ +"id": "4ef838d4-feaa-4bd3-b2c7-ccd938be4373", +"name": "Listen for incoming events", +"type": "n8n-nodes-base.telegramTrigger", +"position": [ +1580, +360 +], +"webhookId": "322dce18-f93e-4f86-b9b1-3305519b7834", +"parameters": { +"updates": [ +"*" +], +"additionalFields": {} +}, +"credentials": { +"telegramApi": { +"id": "9dexJXnlVPA6wt8K", +"name": "Chat & Sound" +} +}, +"typeVersion": 1 +}, +{ +"id": "fed51c41-2846-4a1a-a5f5-ce121ee7fe88", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1460, +180 +], +"parameters": { +"color": 7, +"width": 926.3188190787038, +"height": 553.452795998601, +"content": "## Generate an image with Dall-E-3 and send it via Telegram" +}, +"typeVersion": 1 +}, +{ +"id": "1c7a204b-3ed7-47bd-a434-202b05272d18", +"name": "Send final reply", +"type": "n8n-nodes-base.telegram", +"onError": "continueErrorOutput", +"position": [ +2140, +360 +], +"parameters": { +"text": "={{ $json.output }}", +"chatId": "={{ $('Listen for incoming events').first().json.message.from.id }}", +"additionalFields": { +"appendAttribution": false +} +}, +"credentials": { +"telegramApi": { +"id": "9dexJXnlVPA6wt8K", +"name": "Chat & Sound" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "bebbe9d4-47ba-4c13-9e1e-d36bfe6e472e", +"name": "Send back an image", +"type": "n8n-nodes-base.telegramTool", +"position": [ +2020, +580 +], +"parameters": { +"file": "={{ $fromAI(\"url\", \"a valid url of an image\", \"string\", \" \") }}", +"chatId": "={{ $('Listen for incoming events').first().json.message.from.id }}", +"operation": "sendDocument", +"additionalFields": {} +}, +"credentials": { +"telegramApi": { +"id": "9dexJXnlVPA6wt8K", +"name": "Chat & Sound" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "38f2410d-bd55-4ddf-8aaa-4e28919de78f", +"name": "Generate image in Dalle", +"type": "@n8n/n8n-nodes-langchain.toolHttpRequest", +"position": [ +1880, +580 +], +"parameters": { +"url": "https://api.openai.com/v1/images/generations", +"method": "POST", +"sendBody": true, +"authentication": "predefinedCredentialType", +"parametersBody": { +"values": [ +{ +"name": "model", +"value": "dall-e-3", +"valueProvider": "fieldValue" +}, +{ +"name": "prompt" +} +] +}, +"toolDescription": "Call this tool to request a Dall-E-3 model, when the user asks to draw something. If you gеt a response from this tool, forward it to the Telegram tool.", +"nodeCredentialType": "openAiApi" +}, +"credentials": { +"openAiApi": { +"id": "rveqdSfp7pCRON1T", +"name": "Ted's Tech Talks OpenAi" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "34265eab-9f37-475a-a2ae-a6c37c69c595", +"name": "AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +1780, +360 +], +"parameters": { +"text": "={{ $json.message.text }}", +"options": { +"systemMessage": "=You are a helpful assistant. You are communicating with a user named {{ $json.message.from.first_name }}. Address the user by name every time. If the user asks for an image, always send the link to the image in the final reply." +}, +"promptType": "define" +}, +"typeVersion": 1.7 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "b36989c5-295a-4df6-84e9-776815509bc9", +"connections": { +"AI Agent": { +"main": [ +[ +{ +"node": "Send final reply", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Send back an image": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Window Buffer Memory": { +"ai_memory": [ +[ +{ +"node": "AI Agent", +"type": "ai_memory", +"index": 0 +} +] +] +}, +"Generate image in Dalle": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Listen for incoming events": { +"main": [ +[ +{ +"node": "AI Agent", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Analyse papers from Hugging Face with AI and store them in Notion.txt b/Analyse papers from Hugging Face with AI and store them in Notion.txt new file mode 100644 index 0000000..140b6b5 --- /dev/null +++ b/Analyse papers from Hugging Face with AI and store them in Notion.txt @@ -0,0 +1,470 @@ +{ +"id": "FU3MrLkaTHmfdG4n", +"meta": { +"instanceId": "3294023dd650d95df294922b9d55d174ef26f4a2e6cce97c8a4ab5f98f5b8c7b", +"templateCredsSetupCompleted": true +}, +"name": "Hugging Face to Notion", +"tags": [], +"nodes": [ +{ +"id": "32d5bfee-97f1-4e92-b62e-d09bdd9c3821", +"name": "Schedule Trigger", +"type": "n8n-nodes-base.scheduleTrigger", +"position": [ +-2640, +-300 +], +"parameters": { +"rule": { +"interval": [ +{ +"field": "weeks", +"triggerAtDay": [ +1, +2, +3, +4, +5 +], +"triggerAtHour": 8 +} +] +} +}, +"typeVersion": 1.2 +}, +{ +"id": "b1f4078e-ac77-47ec-995c-f52fd98fafef", +"name": "If", +"type": "n8n-nodes-base.if", +"position": [ +-1360, +-280 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "7094d6db-1fa7-4b59-91cf-6bbd5b5f067e", +"operator": { +"type": "object", +"operation": "empty", +"singleValue": true +}, +"leftValue": "={{ $json }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "afac08e1-b629-4467-86ef-907e4a5e8841", +"name": "Loop Over Items", +"type": "n8n-nodes-base.splitInBatches", +"position": [ +-1760, +-300 +], +"parameters": { +"options": { +"reset": false +} +}, +"typeVersion": 3 +}, +{ +"id": "807ba450-9c89-4f88-aa84-91f43e3adfc6", +"name": "Split Out", +"type": "n8n-nodes-base.splitOut", +"position": [ +-1960, +-300 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "url, url" +}, +"typeVersion": 1 +}, +{ +"id": "08dd3f15-2030-48f2-ab0f-f85f797268e1", +"name": "Request Hugging Face Paper", +"type": "n8n-nodes-base.httpRequest", +"position": [ +-2440, +-300 +], +"parameters": { +"url": "https://huggingface.co/papers", +"options": {}, +"sendQuery": true, +"queryParameters": { +"parameters": [ +{ +"name": "date", +"value": "={{ $now.minus(1,'days').format('yyyy-MM-dd') }}" +} +] +} +}, +"typeVersion": 4.2 +}, +{ +"id": "f37ba769-d881-4aad-927d-ca1f4a68b9a1", +"name": "Extract Hugging Face Paper", +"type": "n8n-nodes-base.html", +"position": [ +-2200, +-300 +], +"parameters": { +"options": {}, +"operation": "extractHtmlContent", +"extractionValues": { +"values": [ +{ +"key": "url", +"attribute": "href", +"cssSelector": ".line-clamp-3", +"returnArray": true, +"returnValue": "attribute" +} +] +} +}, +"typeVersion": 1.2 +}, +{ +"id": "94ba99bf-a33b-4311-a4e6-86490e1bb9ad", +"name": "Check Paper URL Existed", +"type": "n8n-nodes-base.notion", +"position": [ +-1540, +-280 +], +"parameters": { +"filters": { +"conditions": [ +{ +"key": "URL|url", +"urlValue": "={{ 'https://huggingface.co'+$json.url }}", +"condition": "equals" +} +] +}, +"options": {}, +"resource": "databasePage", +"operation": "getAll", +"databaseId": { +"__rl": true, +"mode": "list", +"value": "17b67aba-1fcc-80ae-baa1-d88ffda7ae83", +"cachedResultUrl": "https://www.notion.so/17b67aba1fcc80aebaa1d88ffda7ae83", +"cachedResultName": "huggingface-abstract" +}, +"filterType": "manual" +}, +"credentials": { +"notionApi": { +"id": "I5KdUzwhWnphQ862", +"name": "notion" +} +}, +"typeVersion": 2.2, +"alwaysOutputData": true +}, +{ +"id": "ece8dee2-e444-4557-aad9-5bdcb5ecd756", +"name": "Request Hugging Face Paper Detail", +"type": "n8n-nodes-base.httpRequest", +"position": [ +-1080, +-300 +], +"parameters": { +"url": "={{ 'https://huggingface.co'+$('Split Out').item.json.url }}", +"options": {} +}, +"typeVersion": 4.2 +}, +{ +"id": "53b266fe-e7c4-4820-92eb-78a6ba7a6430", +"name": "OpenAI Analysis Abstract", +"type": "@n8n/n8n-nodes-langchain.openAi", +"position": [ +-640, +-300 +], +"parameters": { +"modelId": { +"__rl": true, +"mode": "list", +"value": "gpt-4o-2024-11-20", +"cachedResultName": "GPT-4O-2024-11-20" +}, +"options": {}, +"messages": { +"values": [ +{ +"role": "system", +"content": "Extract the following key details from the paper abstract:\n\nCore Introduction: Summarize the main contributions and objectives of the paper, highlighting its innovations and significance.\nKeyword Extraction: List 2-5 keywords that best represent the research direction and techniques of the paper.\nKey Data and Results: Extract important performance metrics, comparison results, and the paper's advantages over other studies.\nTechnical Details: Provide a brief overview of the methods, optimization techniques, and datasets mentioned in the paper.\nClassification: Assign an appropriate academic classification based on the content of the paper.\n\n\nOutput as json:\n{\n \"Core_Introduction\": \"PaSa is an advanced Paper Search agent powered by large language models that can autonomously perform a series of decisions (including invoking search tools, reading papers, and selecting relevant references) to provide comprehensive and accurate results for complex academic queries.\",\n \"Keywords\": [\n \"Paper Search Agent\",\n \"Large Language Models\",\n \"Reinforcement Learning\",\n \"Academic Queries\",\n \"Performance Benchmarking\"\n ],\n \"Data_and_Results\": \"PaSa outperforms existing baselines (such as Google, GPT-4, chatGPT) in tests using AutoScholarQuery (35k academic queries) and RealScholarQuery (real-world academic queries). For example, PaSa-7B exceeds Google with GPT-4o by 37.78% in recall@20 and 39.90% in recall@50.\",\n \"Technical_Details\": \"PaSa is optimized using reinforcement learning with the AutoScholarQuery synthetic dataset, demonstrating superior performance in multiple benchmarks.\",\n \"Classification\": [\n \"Artificial Intelligence (AI)\",\n \"Academic Search and Information Retrieval\",\n \"Natural Language Processing (NLP)\",\n \"Reinforcement Learning\"\n ]\n}\n```" +}, +{ +"content": "={{ $json.abstract }}" +} +] +}, +"jsonOutput": true +}, +"credentials": { +"openAiApi": { +"id": "LmLcxHwbzZNWxqY6", +"name": "Unnamed credential" +} +}, +"typeVersion": 1.8 +}, +{ +"id": "f491cd7f-598e-46fd-b80c-04cfa9766dfd", +"name": "Store Abstract Notion", +"type": "n8n-nodes-base.notion", +"position": [ +-300, +-300 +], +"parameters": { +"options": {}, +"resource": "databasePage", +"databaseId": { +"__rl": true, +"mode": "list", +"value": "17b67aba-1fcc-80ae-baa1-d88ffda7ae83", +"cachedResultUrl": "https://www.notion.so/17b67aba1fcc80aebaa1d88ffda7ae83", +"cachedResultName": "huggingface-abstract" +}, +"propertiesUi": { +"propertyValues": [ +{ +"key": "URL|url", +"urlValue": "={{ 'https://huggingface.co'+$('Split Out').item.json.url }}" +}, +{ +"key": "title|title", +"title": "={{ $('Extract Hugging Face Paper Abstract').item.json.title }}" +}, +{ +"key": "abstract|rich_text", +"textContent": "={{ $('Extract Hugging Face Paper Abstract').item.json.abstract.substring(0,2000) }}" +}, +{ +"key": "scrap-date|date", +"date": "={{ $today.format('yyyy-MM-dd') }}", +"includeTime": false +}, +{ +"key": "Classification|rich_text", +"textContent": "={{ $json.message.content.Classification.join(',') }}" +}, +{ +"key": "Technical_Details|rich_text", +"textContent": "={{ $json.message.content.Technical_Details }}" +}, +{ +"key": "Data_and_Results|rich_text", +"textContent": "={{ $json.message.content.Data_and_Results }}" +}, +{ +"key": "keywords|rich_text", +"textContent": "={{ $json.message.content.Keywords.join(',') }}" +}, +{ +"key": "Core Introduction|rich_text", +"textContent": "={{ $json.message.content.Core_Introduction }}" +} +] +} +}, +"credentials": { +"notionApi": { +"id": "I5KdUzwhWnphQ862", +"name": "notion" +} +}, +"typeVersion": 2.2 +}, +{ +"id": "d5816a1c-d1fa-4be2-8088-57fbf68e6b43", +"name": "Extract Hugging Face Paper Abstract", +"type": "n8n-nodes-base.html", +"position": [ +-840, +-300 +], +"parameters": { +"options": {}, +"operation": "extractHtmlContent", +"extractionValues": { +"values": [ +{ +"key": "abstract", +"cssSelector": ".text-gray-700" +}, +{ +"key": "title", +"cssSelector": ".text-2xl" +} +] +} +}, +"typeVersion": 1.2 +} +], +"active": true, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "4b0ec2a3-253d-46d5-a4d4-1d9ff21ba4a3", +"connections": { +"If": { +"main": [ +[ +{ +"node": "Request Hugging Face Paper Detail", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Loop Over Items", +"type": "main", +"index": 0 +} +] +] +}, +"Split Out": { +"main": [ +[ +{ +"node": "Loop Over Items", +"type": "main", +"index": 0 +} +] +] +}, +"Loop Over Items": { +"main": [ +[], +[ +{ +"node": "Check Paper URL Existed", +"type": "main", +"index": 0 +} +] +] +}, +"Schedule Trigger": { +"main": [ +[ +{ +"node": "Request Hugging Face Paper", +"type": "main", +"index": 0 +} +] +] +}, +"Store Abstract Notion": { +"main": [ +[ +{ +"node": "Loop Over Items", +"type": "main", +"index": 0 +} +] +] +}, +"Check Paper URL Existed": { +"main": [ +[ +{ +"node": "If", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Analysis Abstract": { +"main": [ +[ +{ +"node": "Store Abstract Notion", +"type": "main", +"index": 0 +} +] +] +}, +"Extract Hugging Face Paper": { +"main": [ +[ +{ +"node": "Split Out", +"type": "main", +"index": 0 +} +] +] +}, +"Request Hugging Face Paper": { +"main": [ +[ +{ +"node": "Extract Hugging Face Paper", +"type": "main", +"index": 0 +} +] +] +}, +"Request Hugging Face Paper Detail": { +"main": [ +[ +{ +"node": "Extract Hugging Face Paper Abstract", +"type": "main", +"index": 0 +} +] +] +}, +"Extract Hugging Face Paper Abstract": { +"main": [ +[ +{ +"node": "OpenAI Analysis Abstract", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Analyze & Sort Suspicious Email Contents with ChatGPT.txt b/Analyze & Sort Suspicious Email Contents with ChatGPT.txt new file mode 100644 index 0000000..b36a892 --- /dev/null +++ b/Analyze & Sort Suspicious Email Contents with ChatGPT.txt @@ -0,0 +1,828 @@ +{ +"meta": { +"instanceId": "03e9d14e9196363fe7191ce21dc0bb17387a6e755dcc9acc4f5904752919dca8" +}, +"nodes": [ +{ +"id": "94dd7f48-0013-4fb5-89c4-826ecd7f2d66", +"name": "Gmail Trigger", +"type": "n8n-nodes-base.gmailTrigger", +"position": [ +1460, +120 +], +"parameters": { +"simple": false, +"filters": {}, +"options": {}, +"pollTimes": { +"item": [ +{ +"mode": "everyMinute" +} +] +} +}, +"credentials": { +"gmailOAuth2": { +"id": "kkhNhqKpZt6IUZd0", +"name": "Gmail" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "ca2023fa-ceca-4923-80e4-a3843803536c", +"name": "Microsoft Outlook Trigger", +"type": "n8n-nodes-base.microsoftOutlookTrigger", +"disabled": true, +"position": [ +1480, +680 +], +"parameters": { +"fields": [ +"body", +"toRecipients", +"subject", +"bodyPreview" +], +"output": "fields", +"filters": {}, +"options": {}, +"pollTimes": { +"item": [ +{ +"mode": "everyMinute" +} +] +} +}, +"credentials": { +"microsoftOutlookOAuth2Api": { +"id": "vTCK0oVQ0WjFrI5H", +"name": " Outlook Credential" +} +}, +"typeVersion": 1 +}, +{ +"id": "1f011214-91a0-4cfa-9d9e-29864937c0a3", +"name": "Screenshot HTML", +"type": "n8n-nodes-base.httpRequest", +"position": [ +2620, +420 +], +"parameters": { +"url": "https://hcti.io/v1/image", +"method": "POST", +"options": {}, +"sendBody": true, +"sendQuery": true, +"authentication": "genericCredentialType", +"bodyParameters": { +"parameters": [ +{ +"name": "html", +"value": "={{ $('Set Email Variables').item.json.htmlBody }}" +} +] +}, +"genericAuthType": "httpBasicAuth", +"queryParameters": { +"parameters": [ +{} +] +} +}, +"credentials": { +"httpBasicAuth": { +"id": "8tm8mUWmPvtmPFPk", +"name": "hcti.io" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "64f4789f-9de8-414f-af62-ddc339f0d0ac", +"name": "Retrieve Screenshot", +"type": "n8n-nodes-base.httpRequest", +"position": [ +2800, +420 +], +"parameters": { +"url": "={{ $json.url }}", +"options": {}, +"authentication": "genericCredentialType", +"genericAuthType": "httpBasicAuth" +}, +"credentials": { +"httpBasicAuth": { +"id": "8tm8mUWmPvtmPFPk", +"name": "hcti.io" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "db707bd9-6abc-4ab7-8ffa-ad25c5e8adc4", +"name": "Set Outlook Variables", +"type": "n8n-nodes-base.set", +"position": [ +2040, +680 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "38bd3db2-1a8d-4c40-a2dd-336e0cc84224", +"name": "htmlBody", +"type": "string", +"value": "={{ $('Microsoft Outlook Trigger').item.json.body.content }}" +}, +{ +"id": "13bdd95b-ef02-486e-b38b-d14bd05a4a8a", +"name": "headers", +"type": "string", +"value": "={{ $json}}" +}, +{ +"id": "20566ad4-7eb7-42b1-8a0d-f8b759610f10", +"name": "subject", +"type": "string", +"value": "={{ $('Microsoft Outlook Trigger').item.json.subject }}" +}, +{ +"id": "7171998f-a5a2-4e23-946a-9c1ad75710e7", +"name": "recipient", +"type": "string", +"value": "={{ $('Microsoft Outlook Trigger').item.json.toRecipients[0].emailAddress.address }}" +}, +{ +"id": "cc262634-2470-4524-8319-abe2518a6335", +"name": "textBody", +"type": "string", +"value": "={{ $('Retrieve Headers of Email').item.json.body.content }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "7a3622c0-6949-4ea3-ae13-46a1ee26de7b", +"name": "Set Gmail Variables", +"type": "n8n-nodes-base.set", +"position": [ +2020, +120 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "38bd3db2-1a8d-4c40-a2dd-336e0cc84224", +"name": "htmlBody", +"type": "string", +"value": "={{ $json.html }}" +}, +{ +"id": "18fbcf78-6d3c-4036-b3a2-fb5adf22176a", +"name": "headers", +"type": "string", +"value": "={{ $json.headers }}" +}, +{ +"id": "1d690098-be2a-4604-baf8-62f314930929", +"name": "subject", +"type": "string", +"value": "={{ $json.subject }}" +}, +{ +"id": "8009f00a-547f-4eb1-b52d-2e7305248885", +"name": "recipient", +"type": "string", +"value": "={{ $json.to.text }}" +}, +{ +"id": "1932e97d-b03b-4964-b8bc-8262aaaa1f7a", +"name": "textBody", +"type": "string", +"value": "={{ $json.text }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "4b4c6b34-f74c-4402-91a1-4d002e02a3bd", +"name": "Retrieve Headers of Email", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1700, +680 +], +"parameters": { +"url": "=https://graph.microsoft.com/v1.0/me/messages/{{ $json.id }}?$select=internetMessageHeaders,body", +"options": {}, +"sendHeaders": true, +"authentication": "predefinedCredentialType", +"headerParameters": { +"parameters": [ +{ +"name": "Accept", +"value": "application/json" +}, +{ +"name": "Prefer", +"value": "outlook.body-content-type=\"text\"" +} +] +}, +"nodeCredentialType": "microsoftOutlookOAuth2Api" +}, +"credentials": { +"microsoftOutlookOAuth2Api": { +"id": "vTCK0oVQ0WjFrI5H", +"name": " Outlook Credential" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "0c9883b5-3eb7-45db-9803-d1b30166a3b5", +"name": "Format Headers", +"type": "n8n-nodes-base.code", +"position": [ +1880, +680 +], +"parameters": { +"jsCode": "const input = $('Retrieve Headers of Email').item.json.internetMessageHeaders;\n\nconst result = input.reduce((acc, { name, value }) => {\n if (!acc[name]) acc[name] = [];\n acc[name].push(value);\n return acc;\n}, {});\n\nreturn result;" +}, +"typeVersion": 2 +}, +{ +"id": "c21a976c-00e5-4823-bd94-4c95a7d60438", +"name": "Analyze Email with ChatGPT", +"type": "@n8n/n8n-nodes-langchain.openAi", +"position": [ +3000, +420 +], +"parameters": { +"modelId": { +"__rl": true, +"mode": "list", +"value": "gpt-4o", +"cachedResultName": "GPT-4O" +}, +"options": {}, +"messages": { +"values": [ +{ +"content": "=Describe the following email using the HTML body and headers. Determine if the email could be a phishing email. \n\nHere is the HTML body:\n{{ $('Set Email Variables').item.json.htmlBody }}\n\nThe message headers are as follows:\n{{ $('Set Email Variables').item.json.headers }}\n\n" +}, +{ +"role": "system", +"content": "Please make sure to output all responses using the following structured JSON output:\n{\n \"malicious\": false,\n \"summary\": \"The email appears to be a legitimate communication from a known sender. It contains no suspicious links, attachments, or language that indicates phishing or malicious intent.\"\n}\n\nFormat the response for Jira who uses a wiki-style renderer. Do not include ``` around your response. Make the summary as verbose as possible including a full breakdown of why the email is benign or malicious." +} +] +}, +"jsonOutput": true +}, +"credentials": { +"openAiApi": { +"id": "76", +"name": "OpenAi account" +} +}, +"typeVersion": 1.6 +}, +{ +"id": "a91f4095-9245-4276-b21f-f415de22df62", +"name": "Create Potentially Malicious Ticket", +"type": "n8n-nodes-base.jira", +"position": [ +3640, +400 +], +"parameters": { +"project": { +"__rl": true, +"mode": "list", +"value": "10001", +"cachedResultName": "Support" +}, +"summary": "=Potentially Malicious - Phishing Email Reported: \"{{ $('Set Email Variables').item.json.subject }}\"", +"issueType": { +"__rl": true, +"mode": "list", +"value": "10008", +"cachedResultName": "Task" +}, +"additionalFields": { +"description": "=A phishing email was reported by {{ $('Set Email Variables').item.json.recipient }} with the subject line \"{{ $('Set Email Variables').item.json.subject }}\"\n\\\\\nh2. Here is ChatGPT's analysis of the email:\n{{ $json.message.content.summary }}" +} +}, +"credentials": { +"jiraSoftwareCloudApi": { +"id": "BZmmGUrNIsgM9fDj", +"name": "New Jira Cloud" +} +}, +"typeVersion": 1 +}, +{ +"id": "a5a66a0e-9d8a-45a9-b1ae-aec78ddfec27", +"name": "Create Potentially Benign Ticket", +"type": "n8n-nodes-base.jira", +"position": [ +3640, +580 +], +"parameters": { +"project": { +"__rl": true, +"mode": "list", +"value": "10001", +"cachedResultName": "Support" +}, +"summary": "=Potentially Benign - Phishing Email Reported: \"{{ $('Set Email Variables').item.json.subject }}\"", +"issueType": { +"__rl": true, +"mode": "list", +"value": "10008", +"cachedResultName": "Task" +}, +"additionalFields": { +"description": "=A phishing email was reported by {{ $('Set Email Variables').item.json.recipient }} with the subject line \"{{ $('Set Email Variables').item.json.subject }}\"\n\\\\\nh2. Here is ChatGPT's analysis of the email:\n{{ $json.message.content.summary }}" +} +}, +"credentials": { +"jiraSoftwareCloudApi": { +"id": "BZmmGUrNIsgM9fDj", +"name": "New Jira Cloud" +} +}, +"typeVersion": 1 +}, +{ +"id": "5af0d60b-d021-4dd9-98f7-b2842800764a", +"name": "Rename Screenshot", +"type": "n8n-nodes-base.code", +"position": [ +4020, +480 +], +"parameters": { +"mode": "runOnceForEachItem", +"jsCode": "$('Retrieve Screenshot').item.binary.data.fileName = 'emailScreenshot.png'\n\nreturn $('Retrieve Screenshot').item;" +}, +"typeVersion": 2 +}, +{ +"id": "441c4cbb-bd93-4213-bd34-e18f2a49389f", +"name": "Set Jira ID", +"type": "n8n-nodes-base.set", +"position": [ +3860, +480 +], +"parameters": { +"options": {}, +"includeOtherFields": true +}, +"typeVersion": 3.4 +}, +{ +"id": "4c71188c-011d-4f8e-a36c-87900bfab59a", +"name": "Upload Screenshot of Email to Jira", +"type": "n8n-nodes-base.jira", +"position": [ +4220, +480 +], +"parameters": { +"issueKey": "={{ $('Set Jira ID').item.json.key }}", +"resource": "issueAttachment" +}, +"credentials": { +"jiraSoftwareCloudApi": { +"id": "BZmmGUrNIsgM9fDj", +"name": "New Jira Cloud" +} +}, +"typeVersion": 1 +}, +{ +"id": "3c031c34-8306-44e1-8e0e-a584c5323112", +"name": "Upload Email Body to Jira", +"type": "n8n-nodes-base.jira", +"position": [ +4620, +480 +], +"parameters": { +"issueKey": "={{ $('Set Jira ID').item.json.key }}", +"resource": "issueAttachment" +}, +"credentials": { +"jiraSoftwareCloudApi": { +"id": "BZmmGUrNIsgM9fDj", +"name": "New Jira Cloud" +} +}, +"typeVersion": 1 +}, +{ +"id": "d033dcbd-7ccb-451f-ab81-cc6d32d2e01f", +"name": "Convert Email Body to File", +"type": "n8n-nodes-base.convertToFile", +"position": [ +2420, +420 +], +"parameters": { +"options": { +"fileName": "emailBody.txt" +}, +"operation": "toText", +"sourceProperty": "textBody" +}, +"typeVersion": 1.1 +}, +{ +"id": "bda5e2fe-d8c0-456b-975a-35e82ff02816", +"name": "Set Email Variables", +"type": "n8n-nodes-base.set", +"position": [ +2240, +420 +], +"parameters": { +"options": {}, +"includeOtherFields": true +}, +"typeVersion": 3.4 +}, +{ +"id": "54ecd8ab-ac4a-4b6b-bd1b-bf8c70082a33", +"name": "Rename Email Body Screenshot", +"type": "n8n-nodes-base.code", +"position": [ +4420, +480 +], +"parameters": { +"mode": "runOnceForEachItem", +"jsCode": "$('Convert Email Body to File').item.binary.data.fileName = 'emailBody.txt'\n\nreturn $('Convert Email Body to File').item;" +}, +"typeVersion": 2 +}, +{ +"id": "fe5b82cc-b4bb-4c97-9477-075d5a280e9f", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2574.536755825029, +0 +], +"parameters": { +"color": 7, +"width": 376.8280004374956, +"height": 595.590013880477, +"content": "![hctiapi](https://uploads.n8n.io/templates/hctiapi2.png)\n## Email Body Screenshot Creation\n\nThe **Screenshot HTML** node sends the email's HTML body to the **hcti.io** API, generating a screenshot that visually represents the email's layout. The **Retrieve Screenshot** node then fetches this image, making it available for attachment or review in subsequent steps. This dual-format processing ensures both clarity and flexibility in email analysis workflows." +}, +"typeVersion": 1 +}, +{ +"id": "86b21049-f65e-4c6a-a854-c4376f870da9", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1380, +-149.99110983560342 +], +"parameters": { +"color": 7, +"width": 814.4556539379754, +"height": 444.5525554815556, +"content": "![Gmail](https://uploads.n8n.io/templates/gmail.png)\n## Gmail Integration and Data Extraction\n\nThis section of the workflow connects to a Gmail account using the **Gmail Trigger** node, capturing incoming emails in real-time, with checks performed every minute. Once an email is detected, its key components—such as the subject, recipient, body, and headers—are extracted and assigned to variables using the **Set Gmail Variables** node. These variables are structured for subsequent analysis and processing in later steps." +}, +"typeVersion": 1 +}, +{ +"id": "b1a786cf-7a8d-49e1-90ed-31f3d0e65b13", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1380, +308 +], +"parameters": { +"color": 7, +"width": 809.7918597571277, +"height": 602.9002284617277, +"content": "![Gmail](https://uploads.n8n.io/templates/outlook.png)\n## Microsoft Outlook Integration and Email Header Processing\n\nThis section enables the integration of Microsoft Outlook to monitor and capture incoming emails. The Microsoft Outlook Trigger node checks for new messages every minute. Once an email is detected, the Retrieve Headers of Email node fetches detailed header and body content via the Microsoft Graph API. The Format Headers node organizes the email headers into a structured format using a JavaScript function, ensuring clarity and readiness for further processing. Finally, the Set Outlook Variables node extracts and assigns key details—such as the email subject, recipient, body, and formatted headers—to variables for use in subsequent workflow steps. This section is essential for processing Outlook emails and preparing them for analysis and reporting.\n\n\n\n\n\n\n" +}, +"typeVersion": 1 +}, +{ +"id": "e7ace035-b5f5-4ef3-a117-22c7c938868d", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2958.4325220284563, +24.744924120002338 +], +"parameters": { +"color": 7, +"width": 593.0990401534098, +"height": 573.1750519720028, +"content": "![hctiapi](https://uploads.n8n.io/templates/openai.png)\n## AI-Powered Email Analysis and Threat Detection\n\nThis section leverages ChatGPT for advanced email content and header analysis to determine potential phishing threats. The **Analyze Email with ChatGPT** node processes the email's HTML body and headers, generating a detailed JSON response that categorizes the email as malicious or benign. The response includes a verbose explanation, formatted for Jira, outlining the reasons for the classification. The **Check if Malicious** node evaluates the AI output to determine the next steps based on the email's threat status. If flagged as malicious, subsequent actions like reporting and ticket creation are triggered. This section ensures precise, AI-driven analysis to enhance email security workflows." +}, +"typeVersion": 1 +}, +{ +"id": "02c1ad8e-f952-42d2-ae9f-cf3a77e49e52", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +3562.4948140707697, +-125.79607719303533 +], +"parameters": { +"color": 7, +"width": 1251.7025543502837, +"height": 891.579206098173, +"content": "![hctiapi](https://uploads.n8n.io/templates/jira.png)\n## Automated Jira Ticket Creation and Email Attachment\n\nThis section streamlines the process of logging phishing email reports in Jira, complete with detailed analysis and attachments. The workflow creates two distinct Jira tickets depending on the AI classification of the email:\n\n1. **Potentially Malicious**: The **Create Potentially Malicious Ticket** node generates a ticket if the email is flagged as a phishing attempt, including a summary of ChatGPT's analysis and the email’s details.\n2. **Potentially Benign**: If the email is classified as safe, the **Create Potentially Benign Ticket** node logs a ticket with similar details but under a non-malicious category.\n\n\nThe **Set Jira ID** node ensures the generated ticket's ID is tracked for subsequent operations. Attachments are handled efficiently:\n\n- **Rename Screenshot** prepares the email screenshot for upload.\n- **Upload Screenshot of Email to Jira** adds the screenshot to the Jira ticket for visual context.\n- **Rename Email Body Screenshot** and **Upload Email Body to Jira** manage the attachment of the email's text body as a `.txt` file.\n\n\nThis section enhances reporting by automating ticket creation, ensuring all relevant email data is readily available for review by security teams." +}, +"typeVersion": 1 +}, +{ +"id": "597ef23e-c61c-4e27-8c14-74ec20079c96", +"name": "Check if Malicious", +"type": "n8n-nodes-base.if", +"position": [ +3400, +420 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "493f412c-5f11-4173-8940-90f5bc7f5fab", +"operator": { +"type": "boolean", +"operation": "true", +"singleValue": true +}, +"leftValue": "={{ $json.message.content.malicious }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "af512af9-924b-4019-bdf9-62aac9cd0dac", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2200, +39.041733604283195 +], +"parameters": { +"color": 7, +"width": 365.6458805720866, +"height": 559.8072303111675, +"content": "![n8n](https://uploads.n8n.io/templates/n8n.png)\n## Email Body Conversion\n\nThis section processes the email body into both text and visual formats for detailed analysis and reporting. The **Set Email Variables** node organizes the email's data, including its HTML body and text content, to prepare it for further steps. The **Convert Email Body to File** node creates a `.txt` file containing the plain text version of the email body, useful for documentation or further analysis." +}, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"Set Jira ID": { +"main": [ +[ +{ +"node": "Rename Screenshot", +"type": "main", +"index": 0 +} +] +] +}, +"Gmail Trigger": { +"main": [ +[ +{ +"node": "Set Gmail Variables", +"type": "main", +"index": 0 +} +] +] +}, +"Format Headers": { +"main": [ +[ +{ +"node": "Set Outlook Variables", +"type": "main", +"index": 0 +} +] +] +}, +"Screenshot HTML": { +"main": [ +[ +{ +"node": "Retrieve Screenshot", +"type": "main", +"index": 0 +} +] +] +}, +"Rename Screenshot": { +"main": [ +[ +{ +"node": "Upload Screenshot of Email to Jira", +"type": "main", +"index": 0 +} +] +] +}, +"Check if Malicious": { +"main": [ +[ +{ +"node": "Create Potentially Malicious Ticket", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Create Potentially Benign Ticket", +"type": "main", +"index": 0 +} +] +] +}, +"Retrieve Screenshot": { +"main": [ +[ +{ +"node": "Analyze Email with ChatGPT", +"type": "main", +"index": 0 +} +] +] +}, +"Set Email Variables": { +"main": [ +[ +{ +"node": "Convert Email Body to File", +"type": "main", +"index": 0 +} +] +] +}, +"Set Gmail Variables": { +"main": [ +[ +{ +"node": "Set Email Variables", +"type": "main", +"index": 0 +} +] +] +}, +"Set Outlook Variables": { +"main": [ +[ +{ +"node": "Set Email Variables", +"type": "main", +"index": 0 +} +] +] +}, +"Microsoft Outlook Trigger": { +"main": [ +[ +{ +"node": "Retrieve Headers of Email", +"type": "main", +"index": 0 +} +] +] +}, +"Retrieve Headers of Email": { +"main": [ +[ +{ +"node": "Format Headers", +"type": "main", +"index": 0 +} +] +] +}, +"Analyze Email with ChatGPT": { +"main": [ +[ +{ +"node": "Check if Malicious", +"type": "main", +"index": 0 +} +] +] +}, +"Convert Email Body to File": { +"main": [ +[ +{ +"node": "Screenshot HTML", +"type": "main", +"index": 0 +} +] +] +}, +"Rename Email Body Screenshot": { +"main": [ +[ +{ +"node": "Upload Email Body to Jira", +"type": "main", +"index": 0 +} +] +] +}, +"Create Potentially Benign Ticket": { +"main": [ +[ +{ +"node": "Set Jira ID", +"type": "main", +"index": 0 +} +] +] +}, +"Upload Screenshot of Email to Jira": { +"main": [ +[ +{ +"node": "Rename Email Body Screenshot", +"type": "main", +"index": 0 +} +] +] +}, +"Create Potentially Malicious Ticket": { +"main": [ +[ +{ +"node": "Set Jira ID", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Analyze Suspicious Email Contents with ChatGPT Vision.txt b/Analyze Suspicious Email Contents with ChatGPT Vision.txt new file mode 100644 index 0000000..16c6034 --- /dev/null +++ b/Analyze Suspicious Email Contents with ChatGPT Vision.txt @@ -0,0 +1,600 @@ +{ +"meta": { +"instanceId": "03e9d14e9196363fe7191ce21dc0bb17387a6e755dcc9acc4f5904752919dca8" +}, +"nodes": [ +{ +"id": "1bad6bfc-9ec9-48a5-b8f7-73c4de3d08cf", +"name": "Gmail Trigger", +"type": "n8n-nodes-base.gmailTrigger", +"position": [ +1480, +160 +], +"parameters": { +"simple": false, +"filters": {}, +"options": {}, +"pollTimes": { +"item": [ +{ +"mode": "everyMinute" +} +] +} +}, +"credentials": { +"gmailOAuth2": { +"id": "kkhNhqKpZt6IUZd0", +"name": " Gmail" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "9ac747a1-4fd8-46ba-b4c1-75fd17aab2ed", +"name": "Microsoft Outlook Trigger", +"type": "n8n-nodes-base.microsoftOutlookTrigger", +"disabled": true, +"position": [ +1480, +720 +], +"parameters": { +"fields": [ +"body", +"toRecipients", +"subject", +"bodyPreview" +], +"output": "fields", +"filters": {}, +"options": {}, +"pollTimes": { +"item": [ +{ +"mode": "everyMinute" +} +] +} +}, +"credentials": { +"microsoftOutlookOAuth2Api": { +"id": "vTCK0oVQ0WjFrI5H", +"name": " Outlook Credential" +} +}, +"typeVersion": 1 +}, +{ +"id": "5bf9b0e8-b84e-44a2-aad2-45dde3e4ab1b", +"name": "Screenshot HTML", +"type": "n8n-nodes-base.httpRequest", +"position": [ +2520, +480 +], +"parameters": { +"url": "https://hcti.io/v1/image", +"method": "POST", +"options": {}, +"sendBody": true, +"sendQuery": true, +"authentication": "genericCredentialType", +"bodyParameters": { +"parameters": [ +{ +"name": "html", +"value": "={{ $json.htmlBody }}" +} +] +}, +"genericAuthType": "httpBasicAuth", +"queryParameters": { +"parameters": [ +{} +] +} +}, +"credentials": { +"httpBasicAuth": { +"id": "8tm8mUWmPvtmPFPk", +"name": "hcti.io" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "fc770d1d-6c18-4d14-8344-1dc042464df6", +"name": "Retrieve Screenshot", +"type": "n8n-nodes-base.httpRequest", +"position": [ +2700, +480 +], +"parameters": { +"url": "={{ $json.url }}", +"options": {}, +"authentication": "genericCredentialType", +"genericAuthType": "httpBasicAuth" +}, +"credentials": { +"httpBasicAuth": { +"id": "8tm8mUWmPvtmPFPk", +"name": "hcti.io" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "2f3e5cc0-24e8-450a-898b-71e2d6f7bb58", +"name": "Set Outlook Variables", +"type": "n8n-nodes-base.set", +"position": [ +2020, +720 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "38bd3db2-1a8d-4c40-a2dd-336e0cc84224", +"name": "htmlBody", +"type": "string", +"value": "={{ $('Microsoft Outlook Trigger').item.json.body.content }}" +}, +{ +"id": "13bdd95b-ef02-486e-b38b-d14bd05a4a8a", +"name": "headers", +"type": "string", +"value": "={{ $json}}" +}, +{ +"id": "20566ad4-7eb7-42b1-8a0d-f8b759610f10", +"name": "subject", +"type": "string", +"value": "={{ $('Microsoft Outlook Trigger').item.json.subject }}" +}, +{ +"id": "7171998f-a5a2-4e23-946a-9c1ad75710e7", +"name": "recipient", +"type": "string", +"value": "={{ $('Microsoft Outlook Trigger').item.json.toRecipients[0].emailAddress.address }}" +}, +{ +"id": "cc262634-2470-4524-8319-abe2518a6335", +"name": "textBody", +"type": "string", +"value": "={{ $('Retrieve Headers of Email').item.json.body.content }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "374e5b16-a666-4706-9fd2-762b2927012d", +"name": "Set Gmail Variables", +"type": "n8n-nodes-base.set", +"position": [ +2040, +160 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "38bd3db2-1a8d-4c40-a2dd-336e0cc84224", +"name": "htmlBody", +"type": "string", +"value": "={{ $json.html }}" +}, +{ +"id": "18fbcf78-6d3c-4036-b3a2-fb5adf22176a", +"name": "headers", +"type": "string", +"value": "={{ $json.headers }}" +}, +{ +"id": "1d690098-be2a-4604-baf8-62f314930929", +"name": "subject", +"type": "string", +"value": "={{ $json.subject }}" +}, +{ +"id": "8009f00a-547f-4eb1-b52d-2e7305248885", +"name": "recipient", +"type": "string", +"value": "={{ $json.to.text }}" +}, +{ +"id": "1932e97d-b03b-4964-b8bc-8262aaaa1f7a", +"name": "textBody", +"type": "string", +"value": "={{ $json.text }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "3166738e-d0a3-475b-8b19-51afd519ee3a", +"name": "Retrieve Headers of Email", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1680, +720 +], +"parameters": { +"url": "=https://graph.microsoft.com/v1.0/me/messages/{{ $json.id }}?$select=internetMessageHeaders,body", +"options": {}, +"sendHeaders": true, +"authentication": "predefinedCredentialType", +"headerParameters": { +"parameters": [ +{ +"name": "Accept", +"value": "application/json" +}, +{ +"name": "Prefer", +"value": "outlook.body-content-type=\"text\"" +} +] +}, +"nodeCredentialType": "microsoftOutlookOAuth2Api" +}, +"credentials": { +"microsoftOutlookOAuth2Api": { +"id": "vTCK0oVQ0WjFrI5H", +"name": " Outlook Credential" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "25ae222c-088f-4565-98d6-803c8c1b0826", +"name": "Format Headers", +"type": "n8n-nodes-base.code", +"position": [ +1860, +720 +], +"parameters": { +"jsCode": "const input = $('Retrieve Headers of Email').item.json.internetMessageHeaders;\n\nconst result = input.reduce((acc, { name, value }) => {\n if (!acc[name]) acc[name] = [];\n acc[name].push(value);\n return acc;\n}, {});\n\nreturn result;" +}, +"typeVersion": 2 +}, +{ +"id": "8f14f267-1074-43ea-968d-26a6ab36fd7b", +"name": "Set Email Variables", +"type": "n8n-nodes-base.set", +"position": [ +2360, +480 +], +"parameters": { +"options": {}, +"includeOtherFields": true +}, +"typeVersion": 3.4 +}, +{ +"id": "45d156aa-91f4-483c-91d4-c9de4a4f595d", +"name": "ChatGPT Analysis", +"type": "@n8n/n8n-nodes-langchain.openAi", +"position": [ +3100, +480 +], +"parameters": { +"text": "=Describe this image. Determine if the email could be a phishing email. The message headers are as follows:\n{{ $('Set Email Variables').item.json.headers }}\n\nFormat the response for Jira who uses a wiki-style renderer. Do not include ``` around your response.", +"modelId": { +"__rl": true, +"mode": "list", +"value": "chatgpt-4o-latest", +"cachedResultName": "CHATGPT-4O-LATEST" +}, +"options": { +"maxTokens": 1500 +}, +"resource": "image", +"inputType": "base64", +"operation": "analyze" +}, +"credentials": { +"openAiApi": { +"id": "76", +"name": "OpenAi account" +} +}, +"typeVersion": 1.6 +}, +{ +"id": "62ca591b-6627-496c-96a7-95cb0081480d", +"name": "Create Jira Ticket", +"type": "n8n-nodes-base.jira", +"position": [ +3500, +480 +], +"parameters": { +"project": { +"__rl": true, +"mode": "list", +"value": "10001", +"cachedResultName": "Support" +}, +"summary": "=Phishing Email Reported: \"{{ $('Set Email Variables').item.json.subject }}\"", +"issueType": { +"__rl": true, +"mode": "list", +"value": "10008", +"cachedResultName": "Task" +}, +"additionalFields": { +"description": "=A phishing email was reported by {{ $('Set Email Variables').item.json.recipient }} with the subject line \"{{ $('Set Email Variables').item.json.subject }}\" and body:\n{{ $('Set Email Variables').item.json.textBody }}\n\\\\\n\\\\\n\\\\\nh2. Here is ChatGPT's analysis of the email:\n{{ $json.content }}" +} +}, +"credentials": { +"jiraSoftwareCloudApi": { +"id": "BZmmGUrNIsgM9fDj", +"name": "New Jira Cloud" +} +}, +"typeVersion": 1 +}, +{ +"id": "071380c8-8070-4f8f-86c6-87c4ee3bc261", +"name": "Rename Screenshot", +"type": "n8n-nodes-base.code", +"position": [ +3680, +480 +], +"parameters": { +"mode": "runOnceForEachItem", +"jsCode": "$('Retrieve Screenshot').item.binary.data.fileName = 'emailScreenshot.png'\n\nreturn $('Retrieve Screenshot').item;" +}, +"typeVersion": 2 +}, +{ +"id": "05c57490-c1ee-48f0-9e38-244c9a995e22", +"name": "Upload Screenshot of Email to Jira", +"type": "n8n-nodes-base.jira", +"position": [ +3860, +480 +], +"parameters": { +"issueKey": "={{ $('Create Jira Ticket').item.json.key }}", +"resource": "issueAttachment" +}, +"credentials": { +"jiraSoftwareCloudApi": { +"id": "BZmmGUrNIsgM9fDj", +"name": "New Jira Cloud" +} +}, +"typeVersion": 1 +}, +{ +"id": "be02770d-a943-41f5-98a9-5c433a6a3dbf", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1420, +-107.36679523834897 +], +"parameters": { +"color": 7, +"width": 792.3026315789474, +"height": 426.314163659402, +"content": "![Gmail](https://uploads.n8n.io/templates/gmail.png)\n## Gmail Integration and Data Extraction\n\nThis section of the workflow connects to a Gmail account using the **Gmail Trigger** node, capturing incoming emails in real-time, with checks performed every minute. Once an email is detected, its key components—such as the subject, recipient, body, and headers—are extracted and assigned to variables using the **Set Gmail Variables** node. These variables are structured for subsequent analysis and processing in later steps." +}, +"typeVersion": 1 +}, +{ +"id": "c1d2f691-669a-46de-9ef8-59ce4e6980c5", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1420, +380.6918768014301 +], +"parameters": { +"color": 7, +"width": 792.3026315789474, +"height": 532.3344389880435, +"content": "![Gmail](https://uploads.n8n.io/templates/outlook.png)\n## Microsoft Outlook Integration and Email Header Processing\n\nThis section connects to a Microsoft Outlook account to monitor incoming emails using the **Microsoft Outlook Trigger** node, which checks for new messages every minute. Emails are then processed to retrieve detailed headers and body content via the **Retrieve Headers of Email** node. The headers are structured into a user-friendly format using the **Format Headers** code node, ensuring clarity for further analysis. Key details, including the email's subject, recipient, and body content, are assigned to variables with the **Set Outlook Variables** node for streamlined integration into subsequent workflow steps." +}, +"typeVersion": 1 +}, +{ +"id": "c189e2e0-9f51-4bc0-a483-8b7f0528be70", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2287.3684210526317, +46.18421052631584 +], +"parameters": { +"color": 7, +"width": 580.4605263157906, +"height": 615.460526315789, +"content": "![hctiapi](https://uploads.n8n.io/templates/hctiapi.png)\n## HTML Screenshot Generation and Email Visualization\n\nThis section processes an email’s HTML content to create a visual representation, useful for documentation or phishing detection workflows. The **Set Email Variables** node organizes the email's HTML body into a format ready for processing. The **Screenshot HTML** node sends this HTML content to the **hcti.io** API, which generates a screenshot of the email's layout. The **Retrieve Screenshot** node then fetches the image URL for further use in the workflow. This setup ensures that the email's appearance is preserved in a visually accessible format, simplifying review and reporting. Keep in mind however that this exposes the email content to a third party. If you self host n8n, you can deploy a cli tool to rasterize locally instead." +}, +"typeVersion": 1 +}, +{ +"id": "9076f9e9-f4fb-409a-9580-1ae459094c31", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2880, +123.72476075009968 +], +"parameters": { +"color": 7, +"width": 507.82894736842223, +"height": 537.9199760920052, +"content": "![hctiapi](https://uploads.n8n.io/templates/openai.png)\n## AI-Powered Email Analysis with ChatGPT\n\nThis section leverages AI to analyze email content and headers for phishing indicators. The **ChatGPT Analysis** node utilizes the ChatGPT-4 model to review the email screenshot and associated metadata, including message headers. It generates a detailed report indicating whether the email might be a phishing attempt. The output is formatted specifically for Jira’s wiki-style renderer, making it ready for seamless integration into ticketing workflows. This ensures thorough and automated email threat assessments." +}, +"typeVersion": 1 +}, +{ +"id": "ca2488af-e787-4675-802a-8b4f2d845376", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +3400, +122.88662032580646 +], +"parameters": { +"color": 7, +"width": 692.434210526317, +"height": 529.5475902005091, +"content": "![hctiapi](https://uploads.n8n.io/templates/jira.png)\n## Automated Jira Ticket Creation for Phishing Reports\n\nThis section streamlines the process of reporting phishing emails by automatically creating detailed Jira tickets. The **Create Jira Ticket** node compiles email information, including the subject, recipient, body text, and ChatGPT's phishing analysis, into a structured ticket. The **Rename Screenshot** node ensures that the email screenshot file is appropriately labeled for attachment. Finally, the **Upload Screenshot of Email to Jira** node attaches the email’s visual representation to the ticket, providing additional context for the security team. This integration ensures that phishing reports are logged with all necessary details, enabling efficient tracking and resolution." +}, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"Gmail Trigger": { +"main": [ +[ +{ +"node": "Set Gmail Variables", +"type": "main", +"index": 0 +} +] +] +}, +"Format Headers": { +"main": [ +[ +{ +"node": "Set Outlook Variables", +"type": "main", +"index": 0 +} +] +] +}, +"Screenshot HTML": { +"main": [ +[ +{ +"node": "Retrieve Screenshot", +"type": "main", +"index": 0 +} +] +] +}, +"ChatGPT Analysis": { +"main": [ +[ +{ +"node": "Create Jira Ticket", +"type": "main", +"index": 0 +} +] +] +}, +"Rename Screenshot": { +"main": [ +[ +{ +"node": "Upload Screenshot of Email to Jira", +"type": "main", +"index": 0 +} +] +] +}, +"Create Jira Ticket": { +"main": [ +[ +{ +"node": "Rename Screenshot", +"type": "main", +"index": 0 +} +] +] +}, +"Retrieve Screenshot": { +"main": [ +[ +{ +"node": "ChatGPT Analysis", +"type": "main", +"index": 0 +} +] +] +}, +"Set Email Variables": { +"main": [ +[ +{ +"node": "Screenshot HTML", +"type": "main", +"index": 0 +} +] +] +}, +"Set Gmail Variables": { +"main": [ +[ +{ +"node": "Set Email Variables", +"type": "main", +"index": 0 +} +] +] +}, +"Set Outlook Variables": { +"main": [ +[ +{ +"node": "Set Email Variables", +"type": "main", +"index": 0 +} +] +] +}, +"Microsoft Outlook Trigger": { +"main": [ +[ +{ +"node": "Retrieve Headers of Email", +"type": "main", +"index": 0 +} +] +] +}, +"Retrieve Headers of Email": { +"main": [ +[ +{ +"node": "Format Headers", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Analyze feedback and send a message on Mattermost.txt b/Analyze feedback and send a message on Mattermost.txt new file mode 100644 index 0000000..cd604d6 --- /dev/null +++ b/Analyze feedback and send a message on Mattermost.txt @@ -0,0 +1,128 @@ +{ +"id": "133", +"name": "Analyze the sentiment of feedback and send a message on Mattermost", +"nodes": [ +{ +"name": "Typeform Trigger", +"type": "n8n-nodes-base.typeformTrigger", +"position": [ +510, +260 +], +"webhookId": "ad8a87ef-d293-4e48-8d36-838d69ebce0f", +"parameters": { +"formId": "" +}, +"credentials": { +"typeformApi": "typeform" +}, +"typeVersion": 1 +}, +{ +"name": "Google Cloud Natural Language", +"type": "n8n-nodes-base.googleCloudNaturalLanguage", +"position": [ +710, +260 +], +"parameters": { +"content": "={{$node[\"Typeform Trigger\"].json[\"What did you think about the event?\"]}}", +"options": {} +}, +"credentials": { +"googleCloudNaturalLanguageOAuth2Api": "cloud" +}, +"typeVersion": 1 +}, +{ +"name": "IF", +"type": "n8n-nodes-base.if", +"position": [ +910, +260 +], +"parameters": { +"conditions": { +"number": [ +{ +"value1": "={{$node[\"Google Cloud Natural Language\"].json[\"documentSentiment\"][\"score\"]}}" +} +] +} +}, +"typeVersion": 1 +}, +{ +"name": "Mattermost", +"type": "n8n-nodes-base.mattermost", +"position": [ +1110, +160 +], +"parameters": { +"message": "=You got a new feedback with a score of {{$node[\"Google Cloud Natural Language\"].json[\"documentSentiment\"][\"score\"]}}. Here is what it says:{{$node[\"Typeform Trigger\"].json[\"What did you think about the event?\"]}}", +"channelId": "4h1bz64cyifwxnzojkzh8hxh4a", +"attachments": [], +"otherOptions": {} +}, +"credentials": { +"mattermostApi": "mattermost" +}, +"typeVersion": 1 +}, +{ +"name": "NoOp", +"type": "n8n-nodes-base.noOp", +"position": [ +1110, +360 +], +"parameters": {}, +"typeVersion": 1 +} +], +"active": false, +"settings": {}, +"connections": { +"IF": { +"main": [ +[ +{ +"node": "Mattermost", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "NoOp", +"type": "main", +"index": 0 +} +] +] +}, +"Typeform Trigger": { +"main": [ +[ +{ +"node": "Google Cloud Natural Language", +"type": "main", +"index": 0 +} +] +] +}, +"Google Cloud Natural Language": { +"main": [ +[ +{ +"node": "IF", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Analyze feedback using AWS Comprehend and send it to a Mattermost channel.txt b/Analyze feedback using AWS Comprehend and send it to a Mattermost channel.txt new file mode 100644 index 0000000..c204cf9 --- /dev/null +++ b/Analyze feedback using AWS Comprehend and send it to a Mattermost channel.txt @@ -0,0 +1,126 @@ +{ +"nodes": [ +{ +"name": "Mattermost", +"type": "n8n-nodes-base.mattermost", +"position": [ +810, +300 +], +"parameters": { +"message": "=You got new feedback with a score of {{$json[\"SentimentScore\"][\"Negative\"]}}. Here is what it says:{{$node[\"Typeform Trigger\"].json[\"What did you think about the event?\"]}}", +"channelId": "h7cxrd1cefr13x689enzyw7xhc", +"attachments": [], +"otherOptions": {} +}, +"credentials": { +"mattermostApi": "Mattermost Credentials" +}, +"typeVersion": 1 +}, +{ +"name": "NoOp", +"type": "n8n-nodes-base.noOp", +"position": [ +800, +500 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"name": "IF", +"type": "n8n-nodes-base.if", +"position": [ +600, +400 +], +"parameters": { +"conditions": { +"number": [], +"string": [ +{ +"value1": "={{$json[\"Sentiment\"]}}", +"value2": "NEGATIVE" +} +] +} +}, +"typeVersion": 1 +}, +{ +"name": "AWS Comprehend", +"type": "n8n-nodes-base.awsComprehend", +"position": [ +400, +400 +], +"parameters": { +"text": "={{$json[\"What did you think about the event?\"]}}", +"operation": "detectSentiment" +}, +"credentials": { +"aws": "AWS Comprehend Credentials" +}, +"typeVersion": 1 +}, +{ +"name": "Typeform Trigger", +"type": "n8n-nodes-base.typeformTrigger", +"position": [ +200, +400 +], +"webhookId": "ad8a87ef-d293-4e48-8d36-838d69ebce0f", +"parameters": { +"formId": "DuJHEGW5" +}, +"credentials": { +"typeformApi": "typeform" +}, +"typeVersion": 1 +} +], +"connections": { +"IF": { +"main": [ +[ +{ +"node": "Mattermost", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "NoOp", +"type": "main", +"index": 0 +} +] +] +}, +"AWS Comprehend": { +"main": [ +[ +{ +"node": "IF", +"type": "main", +"index": 0 +} +] +] +}, +"Typeform Trigger": { +"main": [ +[ +{ +"node": "AWS Comprehend", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Analyze tradingview.com charts with Chrome extension, N8N and OpenAI.txt b/Analyze tradingview.com charts with Chrome extension, N8N and OpenAI.txt new file mode 100644 index 0000000..5d58128 --- /dev/null +++ b/Analyze tradingview.com charts with Chrome extension, N8N and OpenAI.txt @@ -0,0 +1,131 @@ +{ +"id": "Q8On8rR6BkmPzDUd", +"meta": { +"instanceId": "f57770b08f6a574802832e927ed1b0063c627ffc5b95965abf0d4a7396150138" +}, +"name": "chrome extension backend with AI", +"tags": [], +"nodes": [ +{ +"id": "0f38fe62-36d9-43da-a992-a3981377e89e", +"name": "Webhook", +"type": "n8n-nodes-base.webhook", +"position": [ +-220, +-20 +], +"webhookId": "e9a97dd5-f1e7-4d5b-a6f1-be5f0c9eb96c", +"parameters": { +"path": "e9a97dd5-f1e7-4d5b-a6f1-be5f0c9eb96c", +"options": {}, +"httpMethod": "POST", +"responseMode": "responseNode" +}, +"typeVersion": 2 +}, +{ +"id": "83959562-edf5-4d37-bd11-47186c6a31c7", +"name": "OpenAI", +"type": "@n8n/n8n-nodes-langchain.openAi", +"position": [ +-40, +-20 +], +"parameters": { +"text": "You are an expert financial analyst tasked with providing an advanced technical analyses of a stock or crypto currency chart provided. Your analysis will be based on various technical indicators and will provide simple insights for novice traders. Just explain to traders were you expect the market is moving. Also warn them this is not a binding advice. Make sure to explain everything in infant language.", +"modelId": { +"__rl": true, +"mode": "list", +"value": "gpt-4o-mini", +"cachedResultName": "GPT-4O-MINI" +}, +"options": {}, +"resource": "image", +"inputType": "base64", +"operation": "analyze" +}, +"credentials": { +"openAiApi": { +"id": "8MS1muoK4z86fxUs", +"name": "OpenAi account" +} +}, +"typeVersion": 1.7 +}, +{ +"id": "c6f1f833-7ba3-49c5-86df-f586e6bb5975", +"name": "Respond to Webhook", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +140, +-20 +], +"parameters": { +"options": {}, +"respondWith": "text", +"responseBody": "={{ $json.content }}" +}, +"typeVersion": 1.1 +}, +{ +"id": "e3a38a76-283b-4567-a8da-315ef1e2bc4f", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-260, +-140 +], +"parameters": { +"width": 620, +"height": 300, +"content": "## N8N en OpenAI image analyser" +}, +"typeVersion": 1 +}, +{ +"id": "8e7e26db-8767-4727-ab0c-900b50a73411", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-80, +180 +], +"parameters": { +"color": 5, +"height": 340, +"content": "## AI prompt\nYou are an expert financial analyst tasked with providing an advanced technical analyses of a stock or crypto currency chart provided. Your analysis will be based on various technical indicators and will provide simple insights for novice traders. Just explain to traders were you expect the market is moving. Also warn them this is not a binding advice. Make sure to explain everything in infant language." +}, +"typeVersion": 1 +} +], +"active": true, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "caf32442-e9c5-466a-8888-9abd2c1b3449", +"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/Angie, Personal AI Assistant with Telegram Voice and Text.txt b/Angie, Personal AI Assistant with Telegram Voice and Text.txt new file mode 100644 index 0000000..f7af6d8 --- /dev/null +++ b/Angie, Personal AI Assistant with Telegram Voice and Text.txt @@ -0,0 +1,476 @@ +{ +"meta": { +"instanceId": "2723a3a635131edfcb16103f3d4dbaadf3658e386b4762989cbf49528dccbdbd" +}, +"nodes": [ +{ +"id": "c70236ea-91ab-4e47-b6f6-63a70ede5d3c", +"name": "Google Calendar", +"type": "n8n-nodes-base.googleCalendarTool", +"position": [ +1000, +680 +], +"parameters": { +"options": { +"fields": "=items(summary, start(dateTime))", +"timeMin": "={{$fromAI(\"date\",\"the date after which to fetch the messages in format YYYY-MM-DDTHH:MM:SS\")}}" +}, +"calendar": { +"__rl": true, +"mode": "list", +"value": "derekcheungsa@gmail.com", +"cachedResultName": "derekcheungsa@gmail.com" +}, +"operation": "getAll" +}, +"credentials": { +"googleCalendarOAuth2Api": { +"id": "qx8JdPX4I5Xk9c46", +"name": "Google Calendar account" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "d2287bea-de47-4180-8ee6-55d4ab1a89da", +"name": "Window Buffer Memory", +"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow", +"position": [ +760, +680 +], +"parameters": { +"sessionKey": "={{ $('Listen for incoming events').first().json.message.from.id }}", +"sessionIdType": "customKey" +}, +"typeVersion": 1.2 +}, +{ +"id": "fa955731-86f6-4e4d-8604-dab5f52dee87", +"name": "Get Email", +"type": "n8n-nodes-base.gmailTool", +"position": [ +880, +680 +], +"parameters": { +"filters": { +"labelIds": [ +"INBOX", +"UNREAD" +], +"readStatus": "unread", +"receivedAfter": "={{$fromAI(\"date\",\"the date after which to fetch the messages in format YYYY-MM-DDTHH:MM:SS\")}}" +}, +"operation": "getAll" +}, +"credentials": { +"gmailOAuth2": { +"id": "tojOpzEqFprdxS46", +"name": "Gmail account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "46511f47-1687-4cbe-ae41-ceb205ed1f11", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +640, +680 +], +"parameters": { +"model": "gpt-4o-mini", +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "5oYe8Cxj7liOPAKk", +"name": "Derek T" +} +}, +"typeVersion": 1 +}, +{ +"id": "64fe44db-af19-43eb-9ff1-de0a72a9e645", +"name": "Listen for incoming events", +"type": "n8n-nodes-base.telegramTrigger", +"position": [ +-160, +360 +], +"webhookId": "322dce18-f93e-4f86-b9b1-3305519b7834", +"parameters": { +"updates": [ +"message" +], +"additionalFields": {} +}, +"credentials": { +"telegramApi": { +"id": "Ov00cT0t4h4AFtZ0", +"name": "Telegram account" +} +}, +"typeVersion": 1 +}, +{ +"id": "e35c04ff-a050-4564-8c1b-5b22b556872f", +"name": "Telegram", +"type": "n8n-nodes-base.telegram", +"onError": "continueErrorOutput", +"position": [ +1280, +360 +], +"parameters": { +"text": "={{ $json.output }}", +"chatId": "={{ $('Listen for incoming events').first().json.message.from.id }}", +"additionalFields": { +"parse_mode": "Markdown", +"appendAttribution": false +} +}, +"credentials": { +"telegramApi": { +"id": "Ov00cT0t4h4AFtZ0", +"name": "Telegram account" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "e791d4f8-2c19-4c14-a71e-39a04f22e944", +"name": "If", +"type": "n8n-nodes-base.if", +"position": [ +200, +360 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "a0bf9719-4272-46f6-ab3b-eda6f7b44fd8", +"operator": { +"type": "string", +"operation": "empty", +"singleValue": true +}, +"leftValue": "={{ $json.message.text }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "5bd1788a-3d08-4eb3-8e03-3ce82f44d2a7", +"name": "Speech to Text", +"type": "@n8n/n8n-nodes-langchain.openAi", +"position": [ +620, +360 +], +"parameters": { +"options": {}, +"resource": "audio", +"operation": "transcribe" +}, +"credentials": { +"openAiApi": { +"id": "5oYe8Cxj7liOPAKk", +"name": "Derek T" +} +}, +"typeVersion": 1.3 +}, +{ +"id": "b67a2a93-517b-469e-aaa4-32c422710743", +"name": "Voice or Text", +"type": "n8n-nodes-base.set", +"position": [ +40, +360 +], +"parameters": { +"fields": { +"values": [ +{ +"name": "text", +"stringValue": "={{ $json?.message?.text || \"\" }}" +} +] +}, +"options": {} +}, +"typeVersion": 3.2 +}, +{ +"id": "8105c39f-9e87-44c4-9215-b3777f0b4164", +"name": "Get Voice File", +"type": "n8n-nodes-base.telegram", +"position": [ +380, +360 +], +"parameters": { +"fileId": "={{ $('Listen for incoming events').item.json.message.voice.file_id }}", +"resource": "file" +}, +"credentials": { +"telegramApi": { +"id": "Ov00cT0t4h4AFtZ0", +"name": "Telegram account" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "759b975f-d17c-4386-a5b3-12413f0361f4", +"name": "Angie, AI Assistant 👩🏻‍🏫", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +780, +360 +], +"parameters": { +"text": "={{ $json.text }}", +"options": { +"systemMessage": "=You are a helpful assistant.\n\nToday's date is {{ $now }}.\n\nGuidelines:\n- When fetching emails, filter out any promotional emails. \n- When summarizing emails, include Sender, Message date, subject, and brief summary of email.\n- if the user did not specify a date in the request assume they are asking for today\n- Use baserow tool to answer questions about tasks\n- When answering questions about calendar events, filter out events that don't apply to the question. For example, the question is about events for today, only reply with events for today. Don't mention future events if it's more than 1 week away" +}, +"promptType": "define" +}, +"typeVersion": 1.6 +}, +{ +"id": "5537c777-f003-4673-b48a-4993a0c10520", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +20, +260 +], +"parameters": { +"color": 5, +"width": 496.25, +"height": 278.75, +"content": "## Process Telegram Request\n" +}, +"typeVersion": 1 +}, +{ +"id": "40e92679-b47a-4213-bb23-3f8d086459f2", +"name": "Tasks", +"type": "n8n-nodes-base.baserowTool", +"position": [ +1120, +680 +], +"parameters": { +"tableId": 372174, +"databaseId": 146496, +"additionalOptions": {} +}, +"credentials": { +"baserowApi": { +"id": "jsgACn0VxAPoD0E2", +"name": "Baserow account" +} +}, +"typeVersion": 1 +}, +{ +"id": "570a0647-b571-4ebc-9dfe-40244b5a0b2a", +"name": "Contacts", +"type": "n8n-nodes-base.baserowTool", +"position": [ +1240, +680 +], +"parameters": { +"tableId": 372177, +"databaseId": 146496, +"descriptionType": "manual", +"toolDescription": "Useful for getting contact information. For example emails or phone numbers.", +"additionalOptions": {} +}, +"credentials": { +"baserowApi": { +"id": "jsgACn0VxAPoD0E2", +"name": "Baserow account" +} +}, +"typeVersion": 1 +}, +{ +"id": "7fb1d95a-a8d6-4040-9271-5197296be7da", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-620, +220 +], +"parameters": { +"color": 5, +"width": 386.9292441979969, +"height": 389.78268107403096, +"content": "## Start here: Step-by Step Youtube Tutorial :star:\n\n[![Building an AI Personal Assistant](https://img.youtube.com/vi/pXjowPc6V2s/sddefault.jpg)](https://youtu.be/pXjowPc6V2s)\n" +}, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"If": { +"main": [ +[ +{ +"node": "Get Voice File", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Angie, AI Assistant 👩🏻‍🏫", +"type": "main", +"index": 0 +} +] +] +}, +"Tasks": { +"ai_tool": [ +[ +{ +"node": "Angie, AI Assistant 👩🏻‍🏫", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Contacts": { +"ai_tool": [ +[ +{ +"node": "Angie, AI Assistant 👩🏻‍🏫", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Get Email": { +"ai_tool": [ +[ +{ +"node": "Angie, AI Assistant 👩🏻‍🏫", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Voice or Text": { +"main": [ +[ +{ +"node": "If", +"type": "main", +"index": 0 +} +] +] +}, +"Get Voice File": { +"main": [ +[ +{ +"node": "Speech to Text", +"type": "main", +"index": 0 +} +] +] +}, +"Speech to Text": { +"main": [ +[ +{ +"node": "Angie, AI Assistant 👩🏻‍🏫", +"type": "main", +"index": 0 +} +] +] +}, +"Google Calendar": { +"ai_tool": [ +[ +{ +"node": "Angie, AI Assistant 👩🏻‍🏫", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Angie, AI Assistant 👩🏻‍🏫", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Window Buffer Memory": { +"ai_memory": [ +[ +{ +"node": "Angie, AI Assistant 👩🏻‍🏫", +"type": "ai_memory", +"index": 0 +} +] +] +}, +"Listen for incoming events": { +"main": [ +[ +{ +"node": "Voice or Text", +"type": "main", +"index": 0 +} +] +] +}, +"Angie, AI Assistant 👩🏻‍🏫": { +"main": [ +[ +{ +"node": "Telegram", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Ask a human for help when the AI doesn_t know the answer.txt b/Ask a human for help when the AI doesn_t know the answer.txt new file mode 100644 index 0000000..6286076 --- /dev/null +++ b/Ask a human for help when the AI doesn_t know the answer.txt @@ -0,0 +1,368 @@ +{ +"name": "Ask a human", +"nodes": [ +{ +"id": "a60c8572-56c1-4bf3-8352-a6419a475887", +"name": "Window Buffer Memory", +"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow", +"position": [ +900, +760 +], +"parameters": {}, +"typeVersion": 1.1 +}, +{ +"id": "b4f2e26c-903b-46b8-bd8b-110fd64de9e4", +"name": "Not sure?", +"type": "@n8n/n8n-nodes-langchain.toolWorkflow", +"position": [ +1120, +760 +], +"parameters": { +"name": "dont_know_tool", +"fields": { +"values": [ +{ +"name": "chatInput", +"stringValue": "={{ $('Chat Trigger').item.json.chatInput }}" +} +] +}, +"workflowId": "={{ $workflow.id}}", +"description": "Use this tool if you don't know the answer to the user's question, or if you're not very confident about your answer." +}, +"typeVersion": 1 +}, +{ +"id": "951cc691-b422-4ce6-901f-b7feb3afd1ad", +"name": "Execute Workflow Trigger", +"type": "n8n-nodes-base.executeWorkflowTrigger", +"position": [ +540, +1360 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "194ba9c0-e256-449a-8da7-ac5339123a99", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +500, +1020 +], +"parameters": { +"color": 7, +"width": 1118.3459011229047, +"height": 775.3931210698682, +"content": "### Sub-workflow: Custom tool\nThe agent above can call this workflow. It checks if the user has supplied an email address. If they haven't it prompts them to provide one. If they have, it messages a customer support channel for help." +}, +"typeVersion": 1 +}, +{ +"id": "38c6b363-45a7-4e72-9e40-8c0df3cc480f", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +500, +460 +], +"parameters": { +"color": 7, +"width": 927.5, +"height": 486.5625, +"content": "### Main workflow: AI agent using custom tool" +}, +"typeVersion": 1 +}, +{ +"id": "0389315b-e48d-4b00-b9a1-899302b1b094", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1060, +700 +], +"parameters": { +"color": 5, +"width": 197.45572294791873, +"height": 179.21380662202682, +"content": "**This tool calls the sub-workflow below**" +}, +"typeVersion": 1 +}, +{ +"id": "fb11064a-4cf5-4110-9e39-af24a3225164", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +700, +680 +], +"parameters": { +"color": 2, +"width": 150, +"height": 213.44323866265472, +"content": "**Set your credentials**" +}, +"typeVersion": 1 +}, +{ +"id": "d689021d-0a46-4dff-a01a-0b01ecdd198b", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1020, +1180 +], +"parameters": { +"color": 2, +"width": 178.0499248677781, +"height": 250.57252651663197, +"content": "**Set your credentials and Slack details**" +}, +"typeVersion": 1 +}, +{ +"id": "0926cd61-c0b8-4bae-ae65-9afd130d17cd", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +340, +520 +], +"parameters": { +"color": 4, +"width": 185.9375, +"height": 214.8397420554627, +"content": "## Try it out\n\nSelect **Chat** at the bottom and enter:\n\n_Hi! Please respond to this as if you don't know the answer to my query._" +}, +"typeVersion": 1 +}, +{ +"id": "cde69dfe-252e-4a05-8d56-fa79431df5d8", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1580, +1600 +], +"parameters": { +"height": 144.50520156238127, +"content": "## Next steps\n\nLearn more about [Advanced AI in n8n](https://docs.n8n.io/advanced-ai/)" +}, +"typeVersion": 1 +}, +{ +"id": "927b775a-47f6-4067-a1a5-5f13dea28e45", +"name": "Chat Trigger", +"type": "@n8n/n8n-nodes-langchain.chatTrigger", +"position": [ +600, +520 +], +"webhookId": "785e0c0c-12e5-4249-9abe-47bb131975cb", +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "971e7b90-c2d8-4292-9da8-732d7d399f04", +"name": "Prompt the user to provide an email", +"type": "n8n-nodes-base.code", +"position": [ +1060, +1520 +], +"parameters": { +"jsCode": "response = {\"response\":\"I'm sorry I don't know the answer. Please repeat your question and include your email address so I can request help.\"};\nreturn response;" +}, +"typeVersion": 2 +}, +{ +"id": "6f5a21b3-c145-46c8-8e69-660100c4a6fc", +"name": "Confirm that we've messaged a human", +"type": "n8n-nodes-base.code", +"position": [ +1300, +1260 +], +"parameters": { +"jsCode": "response = {\"response\": \"Thank you for getting in touch. I've messaged a human to help.\"}\nreturn response;" +}, +"typeVersion": 2 +}, +{ +"id": "8b17da5e-e392-4028-91b0-bc02d34e46ed", +"name": "AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +820, +520 +], +"parameters": { +"options": { +"systemMessage": "Try to answer the user's question. When you can't answer, or you're not confident of the answer, use the appropriate tool. When you use the dont_know_tool, respond with the message from the tool." +} +}, +"typeVersion": 1.2 +}, +{ +"id": "990ecd3b-6aa0-4b17-8d01-d606b9164fa8", +"name": "Check if user has provided email", +"type": "n8n-nodes-base.if", +"position": [ +760, +1360 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "5e21e7c5-db60-4111-bb17-c289ae0fc159", +"operator": { +"type": "string", +"operation": "regex" +}, +"leftValue": "={{ $('Execute Workflow Trigger').item.json.chatInput }}", +"rightValue": "/([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\\.[a-zA-Z0-9_-]+)/gi" +} +] +} +}, +"typeVersion": 2 +}, +{ +"id": "d14da0ae-06ca-422b-b5b6-e7759e74c787", +"name": "Message Slack for help", +"type": "n8n-nodes-base.slack", +"position": [ +1060, +1260 +], +"parameters": { +"text": "={{ \"A user had a question the bot couldn't answer. Here's their message: \" + $('Execute Workflow Trigger').item.json.chatInput }}", +"select": "channel", +"channelId": { +"__rl": true, +"mode": "name", +"value": "" +}, +"otherOptions": {} +}, +"typeVersion": 2.1 +}, +{ +"id": "278391c7-6945-495e-a4f1-74fb8fcc3549", +"name": "GPT4", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +740, +740 +], +"parameters": { +"model": "gpt-4", +"options": { +"temperature": 0.2 +} +}, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"GPT4": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Not sure?": { +"ai_tool": [ +[ +{ +"node": "AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Chat Trigger": { +"main": [ +[ +{ +"node": "AI Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Window Buffer Memory": { +"ai_memory": [ +[ +{ +"node": "AI Agent", +"type": "ai_memory", +"index": 0 +} +] +] +}, +"Message Slack for help": { +"main": [ +[ +{ +"node": "Confirm that we've messaged a human", +"type": "main", +"index": 0 +} +] +] +}, +"Execute Workflow Trigger": { +"main": [ +[ +{ +"node": "Check if user has provided email", +"type": "main", +"index": 0 +} +] +] +}, +"Check if user has provided email": { +"main": [ +[ +{ +"node": "Message Slack for help", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Prompt the user to provide an email", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Ask questions about a PDF using AI.txt b/Ask questions about a PDF using AI.txt new file mode 100644 index 0000000..09ae539 --- /dev/null +++ b/Ask questions about a PDF using AI.txt @@ -0,0 +1,408 @@ +{ +"meta": { +"instanceId": "62b3b6db4f4d3641a1fa1da6dfb9699a19380a1f60cbc18fc75d6d145f35552b" +}, +"nodes": [ +{ +"id": "40bb5497-d1d2-4eb7-b683-78b88c8d9230", +"name": "Google Drive", +"type": "n8n-nodes-base.googleDrive", +"position": [ +496.83478320435574, +520 +], +"parameters": { +"fileId": { +"__rl": true, +"mode": "url", +"value": "https://drive.google.com/file/d/11Koq9q53nkk0F5Y8eZgaWJUVR03I4-MM/view" +}, +"options": {}, +"operation": "download" +}, +"credentials": { +"googleDriveOAuth2Api": { +"id": "20", +"name": "Google Drive account" +} +}, +"typeVersion": 3 +}, +{ +"id": "1323d520-1528-4a5a-9806-8f4f45306098", +"name": "Recursive Character Text Splitter", +"type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter", +"position": [ +996.8347832043557, +920 +], +"parameters": { +"chunkSize": 3000, +"chunkOverlap": 200 +}, +"typeVersion": 1 +}, +{ +"id": "796b155a-64e6-4a52-9168-a37c68077d99", +"name": "Embeddings OpenAI", +"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi", +"position": [ +836.8347832043557, +740 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "JCgD7807AQpe8Xge", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "dbe42c28-6f0b-4999-8372-0b42f6fb5916", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +260, +420 +], +"parameters": { +"color": 7, +"width": 978.0454109366399, +"height": 806.6556079800943, +"content": "### Load data into database\nFetch file from Google Drive, split it into chunks and insert into Pinecone index" +}, +"typeVersion": 1 +}, +{ +"id": "43dc3736-834d-4322-8fd2-7826b0208c4b", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1520, +420 +], +"parameters": { +"color": 7, +"width": 654.1028019808174, +"height": 806.8716167324012, +"content": "### Chat with database\nEmbed the incoming chat message and use it retrieve relevant chunks from the vector store. These are passed to the model to formulate an answer " +}, +"typeVersion": 1 +}, +{ +"id": "53b18460-8ad6-425a-a01f-c2295cfddde8", +"name": "Default Data Loader", +"type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader", +"position": [ +996.8347832043557, +740 +], +"parameters": { +"options": {}, +"dataType": "binary" +}, +"typeVersion": 1 +}, +{ +"id": "e729a021-eab3-48fa-a818-457efcaeebb2", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-20, +740 +], +"parameters": { +"height": 264.61498034081166, +"content": "## Try me out\n1. In Pinecone, create an index with 1536 dimensions and select it in *both* Pinecone nodes\n2. Click 'test workflow' at the bottom of the canvas to load data into the vector store\n3. Click 'chat' at the bottom of the canvas to ask questions about the data" +}, +"typeVersion": 1 +}, +{ +"id": "3e17c89c-620d-4892-b944-d792e48e3772", +"name": "Question and Answer Chain", +"type": "@n8n/n8n-nodes-langchain.chainRetrievalQa", +"position": [ +1560, +521 +], +"parameters": {}, +"typeVersion": 1.2 +}, +{ +"id": "516507f9-d0d9-4975-85d0-a7852ee41518", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +1560, +741 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "JCgD7807AQpe8Xge", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "8b0a5d26-a60a-40ab-8200-72f542532096", +"name": "Embeddings OpenAI2", +"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi", +"position": [ +1700, +1081 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "JCgD7807AQpe8Xge", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "07f61d20-cf50-48e8-9d34-92244af436cb", +"name": "Vector Store Retriever", +"type": "@n8n/n8n-nodes-langchain.retrieverVectorStore", +"position": [ +1760, +741 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "0777de17-99a0-499a-b71f-245d5f76642e", +"name": "Read Pinecone Vector Store", +"type": "@n8n/n8n-nodes-langchain.vectorStorePinecone", +"position": [ +1700, +921 +], +"parameters": { +"options": {}, +"pineconeIndex": { +"__rl": true, +"mode": "list", +"value": "test-index", +"cachedResultName": "test-index" +} +}, +"credentials": { +"pineconeApi": { +"id": "Pp5aPt4JWBkDOGqZ", +"name": "PineconeApi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "cc5e6897-9d0b-4352-a882-5dc23104bf97", +"name": "Insert into Pinecone vector store", +"type": "@n8n/n8n-nodes-langchain.vectorStorePinecone", +"position": [ +856.8347832043557, +520 +], +"parameters": { +"mode": "insert", +"options": { +"clearNamespace": true +}, +"pineconeIndex": { +"__rl": true, +"mode": "list", +"value": "test-index", +"cachedResultName": "test-index" +} +}, +"credentials": { +"pineconeApi": { +"id": "Pp5aPt4JWBkDOGqZ", +"name": "PineconeApi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "c358aa73-b60f-453f-a3ef-539faa98c9b5", +"name": "When clicking 'Chat' button below", +"type": "@n8n/n8n-nodes-langchain.chatTrigger", +"position": [ +1360, +521 +], +"webhookId": "e259b6fe-b2a9-4dbc-98a4-9a160e7ac10c", +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "d35db9e1-4efc-4980-9814-55fbe65e08fd", +"name": "When clicking 'Test Workflow' button", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +76.83478320435574, +520 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "4c04f576-e834-467d-98b4-38a2d501d82f", +"name": "Set Google Drive file URL", +"type": "n8n-nodes-base.set", +"position": [ +296, +520 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "50025ff5-1b53-475f-b150-2aafef1c4c21", +"name": "file_url", +"type": "string", +"value": "https://drive.google.com/file/d/11Koq9q53nkk0F5Y8eZgaWJUVR03I4-MM/view" +} +] +} +}, +"typeVersion": 3.3 +} +], +"pinData": {}, +"connections": { +"Google Drive": { +"main": [ +[ +{ +"node": "Insert into Pinecone vector store", +"type": "main", +"index": 0 +} +] +] +}, +"Embeddings OpenAI": { +"ai_embedding": [ +[ +{ +"node": "Insert into Pinecone vector store", +"type": "ai_embedding", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Question and Answer Chain", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Embeddings OpenAI2": { +"ai_embedding": [ +[ +{ +"node": "Read Pinecone Vector Store", +"type": "ai_embedding", +"index": 0 +} +] +] +}, +"Default Data Loader": { +"ai_document": [ +[ +{ +"node": "Insert into Pinecone vector store", +"type": "ai_document", +"index": 0 +} +] +] +}, +"Vector Store Retriever": { +"ai_retriever": [ +[ +{ +"node": "Question and Answer Chain", +"type": "ai_retriever", +"index": 0 +} +] +] +}, +"Set Google Drive file URL": { +"main": [ +[ +{ +"node": "Google Drive", +"type": "main", +"index": 0 +} +] +] +}, +"Read Pinecone Vector Store": { +"ai_vectorStore": [ +[ +{ +"node": "Vector Store Retriever", +"type": "ai_vectorStore", +"index": 0 +} +] +] +}, +"Recursive Character Text Splitter": { +"ai_textSplitter": [ +[ +{ +"node": "Default Data Loader", +"type": "ai_textSplitter", +"index": 0 +} +] +] +}, +"When clicking 'Chat' button below": { +"main": [ +[ +{ +"node": "Question and Answer Chain", +"type": "main", +"index": 0 +} +] +] +}, +"When clicking 'Test Workflow' button": { +"main": [ +[ +{ +"node": "Set Google Drive file URL", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Author and Publish Blog Posts From Google Sheets.txt b/Author and Publish Blog Posts From Google Sheets.txt new file mode 100644 index 0000000..f5b8789 --- /dev/null +++ b/Author and Publish Blog Posts From Google Sheets.txt @@ -0,0 +1,1622 @@ +{ +"id": "b0KRVIuuUxE5afHo", +"meta": { +"instanceId": "98bf0d6aef1dd8b7a752798121440fb171bf7686b95727fd617f43452393daa3", +"templateCredsSetupCompleted": true +}, +"name": "Blog Automation TEMPLATE", +"tags": [ +{ +"id": "uumvgGHY5e6zEL7V", +"name": "Published Template", +"createdAt": "2025-02-10T11:18:10.923Z", +"updatedAt": "2025-02-10T11:18:10.923Z" +} +], +"nodes": [ +{ +"id": "20e00146-6bda-4a8a-9544-bf7e5fd4e12e", +"name": "Settings", +"type": "n8n-nodes-base.set", +"position": [ +-420, +-160 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "528b371f-0fba-4be1-9801-0502652da23e", +"name": "urlSpreadsheet", +"type": "string", +"value": "https://docs.google.com/spreadsheets/d/1Kg1-U6mJF4bahH1jCw8kT48MiKz1UMC5n-9q77BHM3Q/edit?gid=0#gid=0" +}, +{ +"id": "1be018c7-51fe-4ea2-967d-ce47a2e8795c", +"name": "urlWordpress", +"type": "string", +"value": "SUBDOMAIN.wordpress.com" +}, +{ +"id": "95377f4f-184b-46a7-94c7-b2313c314cb2", +"name": "wordpressUsername", +"type": "string", +"value": "YourUserName" +}, +{ +"id": "fdc99dc6-d9b0-4d2f-b770-1d8b6b360cad", +"name": "wordpressApplicationPassword", +"type": "string", +"value": "y0ur app1 p4ss w0rd" +}, +{ +"id": "517cb9ff-24fc-41d6-8bcc-253078f56356", +"name": "sheetSchedule", +"type": "string", +"value": "=Schedule" +}, +{ +"id": "584e11da-546b-4472-8674-33ca7e8f4f30", +"name": "sheetConfig", +"type": "string", +"value": "Config" +}, +{ +"id": "ba38cb1e-fd97-4aed-9147-1946c318ddab", +"name": "actionPublish", +"type": "string", +"value": "publish" +}, +{ +"id": "678394b5-20af-4718-9249-4ff6a3c77018", +"name": "actionUpdate", +"type": "string", +"value": "" +}, +{ +"id": "f375b2fa-8772-4313-9d6b-a104edd918b3", +"name": "sheetLog", +"type": "string", +"value": "Log" +}, +{ +"id": "3d7f9677-c753-4126-b33a-d78ef701771f", +"name": "", +"type": "string", +"value": "" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "35731842-9215-43df-9009-9b130d663237", +"name": "ScheduleTrigger", +"type": "n8n-nodes-base.scheduleTrigger", +"position": [ +-620, +-280 +], +"parameters": { +"rule": { +"interval": [ +{ +"field": "hours" +} +] +} +}, +"typeVersion": 1.2 +}, +{ +"id": "4c284d44-ac46-4cdf-9dcb-727b464269a0", +"name": "ManualTrigger", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +-620, +-100 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "b63e7345-67d0-4761-8c1a-49275f34e88d", +"name": "Schedule", +"type": "n8n-nodes-base.googleSheets", +"position": [ +-220, +-80 +], +"parameters": { +"options": {}, +"sheetName": { +"__rl": true, +"mode": "name", +"value": "={{ $('Settings').item.json.sheetSchedule }}" +}, +"documentId": { +"__rl": true, +"mode": "url", +"value": "={{ $('Settings').item.json.urlSpreadsheet }}" +} +}, +"credentials": { +"googleSheetsOAuth2Api": { +"id": "XeXufn5uZvHp3lcX", +"name": "Google Sheets account 2" +} +}, +"notesInFlow": true, +"typeVersion": 4.5 +}, +{ +"id": "5fed06a3-3188-4aed-8040-04e245b74e20", +"name": "Config", +"type": "n8n-nodes-base.code", +"position": [ +40, +-220 +], +"parameters": { +"jsCode": "let a = $(\"fetchConfig\").all();\nlet params = {};\na.forEach(p => params[p.json.Key] = p.json.Value);\n\nreturn params;\n" +}, +"typeVersion": 2 +}, +{ +"id": "685490c8-6b45-40c2-b4db-e97a81c4be8e", +"name": "fetchConfig", +"type": "n8n-nodes-base.googleSheets", +"position": [ +-220, +-220 +], +"parameters": { +"options": {}, +"sheetName": { +"__rl": true, +"mode": "name", +"value": "={{ $('Settings').item.json.sheetConfig }}" +}, +"documentId": { +"__rl": true, +"mode": "url", +"value": "={{ $('Settings').item.json.urlSpreadsheet }}" +} +}, +"credentials": { +"googleSheetsOAuth2Api": { +"id": "XeXufn5uZvHp3lcX", +"name": "Google Sheets account 2" +} +}, +"notesInFlow": true, +"typeVersion": 4.5 +}, +{ +"id": "52a39db8-f9cc-44bb-9c3e-a9abf5821a04", +"name": "AgentLLM", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +-400, +440 +], +"parameters": { +"model": "={{ $json.model }}", +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "66JEQJ5kJel1P9t3", +"name": "OpenRouter" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "6a311ac4-032b-42da-b06e-c916209d2843", +"name": "IfScheduledNow", +"type": "n8n-nodes-base.if", +"position": [ +-620, +780 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "loose" +}, +"combinator": "and", +"conditions": [ +{ +"id": "bb707069-b372-4bbd-8ba5-b7f6b492ab9d", +"operator": { +"type": "number", +"operation": "gte" +}, +"leftValue": "={{ DateTime.now().ts }}", +"rightValue": "={{ DateTime.fromFormat($json.row.Scheduled, \"yyyy-MM-dd HH:mm:ss\").ts }}" +} +] +}, +"looseTypeValidation": true +}, +"typeVersion": 2.2 +}, +{ +"id": "845e419b-15ad-4548-86c5-44bda0433b71", +"name": "PreparedData", +"type": "n8n-nodes-base.code", +"position": [ +40, +-80 +], +"parameters": { +"mode": "runOnceForEachItem", +"jsCode": "function replacePlaceholders(text, row, config) {\n function checkProp(prop, lookup) {\n // console.log('checkProp:' + prop);\n if (!lookup.hasOwnProperty(prop)) return false;\n let value = lookup[prop];\n if (typeof(value) == 'string') {\n value = value.trim();\n if (value == '') return false;\n }\n // console.log('checkProp found:', value)\n return value;\n }\n function replaceMatch(fullMatch, prop) { \n prop = prop.trim();\n // Return the corresponding value\n return checkProp(prop, row)\n || checkProp(prop, config)\n || checkProp(prop + checkProp('Context', row), config)\n || `[could not find \"${ prop }]\"`;\n }\n\n if (typeof(text) != 'string') return '';\n\n // Regex to capture {{ ... }}\n const pattern = /\\{\\{\\s*([^}]+)\\s*\\}\\}/g\n const result = text.replace(pattern, replaceMatch);\n return result.trim();\n}\n\nconst row = $json;\nconst settings = $(\"Settings\").first().json;\nconst config = $(\"Config\").first().json;\nconst prompt_key = 'prompt_' + row.Action;\nconst prompt = replacePlaceholders(config[prompt_key], row, config);\nconst model_key = prompt_key + '_model';\nconst model = replacePlaceholders(config[model_key], row, config);\nconst outputFormat = config[prompt_key + '_outputFormat'];\nconst takeAction = row.Action != row.Status;\nconst action = row.Action\n\n// console.log('prompt', prompt);\n\n// console.log(prompt);\nreturn { takeAction, action, model_key, model, prompt_key, prompt, outputFormat, row, config, settings }" +}, +"typeVersion": 2 +}, +{ +"id": "db294805-df67-4266-919f-94fb0f32c593", +"name": "RecombinedDataRow", +"type": "n8n-nodes-base.code", +"position": [ +40, +280 +], +"parameters": { +"mode": "runOnceForEachItem", +"jsCode": "/**\n * Attempts to parse the \"text\" property in a JSON object\n * that may contain malformed or incorrectly escaped JSON.\n *\n * @param {Object} raw - A string to parse.\n * @returns {Object|null} The parsed JSON object if successful, or null if all attempts fail.\n */\nfunction parseTextAsJson(raw) {\n // 1) First, try a direct parse.\n try {\n return JSON.parse(raw);\n } catch (e) {\n // Continue to next strategy\n }\n\n // Common \"fix-up\" strategies:\n // Strategy A: Attempt to remove over-escaped quotes like `\\\\\"` -> `\"`\n try {\n const fixedA = raw.replace(/\\\\\"/g, '\"');\n return JSON.parse(fixedA);\n } catch (e) {\n // Continue\n }\n\n // Strategy B: Remove escaped newlines, tabs, carriage returns if they’re suspected\n try {\n const fixedB = raw\n .replace(/\\\\n/g, ' ')\n .replace(/\\\\r/g, ' ')\n .replace(/\\\\t/g, ' ');\n return JSON.parse(fixedB);\n } catch (e) {\n // Continue\n }\n\n // Strategy C: Replace single quotes with double quotes (useful if the JSON was incorrectly quoted).\n // NOTE: This is a very rough fix. If your data legitimately includes single quotes you may need\n // a more nuanced approach.\n try {\n const fixedC = raw.replace(/'/g, '\"');\n return JSON.parse(fixedC);\n } catch (e) {\n // Continue\n }\n\n // Strategy D: Combine strategies or chain them if needed:\n // For example, single-quote fix plus removing new lines, etc.\n try {\n let fixedD = raw.replace(/\\\\\"/g, '\"');\n fixedD = fixedD.replace(/\\\\n|\\\\r|\\\\t/g, ' ');\n fixedD = fixedD.replace(/'/g, '\"');\n return JSON.parse(fixedD);\n } catch (e) {\n // If all attempts fail, log or handle the error as needed\n console.error('Could not parse \"text\" property as JSON.', e);\n return { 'Fulltext': raw };\n }\n}\n\nfunction isolateCurlySubstring(str) {\n // This pattern greedily matches everything from the first '{' to the last '}'.\n const match = str.match(/\\{[\\s\\S]*\\}/);\n \n // If a match is found, return it; otherwise return the entire string.\n return match ? match[0] : str;\n}\n\nfunction fixJsonSyntax(str) {\n str = str.replace('\\\"', '\"');\n str = str\n .split(/(\"[^\"]*\"|'[^']*')/)\n .map((part, i) => i % 2 ? part : part.replace(/\\n/g, \" \"))\n .join(\"\");\n return str;\n}\n\nfunction normalizeLLMOutput(param, iteration = 3) {\n // If it's not an object or it's null or an array, just return it as is.\n // (In some workflows, you might decide to throw an error or handle differently.)\n if (!iteration || typeof param !== 'object' || param === null || Array.isArray(param)) {\n return param;\n }\n\n // Get the object's own property keys\n const keys = Object.keys(param);\n\n // If there's more than one property, we assume it's already the complex object we want.\n if (keys.length > 1) {\n // console.log('keys > 1 → return param', param);\n return param;\n }\n\n // If there are no properties, just return it (though this is likely an empty object).\n if (keys.length === 0) {\n return param;\n }\n\n // If there's exactly one property, it might be a JSON-string that we need to parse.\n const singleKey = keys[0];\n const value = param[singleKey];\n // If that single property is a string, fix it and try to parse it as JSON.\n if (typeof value === 'string') {\n try {\n return parseTextAsJson(isolateCurlySubstring(value));\n } catch (e) {\n console.log('value is string → parse failed with error:', e.toString(), '→ return param:', param, 'value:', value);\n // Parsing failed; perhaps it's just a plain string or invalid JSON, so return as is.\n return param;\n }\n }\n\n // Otherwise, repeat this process itratively.\n return normalizeLLMOutput(value, iteration-1);\n}\n\nconst preparedData = $(\"PreparedData\").itemMatching($itemIndex).json;\nconst row = preparedData.row;\nlet gen = normalizeLLMOutput($json);\nlet fulltext = gen.hasOwnProperty('Fulltext') ? gen.Fulltext : gen;\n\n// Append any fulltext field returned to the field\n// in our data row corresponding to the current action. \ngen[row.Action] = fulltext;\n\n// Concatenate any generated fields with those already exisiting\n// in our data row (using seperator if necessary),\n// so we don't loose any pre-entered data.\nconst combined = {};\nObject.keys(gen).forEach(key => {\n const a = String(row[key] ?? \"\");\n const b = String(gen[key]);\n combined[key] = (a && b) ? (a + \"\\n---\\n\" + b) : (a || b);\n});\n\n// Add the row number and set the new status to the action just performed.\ncombined.row_number = row.row_number;\ncombined.Status = row.Action;\ncombined.model = preparedData.model;\n\nreturn combined;" +}, +"typeVersion": 2 +}, +{ +"id": "e0c993c1-678f-4236-8976-735cccb49fee", +"name": "SaveBackToSheet", +"type": "n8n-nodes-base.googleSheets", +"position": [ +480, +280 +], +"parameters": { +"columns": { +"value": {}, +"schema": [ +{ +"id": "ID", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "ID", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Topic", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Topic", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Scheduled", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Scheduled", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Status", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Status", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Action", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Action", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Context", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Context", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Idea", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Idea", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Content", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Content", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Length", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Length", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Media", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Media", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "LinksInternal", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "LinksInternal", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "LinksExternal", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "LinksExternal", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Title", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Title", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Sections", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Sections", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "MainPoints", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "MainPoints", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "GuidingPrinciple", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "GuidingPrinciple", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Metaphor", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Metaphor", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Draft", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Draft", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Final", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Final", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "internal notes", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "internal notes", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "row_number", +"type": "string", +"display": true, +"removed": false, +"readOnly": true, +"required": false, +"displayName": "row_number", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "autoMapInputData", +"matchingColumns": [ +"row_number" +], +"attemptToConvertTypes": false, +"convertFieldsToString": false +}, +"options": { +"handlingExtraData": "ignoreIt" +}, +"operation": "update", +"sheetName": { +"__rl": true, +"mode": "name", +"value": "={{ $('Settings').item.json.sheetSchedule }}" +}, +"documentId": { +"__rl": true, +"mode": "url", +"value": "={{ $('Settings').item.json.urlSpreadsheet }}" +} +}, +"credentials": { +"googleSheetsOAuth2Api": { +"id": "XeXufn5uZvHp3lcX", +"name": "Google Sheets account 2" +} +}, +"typeVersion": 4.5 +}, +{ +"id": "e0b982d9-d24e-4fd0-bc03-8642cd4c988b", +"name": "IfActionPublish", +"type": "n8n-nodes-base.if", +"position": [ +500, +-80 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "c3735d0d-da54-44e7-afe6-fdfacb6117f2", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.row.Action }}", +"rightValue": "={{ $('Settings').item.json.actionPublish }}" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "1d5c2731-61a1-434c-bdf1-294217e4ac1c", +"name": "IfTakeAction", +"type": "n8n-nodes-base.if", +"position": [ +260, +-80 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "85536861-b213-4567-9c9a-f844a28b5405", +"operator": { +"type": "boolean", +"operation": "true", +"singleValue": true +}, +"leftValue": "={{ $json.takeAction }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "aae766a4-d29e-4357-a344-74ee36a382e1", +"name": "IfPromptExists", +"type": "n8n-nodes-base.if", +"position": [ +-600, +280 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "73333657-16ed-4b0d-a81f-34add6c22a1b", +"operator": { +"type": "string", +"operation": "notEmpty", +"singleValue": true +}, +"leftValue": "={{ $json.prompt }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "5b4c4bdf-8997-4c19-8e95-8c84b725404c", +"name": "Basic LLM Chain", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +-360, +280 +], +"parameters": { +"text": "={{ $json.prompt }}", +"promptType": "define" +}, +"typeVersion": 1.5 +}, +{ +"id": "8dc422a3-6b86-4f57-8c4c-df6422f72f57", +"name": "CreatePost", +"type": "n8n-nodes-base.httpRequest", +"position": [ +-220, +780 +], +"parameters": { +"url": "=https://{{ $('Settings').item.json.urlWordpress }}/xmlrpc.php", +"body": "={{ $json.xmlRequestBody }}", +"method": "POST", +"options": {}, +"sendBody": true, +"contentType": "raw", +"sendHeaders": true, +"rawContentType": "text/xml", +"headerParameters": { +"parameters": [ +{ +"name": "Content-Type", +"value": "text/xml" +} +] +} +}, +"typeVersion": 4.2 +}, +{ +"id": "6ad42453-d56b-4bae-aaf3-eb689df998cc", +"name": "SetToPublish", +"type": "n8n-nodes-base.googleSheets", +"position": [ +700, +780 +], +"parameters": { +"columns": { +"value": { +"Status": "={{ $('Settings').item.json.actionPublish }}", +"row_number": "={{ $('PreparedData').item.json.row.row_number }}" +}, +"schema": [ +{ +"id": "ID", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "ID", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Topic", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Topic", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Scheduled", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Scheduled", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Status", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Status", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Action", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Action", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Context", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Context", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Ideas", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Ideas", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Content", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Content", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Length", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Length", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Media", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Media", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "LinksInternal", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "LinksInternal", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "LinksExternal", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "LinksExternal", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Sections", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Sections", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "MainPoints", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "MainPoints", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "GuidingPrinciple", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "GuidingPrinciple", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Metaphor", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Metaphor", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Title", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "Title", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "draft", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "draft", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "words", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "words", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "final", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "final", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "words", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "words", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "TeaserTitle", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "TeaserTitle", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "TeaserText", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "TeaserText", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "internal notes", +"type": "string", +"display": true, +"removed": false, +"required": false, +"displayName": "internal notes", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "row_number", +"type": "string", +"display": true, +"removed": false, +"readOnly": true, +"required": false, +"displayName": "row_number", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [ +"row_number" +], +"attemptToConvertTypes": false, +"convertFieldsToString": false +}, +"options": {}, +"operation": "update", +"sheetName": { +"__rl": true, +"mode": "name", +"value": "={{ $('Settings').item.json.sheetSchedule }}" +}, +"documentId": { +"__rl": true, +"mode": "url", +"value": "={{ $('Settings').item.json.urlSpreadsheet }}" +} +}, +"credentials": { +"googleSheetsOAuth2Api": { +"id": "XeXufn5uZvHp3lcX", +"name": "Google Sheets account 2" +} +}, +"typeVersion": 4.5 +}, +{ +"id": "a1af0f00-de59-48d4-93d2-9cc20e7f1c1c", +"name": "PrepareXmlPost", +"type": "n8n-nodes-base.code", +"position": [ +-380, +780 +], +"parameters": { +"mode": "runOnceForEachItem", +"jsCode": "const username = $('Settings').item.json.wordpressUsername;\nconst password = $('Settings').item.json.wordpressApplicationPassword;\nconst blogId = 0;\nconst published = 1; // 0 = draft, 1 = published\nconst title = $json.row.Title;\nconst text = $json.row.final;\n\n// Helper function to escape XML special characters\nfunction escapeXml(unsafe) {\n return unsafe.replace(/[<>&'\"]/g, (c) => {\n switch (c) {\n case '<': return '<';\n case '>': return '>';\n case '&': return '&';\n case '\\'': return ''';\n case '\"': return '"';\n default: return c;\n }\n });\n}\n\n// Your actual post text, which may contain characters needing escaping\nconst titleEscaped = escapeXml(title);\nconst textEscaped = escapeXml(text);\n\n// Build the XML payload\nconst xmlData = `\n\n wp.newPost\n \n \n ${blogId}\n \n \n ${username}\n \n \n ${password}\n \n \n \n \n \n post_title\n ${titleEscaped}\n \n \n post_content\n ${textEscaped}\n \n \n \n \n \n ${published}\n \n \n`;\n\n\n// Add a new field called 'myNewField' to the JSON of the item\n$input.item.json.xmlRequestBody = xmlData;\n\nreturn $input.item;" +}, +"typeVersion": 2 +}, +{ +"id": "00e6d2ab-6dc4-42ba-8a92-04a35d104908", +"name": "HandleXMLRPCResponse", +"type": "n8n-nodes-base.code", +"position": [ +40, +780 +], +"parameters": { +"mode": "runOnceForEachItem", +"jsCode": "// Get the XML response from the incoming JSON\nconst xmlResponse = $json.data;\n\n// Helper function to extract a value by matching a regex pattern\nfunction extractValue(pattern, xml) {\n const match = xml.match(pattern);\n return match ? match[1] : null;\n}\n\n// Check if the XML contains a fault\nif (xmlResponse.indexOf(\"\") !== -1) {\n // Extract the faultCode and faultString using regex\n // This regex matches the value inside or for faultCode\n const faultCode = extractValue(/faultCode<\\/name>\\s*<(?:int|string)>(.*?)<\\/(?:int|string)>/s, xmlResponse);\n // This regex extracts the faultString from within \n const faultString = extractValue(/faultString<\\/name>\\s*(.*?)<\\/string>/s, xmlResponse);\n return { 'errorCode': faultCode, 'error': faultString };\n} else {\n // Otherwise, assume a successful response.\n // The post ID is contained inside a tag within \n const postId = extractValue(/[\\s\\S]*?(.*?)<\\/string>/, xmlResponse);\n return { postId };\n}" +}, +"typeVersion": 2 +}, +{ +"id": "23212e92-4ad1-4a8c-8e0a-04d8d2a4511d", +"name": "PostingSuccessful", +"type": "n8n-nodes-base.if", +"position": [ +480, +780 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "815d85a1-8f91-4338-977f-503f02c53ea2", +"operator": { +"type": "string", +"operation": "exists", +"singleValue": true +}, +"leftValue": "={{ $('HandleXMLRPCResponse').item.json.postId }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "45c786f0-d795-4ed4-b6d2-f005b43e797f", +"name": "LogStatus", +"type": "n8n-nodes-base.googleSheets", +"position": [ +260, +280 +], +"parameters": { +"columns": { +"value": { +"Date": "={{ $now }}", +"Type": "=info", +"Message": "=Status {{ $json.Status }} for row {{ $('PreparedData').item.json.row.row_number }}" +}, +"schema": [ +{ +"id": "Date", +"type": "string", +"display": true, +"required": false, +"displayName": "Date", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Type", +"type": "string", +"display": true, +"required": false, +"displayName": "Type", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Message", +"type": "string", +"display": true, +"required": false, +"displayName": "Message", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [], +"attemptToConvertTypes": false, +"convertFieldsToString": false +}, +"options": {}, +"operation": "append", +"sheetName": { +"__rl": true, +"mode": "name", +"value": "={{ $('Settings').item.json.sheetLog }}" +}, +"documentId": { +"__rl": true, +"mode": "url", +"value": "={{ $('Settings').item.json.urlSpreadsheet }}" +} +}, +"credentials": { +"googleSheetsOAuth2Api": { +"id": "XeXufn5uZvHp3lcX", +"name": "Google Sheets account 2" +} +}, +"typeVersion": 4.5 +}, +{ +"id": "f58306f5-a5e9-4e44-9c5d-3810e18e6605", +"name": "LogPublished", +"type": "n8n-nodes-base.googleSheets", +"position": [ +260, +780 +], +"parameters": { +"columns": { +"value": { +"Date": "={{ $now }}", +"Type": "={{ $json.errorCode ? 'error' : 'info' }}", +"Message": "=Publishing row {{ $('PreparedData').item.json.row.row_number }}: {{ $json.postId }}{{ $json.errorCode }}{{ $json.error }}" +}, +"schema": [ +{ +"id": "Date", +"type": "string", +"display": true, +"required": false, +"displayName": "Date", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Type", +"type": "string", +"display": true, +"required": false, +"displayName": "Type", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "Message", +"type": "string", +"display": true, +"required": false, +"displayName": "Message", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [], +"attemptToConvertTypes": false, +"convertFieldsToString": false +}, +"options": {}, +"operation": "append", +"sheetName": { +"__rl": true, +"mode": "name", +"value": "={{ $('Settings').item.json.sheetLog }}" +}, +"documentId": { +"__rl": true, +"mode": "url", +"value": "={{ $('Settings').item.json.urlSpreadsheet }}" +} +}, +"credentials": { +"googleSheetsOAuth2Api": { +"id": "XeXufn5uZvHp3lcX", +"name": "Google Sheets account 2" +} +}, +"typeVersion": 4.5 +}, +{ +"id": "c227b790-e1ee-4370-9f24-a734443d1e97", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-460, +-300 +], +"parameters": { +"width": 180, +"height": 360, +"content": "## Settings" +}, +"typeVersion": 1 +}, +{ +"id": "904da209-68fd-4139-885f-bd3f25034aeb", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-440, +180 +], +"parameters": { +"color": 3, +"width": 380, +"height": 380, +"content": "## Author Blog-Post\nUsing OpenRouter to make model fully configurable for each authoring stage" +}, +"typeVersion": 1 +}, +{ +"id": "29f35bf0-6dd3-4c3c-b688-73eb46781c87", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-40, +-300 +], +"parameters": { +"color": 5, +"height": 360, +"content": "## Post-process Data\n{{ Placehoder }} replacement" +}, +"typeVersion": 1 +}, +{ +"id": "296c3257-836d-488c-b048-72261180e286", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +220, +180 +], +"parameters": { +"color": 4, +"width": 180, +"height": 380, +"content": "## Log to Sheet" +}, +"typeVersion": 1 +}, +{ +"id": "42a06803-087f-4dc4-9dd5-1f0281942a30", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +420, +180 +], +"parameters": { +"color": 6, +"width": 420, +"height": 380, +"content": "## Save Result To Sheet" +}, +"typeVersion": 1 +}, +{ +"id": "7a6393e9-ae81-4b9b-856b-7be18f783cf4", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-440, +620 +], +"parameters": { +"color": 3, +"width": 380, +"height": 380, +"content": "## Publish Blog-Post\nUse a generic XMLHttpRequest with subsequent response handling, since the Wordpress node did not work at all." +}, +"typeVersion": 1 +}, +{ +"id": "2d154bd4-c3bc-4137-90ce-7885bac77c71", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-40, +180 +], +"parameters": { +"color": 5, +"height": 380, +"content": "## Post-process Data\nNormalize and re-merge output data structure. " +}, +"typeVersion": 1 +}, +{ +"id": "83834b00-a647-403f-b88a-4c38d9750eb0", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-40, +620 +], +"parameters": { +"color": 5, +"height": 380, +"content": "## Post-process Data\nExtract post id or error message from response." +}, +"typeVersion": 1 +}, +{ +"id": "e7494d0b-b796-437e-b977-a5350b1a8dc5", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +220, +620 +], +"parameters": { +"color": 4, +"width": 180, +"height": 380, +"content": "## Log to Sheet" +}, +"typeVersion": 1 +}, +{ +"id": "1d036f6a-c6e4-428d-b0ce-1e710eb7d90c", +"name": "Sticky Note9", +"type": "n8n-nodes-base.stickyNote", +"position": [ +420, +620 +], +"parameters": { +"color": 6, +"width": 420, +"height": 380, +"content": "## Save Status To Sheet" +}, +"typeVersion": 1 +}, +{ +"id": "105e0743-b4e8-47d7-a4bf-3939df43a43c", +"name": "Sticky Note10", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-640, +160 +], +"parameters": { +"color": 7, +"width": 1500, +"height": 420, +"content": "## Authoring\n## Stage" +}, +"typeVersion": 1 +}, +{ +"id": "80fefb90-35b2-4f0b-b4d5-1cca8519361d", +"name": "Sticky Note11", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-640, +600 +], +"parameters": { +"color": 7, +"width": 1500, +"height": 420, +"content": "## Publishing\n## Stage" +}, +"typeVersion": 1 +}, +{ +"id": "99b0a7b7-6513-47b0-af16-ee66d37dd821", +"name": "Sticky Note12", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-260, +-300 +], +"parameters": { +"width": 200, +"height": 360, +"content": "## Config & Data" +}, +"typeVersion": 1 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "7005e556-a7ae-484c-af71-57c75abd3e17", +"connections": { +"Config": { +"main": [ +[] +] +}, +"AgentLLM": { +"ai_languageModel": [ +[ +{ +"node": "Basic LLM Chain", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Schedule": { +"main": [ +[ +{ +"node": "PreparedData", +"type": "main", +"index": 0 +} +] +] +}, +"Settings": { +"main": [ +[ +{ +"node": "fetchConfig", +"type": "main", +"index": 0 +}, +{ +"node": "Schedule", +"type": "main", +"index": 0 +} +] +] +}, +"LogStatus": { +"main": [ +[ +{ +"node": "SaveBackToSheet", +"type": "main", +"index": 0 +} +] +] +}, +"CreatePost": { +"main": [ +[ +{ +"node": "HandleXMLRPCResponse", +"type": "main", +"index": 0 +} +] +] +}, +"fetchConfig": { +"main": [ +[ +{ +"node": "Config", +"type": "main", +"index": 0 +} +] +] +}, +"IfTakeAction": { +"main": [ +[ +{ +"node": "IfActionPublish", +"type": "main", +"index": 0 +} +] +] +}, +"LogPublished": { +"main": [ +[ +{ +"node": "PostingSuccessful", +"type": "main", +"index": 0 +} +] +] +}, +"PreparedData": { +"main": [ +[ +{ +"node": "IfTakeAction", +"type": "main", +"index": 0 +} +] +] +}, +"SetToPublish": { +"main": [ +[] +] +}, +"ManualTrigger": { +"main": [ +[ +{ +"node": "Settings", +"type": "main", +"index": 0 +} +] +] +}, +"IfPromptExists": { +"main": [ +[ +{ +"node": "Basic LLM Chain", +"type": "main", +"index": 0 +} +] +] +}, +"IfScheduledNow": { +"main": [ +[ +{ +"node": "PrepareXmlPost", +"type": "main", +"index": 0 +} +] +] +}, +"PrepareXmlPost": { +"main": [ +[ +{ +"node": "CreatePost", +"type": "main", +"index": 0 +} +] +] +}, +"Basic LLM Chain": { +"main": [ +[ +{ +"node": "RecombinedDataRow", +"type": "main", +"index": 0 +} +] +] +}, +"IfActionPublish": { +"main": [ +[ +{ +"node": "IfScheduledNow", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "IfPromptExists", +"type": "main", +"index": 0 +} +] +] +}, +"SaveBackToSheet": { +"main": [ +[] +] +}, +"ScheduleTrigger": { +"main": [ +[ +{ +"node": "Settings", +"type": "main", +"index": 0 +} +] +] +}, +"PostingSuccessful": { +"main": [ +[ +{ +"node": "SetToPublish", +"type": "main", +"index": 0 +} +] +] +}, +"RecombinedDataRow": { +"main": [ +[ +{ +"node": "LogStatus", +"type": "main", +"index": 0 +} +] +] +}, +"HandleXMLRPCResponse": { +"main": [ +[ +{ +"node": "LogPublished", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Auto Categorise Outlook Emails with AI.txt b/Auto Categorise Outlook Emails with AI.txt new file mode 100644 index 0000000..c2bf085 --- /dev/null +++ b/Auto Categorise Outlook Emails with AI.txt @@ -0,0 +1,1271 @@ +{ +"meta": { +"instanceId": "67d4d33d8b0ad4e5e12f051d8ad92fc35893d7f48d7f801bc6da4f39967b3592" +}, +"nodes": [ +{ +"id": "30f5203b-469d-4f0c-8493-e8f08e14e4fe", +"name": "When clicking ‘Test workflow’", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +-560, +440 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "d16f59dd-f54e-487b-9aac-67f109ba9869", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1000, +-280 +], +"parameters": { +"color": 7, +"width": 727.9032097745135, +"height": 110.58643966444157, +"content": "# Auto Categorise Outlook Emails with AI\nBuilt by [Wayne Simpson](https://www.linkedin.com/in/simpsonwayne/) at [nocodecreative.io](https://nocodecreative.io)" +}, +"typeVersion": 1 +}, +{ +"id": "4e110412-8530-4322-bc5c-7f9df2b63bcb", +"name": "Sticky Note9", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1100, +-120 +], +"parameters": { +"color": 7, +"width": 506.8102696237577, +"height": 337.24177957113216, +"content": "### Watch Set Up Video 👇\n[![Auto Categorise Outlook Emails with AI](https://vdyfnvnstovfxpabhdjc.supabase.co/storage/v1/object/public/images/Thumbnails/auto-categories-emails.png?t=2024-10-11T09%3A56%3A37.961Z#full-width)](https://www.youtube.com/watch?v=EhRBkkjv_3c)\n\n" +}, +"typeVersion": 1 +}, +{ +"id": "9d79875f-148e-46ef-967a-95c07298456d", +"name": "Ollama Chat Model1", +"type": "@n8n/n8n-nodes-langchain.lmChatOllama", +"position": [ +1129, +684 +], +"parameters": { +"model": "qwen2.5:14b", +"options": { +"temperature": 0.2 +} +}, +"typeVersion": 1 +}, +{ +"id": "bcf92a71-ff5f-46a7-bec3-cedb5be2bf98", +"name": "Microsoft Outlook10", +"type": "n8n-nodes-base.microsoftOutlook", +"position": [ +3020, +8 +], +"parameters": { +"folderId": { +"__rl": true, +"mode": "list", +"value": "AQMkAGE3ZTU5MGMzLTFkNGItNGQ5Zi04MDQ1LThmNGFlMTVhYjMwYgAuAAAD8UhruVwm402lgPBG2Tj-aQEAnz-IOcWBGE2lrVuQgAF6zAAAAgFJAAAA", +"cachedResultUrl": "https://outlook.office365.com/mail/AQMkAGE3ZTU5MGMzLTFkNGItNGQ5Zi04MDQ1LThmNGFlMTVhYjMwYgAuAAAD8UhruVwm402lgPBG2Tj%2FaQEAnz%2FIOcWBGE2lrVuQgAF6zAAAAgFJAAAA", +"cachedResultName": "Junk Email" +}, +"messageId": { +"__rl": true, +"mode": "id", +"value": "={{ $('varID & Category1').item.json.id }}" +}, +"operation": "move" +}, +"typeVersion": 2 +}, +{ +"id": "100db1cb-3819-43c7-a74b-5c087ad4f2da", +"name": "Microsoft Outlook12", +"type": "n8n-nodes-base.microsoftOutlook", +"position": [ +2700, +8 +], +"parameters": { +"messageId": { +"__rl": true, +"mode": "id", +"value": "={{ $('varID & Category1').item.json.id }}" +}, +"operation": "update", +"updateFields": { +"categories": "={{ \n [$('varJSON1').first().json.output.category, $('varJSON1').first().json.output.subCategory]\n .filter(item => item && item.trim() !== \"\")\n .map(item => item.charAt(0).toUpperCase() + item.slice(1))\n}}" +} +}, +"typeVersion": 2 +}, +{ +"id": "d4969259-a3ae-473d-82ef-0c9f7933c899", +"name": "Loop Over Items1", +"type": "n8n-nodes-base.splitInBatches", +"position": [ +160, +448 +], +"parameters": { +"options": {} +}, +"typeVersion": 3 +}, +{ +"id": "524f6be3-7708-4aae-b9ab-e0ef8180a627", +"name": "Microsoft Outlook13", +"type": "n8n-nodes-base.microsoftOutlook", +"position": [ +2700, +188 +], +"parameters": { +"messageId": { +"__rl": true, +"mode": "id", +"value": "={{ $('varID & Category1').item.json.id }}" +}, +"operation": "update", +"updateFields": { +"categories": "={{ \n [$('varJSON1').first().json.output.category, $('varJSON1').first().json.output.subCategory]\n .filter(item => item && item.trim() !== \"\")\n .map(item => item.charAt(0).toUpperCase() + item.slice(1))\n}}" +} +}, +"typeVersion": 2 +}, +{ +"id": "72cb54f3-4e4e-4ad2-8845-11a38fc29f1a", +"name": "Microsoft Outlook15", +"type": "n8n-nodes-base.microsoftOutlook", +"position": [ +3020, +188 +], +"parameters": { +"folderId": { +"__rl": true, +"mode": "list", +"value": "AQMkAGE3ZTU5MGMzLTFkNGItNGQ5Zi04MDQ1LThmNGFlMTVhYjMwYgAuAAAD8UhruVwm402lgPBG2Tj-aQEAnz-IOcWBGE2lrVuQgAF6zAADLJmrBwAAAA==", +"cachedResultUrl": "https://outlook.office365.com/mail/AQMkAGE3ZTU5MGMzLTFkNGItNGQ5Zi04MDQ1LThmNGFlMTVhYjMwYgAuAAAD8UhruVwm402lgPBG2Tj%2FaQEAnz%2FIOcWBGE2lrVuQgAF6zAADLJmrBwAAAA%3D%3D", +"cachedResultName": "Receipt" +}, +"messageId": { +"__rl": true, +"mode": "id", +"value": "={{ $('varID & Category1').item.json.id }}" +}, +"operation": "move" +}, +"typeVersion": 2 +}, +{ +"id": "e4446e84-c05e-4d04-b415-7608e39024ee", +"name": "Microsoft Outlook16", +"type": "n8n-nodes-base.microsoftOutlook", +"position": [ +2709, +504 +], +"parameters": { +"messageId": { +"__rl": true, +"mode": "id", +"value": "={{ $('varID & Category1').item.json.id }}" +}, +"operation": "update", +"updateFields": { +"categories": "={{ \n [$('varJSON1').first().json.output.category, $('varJSON1').first().json.output.subCategory]\n .filter(item => item && item.trim() !== \"\")\n .map(item => item.charAt(0).toUpperCase() + item.slice(1))\n}}" +} +}, +"typeVersion": 2 +}, +{ +"id": "3ee05cfe-a528-472e-aa3d-c890fd88b6c4", +"name": "Microsoft Outlook17", +"type": "n8n-nodes-base.microsoftOutlook", +"position": [ +3020, +508 +], +"parameters": { +"folderId": { +"__rl": true, +"mode": "list", +"value": "AQMkAGE3ZTU5MGMzLTFkNGItNGQ5Zi04MDQ1LThmNGFlMTVhYjMwYgAuAAAD8UhruVwm402lgPBG2Tj-aQEAnz-IOcWBGE2lrVuQgAF6zAADLJmrCAAAAA==", +"cachedResultUrl": "https://outlook.office365.com/mail/AQMkAGE3ZTU5MGMzLTFkNGItNGQ5Zi04MDQ1LThmNGFlMTVhYjMwYgAuAAAD8UhruVwm402lgPBG2Tj%2FaQEAnz%2FIOcWBGE2lrVuQgAF6zAADLJmrCAAAAA%3D%3D", +"cachedResultName": "Community" +}, +"messageId": { +"__rl": true, +"mode": "id", +"value": "={{ $('varID & Category1').item.json.id }}" +}, +"operation": "move" +}, +"typeVersion": 2 +}, +{ +"id": "2fcecd9e-95cc-489a-b874-699c54518e44", +"name": "Microsoft Outlook18", +"type": "n8n-nodes-base.microsoftOutlook", +"position": [ +2709, +344 +], +"parameters": { +"messageId": { +"__rl": true, +"mode": "id", +"value": "={{ $('varID & Category1').item.json.id }}" +}, +"operation": "update", +"updateFields": { +"categories": "={{ \n [$('varJSON1').first().json.output.category, $('varJSON1').first().json.output.subCategory]\n .filter(item => item && item.trim() !== \"\")\n .map(item => item.charAt(0).toUpperCase() + item.slice(1))\n}}" +} +}, +"typeVersion": 2 +}, +{ +"id": "41a39309-1a94-461f-9308-63dd5b9a94a7", +"name": "Microsoft Outlook19", +"type": "n8n-nodes-base.microsoftOutlook", +"position": [ +3020, +348 +], +"parameters": { +"folderId": { +"__rl": true, +"mode": "list", +"value": "AQMkAGE3ZTU5MGMzLTFkNGItNGQ5Zi04MDQ1LThmNGFlMTVhYjMwYgAuAAAD8UhruVwm402lgPBG2Tj-aQEAnz-IOcWBGE2lrVuQgAF6zAADLJmrCQAAAA==", +"cachedResultUrl": "https://outlook.office365.com/mail/AQMkAGE3ZTU5MGMzLTFkNGItNGQ5Zi04MDQ1LThmNGFlMTVhYjMwYgAuAAAD8UhruVwm402lgPBG2Tj%2FaQEAnz%2FIOcWBGE2lrVuQgAF6zAADLJmrCQAAAA%3D%3D", +"cachedResultName": "SaaS" +}, +"messageId": { +"__rl": true, +"mode": "id", +"value": "={{ $('varID & Category1').item.json.id }}" +}, +"operation": "move" +}, +"typeVersion": 2 +}, +{ +"id": "ebf606f9-099c-4218-b23b-66e2487262d0", +"name": "Markdown1", +"type": "n8n-nodes-base.markdown", +"notes": "Converts the body of the email to markdown", +"position": [ +420, +468 +], +"parameters": { +"html": "={{ $('Loop Over Items1').item.json.body.content }}", +"options": {} +}, +"notesInFlow": true, +"typeVersion": 1 +}, +{ +"id": "ff447dd5-3ef6-4a02-8453-3489af8bf6b5", +"name": "varEmal1", +"type": "n8n-nodes-base.set", +"notes": "Set email fields", +"position": [ +620, +468 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "edb304e1-3e9f-4a77-918c-25646addbc53", +"name": "subject", +"type": "string", +"value": "={{ $json.subject }}" +}, +{ +"id": "57a3ef3a-2701-40d9-882f-f43a7219f148", +"name": "importance", +"type": "string", +"value": "={{ $json.importance }}" +}, +{ +"id": "d8317f4f-aa0e-4196-89af-cb016765490a", +"name": "sender", +"type": "object", +"value": "={{ $json.sender.emailAddress }}" +}, +{ +"id": "908716c8-9ff7-4bdc-a1a3-64227559635e", +"name": "from", +"type": "object", +"value": "={{ $json.from.emailAddress }}" +}, +{ +"id": "ce007329-e221-4c5a-8130-2f8e9130160f", +"name": "body", +"type": "string", +"value": "={{ $json.data\n .replace(/<[^>]*>/g, '') // Remove HTML tags\n .replace(/\\[(.*?)\\]\\((.*?)\\)/g, '') // Remove Markdown links like [text](link)\n .replace(/!\\[.*?\\]\\(.*?\\)/g, '') // Remove Markdown images like ![alt](image-link)\n .replace(/\\|/g, '') // Remove table separators \"|\"\n .replace(/-{3,}/g, '') // Remove horizontal rule \"---\"\n .replace(/\\n+/g, ' ') // Remove multiple newlines\n .replace(/([^\\w\\s.,!?@])/g, '') // Remove special characters except essential ones\n .replace(/\\s{2,}/g, ' ') // Replace multiple spaces with a single space\n .trim() // Trim leading/trailing whitespace\n}}\n" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "198524cb-c9f0-4261-8c38-7c878efe7457", +"name": "Microsoft Outlook20", +"type": "n8n-nodes-base.microsoftOutlook", +"position": [ +2700, +668 +], +"parameters": { +"messageId": { +"__rl": true, +"mode": "id", +"value": "={{ $('varID & Category1').item.json.id }}" +}, +"operation": "update", +"updateFields": { +"categories": "={{ \n [$('varJSON1').first().json.output.category, $('varJSON1').first().json.output.subCategory]\n .filter(item => item && item.trim() !== \"\")\n .map(item => item.charAt(0).toUpperCase() + item.slice(1))\n}}" +} +}, +"typeVersion": 2 +}, +{ +"id": "ec73629c-59ac-4f0e-a432-2c06934952ab", +"name": "Microsoft Outlook21", +"type": "n8n-nodes-base.microsoftOutlook", +"position": [ +2709, +1044 +], +"parameters": { +"messageId": { +"__rl": true, +"mode": "id", +"value": "={{ $('varID & Category1').item.json.id }}" +}, +"operation": "update", +"updateFields": { +"categories": "={{ \n [$('varJSON1').first().json.output.category, $('varJSON1').first().json.output.subCategory]\n .filter(item => item && item.trim() !== \"\")\n .map(item => item.charAt(0).toUpperCase() + item.slice(1))\n}}" +} +}, +"typeVersion": 2 +}, +{ +"id": "0a19d15c-0cd3-4f26-9be2-4914522751fb", +"name": "Filter1", +"type": "n8n-nodes-base.filter", +"position": [ +-100, +448 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "c8cd6917-f94e-4fb7-8601-b8ed8f1aa8bf", +"operator": { +"type": "array", +"operation": "empty", +"singleValue": true +}, +"leftValue": "={{ $json.categories }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "96e6e31c-6306-44a8-a57a-2b5216636b00", +"name": "If1", +"type": "n8n-nodes-base.if", +"notes": "Checks if the email has been read", +"position": [ +3320, +668 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "f8cf2a56-cea8-4150-b7a0-048dbda20f2f", +"operator": { +"type": "boolean", +"operation": "true", +"singleValue": true +}, +"leftValue": "={{ $json.isRead }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "8a6e0118-abe3-45e2-aefc-94640348b2ec", +"name": "Microsoft Outlook22", +"type": "n8n-nodes-base.microsoftOutlook", +"position": [ +2709, +864 +], +"parameters": { +"messageId": { +"__rl": true, +"mode": "id", +"value": "={{ $('varID & Category1').item.json.id }}" +}, +"operation": "update", +"updateFields": { +"categories": "={{ \n [$('varJSON1').first().json.output.category, $('varJSON1').first().json.output.subCategory]\n .filter(item => item && item.trim() !== \"\")\n .map(item => item.charAt(0).toUpperCase() + item.slice(1))\n}}" +} +}, +"typeVersion": 2 +}, +{ +"id": "e2d8e7b5-4447-4327-9f4e-b8d52765667e", +"name": "Catch Errors1", +"type": "n8n-nodes-base.set", +"position": [ +1760, +608 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "0dc6d439-60fb-49f6-b4d5-f5cce6f030ad", +"name": "error", +"type": "string", +"value": "={{ $json }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "17f6ac43-51e4-4bee-b0d8-13deb3bf3cc9", +"name": "varJSON1", +"type": "n8n-nodes-base.set", +"onError": "continueErrorOutput", +"position": [ +1540, +468 +], +"parameters": { +"options": { +"ignoreConversionErrors": true +}, +"assignments": { +"assignments": [ +{ +"id": "0c52f57f-74eb-4385-ac6b-f3e5f4f50e73", +"name": "output", +"type": "object", +"value": "={{ $json.output.replace(/^.*?({.*}).*$/s, '$1') }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "82dd9631-a34b-4d54-be28-6f8dcc3548f0", +"name": "Sticky Note10", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-360, +220 +], +"parameters": { +"width": 411.91693012378937, +"height": 401.49417117683515, +"content": "## Outlook Business with filters\nFilters:\n```\nflag/flagStatus eq 'notFlagged' and not categories/any()\n```\n\nThese filters ensure we do not process flagged emails or email that already have a category set." +}, +"typeVersion": 1 +}, +{ +"id": "0583e196-37a5-43db-8c0a-aa624029c926", +"name": "Microsoft Outlook23", +"type": "n8n-nodes-base.microsoftOutlook", +"position": [ +-300, +448 +], +"parameters": { +"limit": 1, +"fields": [ +"flag", +"from", +"importance", +"replyTo", +"sender", +"subject", +"toRecipients", +"body", +"categories", +"isRead" +], +"output": "fields", +"options": {}, +"filtersUI": { +"values": { +"filters": { +"custom": "flag/flagStatus eq 'notFlagged' and not categories/any()", +"foldersToInclude": [ +"AQMkAGE3ZTU5MGMzLTFkNGItNGQ5Zi04MDQ1LThmNGFlMTVhYjMwYgAuAAAD8UhruVwm402lgPBG2Tj-aQEAnz-IOcWBGE2lrVuQgAF6zAAAAgEMAAAA" +] +} +} +}, +"operation": "getAll" +}, +"typeVersion": 2 +}, +{ +"id": "a9540e6b-929b-4460-8972-93e4d19cd934", +"name": "varID & Category1", +"type": "n8n-nodes-base.set", +"position": [ +900, +468 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "de2ad4f2-7381-4715-a3f4-59611e161b74", +"name": "id", +"type": "string", +"value": "={{ $('Microsoft Outlook23').item.json.id }}" +}, +{ +"id": "458c7a89-e4a3-46d0-8b38-72d87748e306", +"name": "category", +"type": "string", +"value": "\"action\", \"junk\", \"receipt\", \"SaaS\", \"community\", \"business\" or \"other\"" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "e6b3b41e-d7d3-4c9b-8189-a005c748ff18", +"name": "Sticky Note11", +"type": "n8n-nodes-base.stickyNote", +"position": [ +360, +348 +], +"parameters": { +"color": 6, +"width": 418.7820408163265, +"height": 301.40952380952365, +"content": "## Sanitise Email \nRemoves HTML and useless information in preparation for the AI Agent" +}, +"typeVersion": 1 +}, +{ +"id": "f9787a75-526c-4ef1-b0a7-0db7d890ab3f", +"name": "Sticky Note12", +"type": "n8n-nodes-base.stickyNote", +"position": [ +820, +348 +], +"parameters": { +"color": 6, +"width": 256.16108843537415, +"height": 298.37931972789124, +"content": "## Modify Categories \nEdit this to customise category selection" +}, +"typeVersion": 1 +}, +{ +"id": "50223a01-34cf-4191-9dd7-3dac02a9e945", +"name": "Sticky Note13", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1480, +328 +], +"parameters": { +"color": 5, +"width": 441.003537414966, +"height": 463.0204081632651, +"content": "## Convert to JSON\n* Ensures the Agent output to converted to JSON\n* Catches any errors and continues processing" +}, +"typeVersion": 1 +}, +{ +"id": "4580c532-96a6-46b4-8922-d79316d1cc01", +"name": "Sticky Note14", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2120, +328 +], +"parameters": { +"color": 5, +"width": 311.71482993197264, +"height": 454.93986394557805, +"content": "## Switch Categories\nEnsure your categories match the **varID & Category** Edit Fields node" +}, +"typeVersion": 1 +}, +{ +"id": "b51a7c34-2a5e-4670-81a4-d1582711c69a", +"name": "Sticky Note15", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2629, +-76 +], +"parameters": { +"color": 4, +"width": 251.3480889735252, +"height": 1289.0156245602684, +"content": "## Set Categories\n" +}, +"typeVersion": 1 +}, +{ +"id": "3a7ede7b-539b-49d2-8803-153ca6c9eb69", +"name": "Sticky Note16", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2949, +-76 +], +"parameters": { +"color": 4, +"width": 251.3480889735252, +"height": 770.995811762121, +"content": "## Move to Folders\n" +}, +"typeVersion": 1 +}, +{ +"id": "ee9a9d78-8c07-470a-9d1b-ceddfc8875ca", +"name": "Sticky Note17", +"type": "n8n-nodes-base.stickyNote", +"position": [ +3260, +553 +], +"parameters": { +"color": 4, +"height": 293.65527013262994, +"content": "## Check if email has been read\n\n" +}, +"typeVersion": 1 +}, +{ +"id": "c75b9d38-79a7-4be2-a90b-a99da1bbd745", +"name": "Microsoft Outlook Move Message1", +"type": "n8n-nodes-base.microsoftOutlook", +"position": [ +3609, +604 +], +"parameters": { +"folderId": { +"__rl": true, +"mode": "list", +"value": "AQMkAGE3ZTU5MGMzLTFkNGItNGQ5Zi04MDQ1LThmNGFlMTVhYjMwYgAuAAAD8UhruVwm402lgPBG2Tj-aQEAnz-IOcWBGE2lrVuQgAF6zAADLJmrCwAAAA==", +"cachedResultUrl": "https://outlook.office365.com/mail/AQMkAGE3ZTU5MGMzLTFkNGItNGQ5Zi04MDQ1LThmNGFlMTVhYjMwYgAuAAAD8UhruVwm402lgPBG2Tj%2FaQEAnz%2FIOcWBGE2lrVuQgAF6zAADLJmrCwAAAA%3D%3D", +"cachedResultName": "Actioned" +}, +"messageId": { +"__rl": true, +"mode": "id", +"value": "={{ $('varID & Category1').item.json.id }}" +}, +"operation": "move" +}, +"typeVersion": 2 +}, +{ +"id": "85ff0348-16dc-46e6-bf70-48a10fe0ded8", +"name": "AI Agent1", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +1160, +468 +], +"parameters": { +"text": "=Categorise the following email\n\n{{ $('varEmal1').first().json.toJsonString() }}\n\n\nEnsure your final output is valid JSON with no additional text or token in the following format:\n\n{\n \"subject\": \"SUBJECT_LINE\",1\n \"category\": \"CATEGORY\",\n \"subCategory\": \"SUBCATEGORY\", //use sparingly\n \"analysis\": \"ANALYSIS_REASONING\"\n}\n\nRemember you can only use ONE of the following categories {{ $json.category }}. No other categories can be used. Use the subcategory for additional context, for example, if a SaaS email requires action, or if a business email requires action. Do not create any additional subcategories, you can only use ONE of the following {{ $json.category }}.", +"options": { +"systemMessage": "=You're an AI assistant for a freelance developer, categorizing emails as {{ $json.category }}. Email info is in tags.\n\nCategorization priority:\n\nAction: Needs response or action (includes some SaaS emails), avoid sales email but include enquires.\nJunk: Ads, sales, newsletters, promotions, daily digests, (emojis often indicate junk), phishing, scams, discounts etc.\nReceipt: Any purchase confirmation.\nSaaS: Account/security updates, unless action required, generic SaaS information, usually from a non-personal email address.\nCommunity: Updates, events, forums, everything related to \"community\".\nBusiness: Any communication related to freelance work, usually from a humans email address\nOther: Doesn't fit into any other category.\n\nKey points:\n\nSaaS emails needing action are \"SaaS\" and subcategory \"action\".\nAnalyze the subject, body, email addresses and other data.\nLook for specific keywords and phrases for each category.\nEmail can have 2 categories, primary and sub, for example, \"action\" and \"SaaS\" or \"action\" and \"business\".\nEmails from business development executives are often junk.\n\n\nOutput in valid JSON format:\n{\n\"subject\": \"SUBJECT_LINE\",\n\"category\": \"PRIMARY CATEGORY\",\n\"subCategory\": \"SUBCATEGORY\", //use sparingly\n\"analysis\": \"Brief 1-2 sentence explanation of category choice\"\n}\nNo additional text or tokens outside the JSON.\n\nYou may only use the following categories and subcategories, do not create any more categories or subcategories: {{ $json.category }}" +}, +"promptType": "define", +"hasOutputParser": true +}, +"typeVersion": 1.6 +}, +{ +"id": "93e7be79-9035-4b58-9a83-b9182a0515f8", +"name": "Merge1", +"type": "n8n-nodes-base.merge", +"position": [ +3989, +564 +], +"parameters": { +"numberInputs": 7 +}, +"typeVersion": 3 +}, +{ +"id": "cbaeaed1-cb09-4614-93f1-3fe349cd0e4e", +"name": "Switch1", +"type": "n8n-nodes-base.switch", +"position": [ +2220, +488 +], +"parameters": { +"rules": { +"values": [ +{ +"outputKey": "junk", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": false, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"operator": { +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.output.category }}", +"rightValue": "junk" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "receipt", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": false, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "0c61c7a8-e8b4-49c5-a96c-402d5eae7089", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.output.category }}", +"rightValue": "receipt" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "SaaS", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": false, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "703f65c8-cf4a-47fe-ad1a-a5f6e0412ae7", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.output.category }}", +"rightValue": "SaaS" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "community", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": false, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "b074d5cd-9215-40df-8877-5df904edc000", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.output.category }}", +"rightValue": "community" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "action", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": false, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "bece338a-e0c5-43b5-b8cc-41229a374213", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.output.category }}", +"rightValue": "action" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "business", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": false, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "d6c9751f-0ffa-4041-a579-6957bb9c9296", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.output.category }}", +"rightValue": "business" +} +] +}, +"renameOutput": true +} +] +}, +"options": { +"ignoreCase": true, +"fallbackOutput": "extra" +} +}, +"typeVersion": 3.2 +} +], +"pinData": {}, +"connections": { +"If1": { +"main": [ +[ +{ +"node": "Microsoft Outlook Move Message1", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Merge1", +"type": "main", +"index": 5 +} +] +] +}, +"Merge1": { +"main": [ +[ +{ +"node": "Loop Over Items1", +"type": "main", +"index": 0 +} +] +] +}, +"Filter1": { +"main": [ +[ +{ +"node": "Loop Over Items1", +"type": "main", +"index": 0 +} +] +] +}, +"Switch1": { +"main": [ +[ +{ +"node": "Microsoft Outlook12", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Microsoft Outlook13", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Microsoft Outlook18", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Microsoft Outlook16", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Microsoft Outlook20", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Microsoft Outlook22", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Microsoft Outlook21", +"type": "main", +"index": 0 +} +] +] +}, +"varEmal1": { +"main": [ +[ +{ +"node": "varID & Category1", +"type": "main", +"index": 0 +} +] +] +}, +"varJSON1": { +"main": [ +[ +{ +"node": "Switch1", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Catch Errors1", +"type": "main", +"index": 0 +} +] +] +}, +"AI Agent1": { +"main": [ +[ +{ +"node": "varJSON1", +"type": "main", +"index": 0 +} +] +] +}, +"Markdown1": { +"main": [ +[ +{ +"node": "varEmal1", +"type": "main", +"index": 0 +} +] +] +}, +"Catch Errors1": { +"main": [ +[ +{ +"node": "Loop Over Items1", +"type": "main", +"index": 0 +} +] +] +}, +"Loop Over Items1": { +"main": [ +null, +[ +{ +"node": "Markdown1", +"type": "main", +"index": 0 +} +] +] +}, +"varID & Category1": { +"main": [ +[ +{ +"node": "AI Agent1", +"type": "main", +"index": 0 +} +] +] +}, +"Ollama Chat Model1": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent1", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Microsoft Outlook10": { +"main": [ +[ +{ +"node": "Merge1", +"type": "main", +"index": 0 +} +] +] +}, +"Microsoft Outlook12": { +"main": [ +[ +{ +"node": "Microsoft Outlook10", +"type": "main", +"index": 0 +} +] +] +}, +"Microsoft Outlook13": { +"main": [ +[ +{ +"node": "Microsoft Outlook15", +"type": "main", +"index": 0 +} +] +] +}, +"Microsoft Outlook15": { +"main": [ +[ +{ +"node": "Merge1", +"type": "main", +"index": 1 +} +] +] +}, +"Microsoft Outlook16": { +"main": [ +[ +{ +"node": "Microsoft Outlook17", +"type": "main", +"index": 0 +} +] +] +}, +"Microsoft Outlook17": { +"main": [ +[ +{ +"node": "Merge1", +"type": "main", +"index": 3 +} +] +] +}, +"Microsoft Outlook18": { +"main": [ +[ +{ +"node": "Microsoft Outlook19", +"type": "main", +"index": 0 +} +] +] +}, +"Microsoft Outlook19": { +"main": [ +[ +{ +"node": "Merge1", +"type": "main", +"index": 2 +} +] +] +}, +"Microsoft Outlook20": { +"main": [ +[ +{ +"node": "If1", +"type": "main", +"index": 0 +} +] +] +}, +"Microsoft Outlook21": { +"main": [ +[ +{ +"node": "Merge1", +"type": "main", +"index": 6 +} +] +] +}, +"Microsoft Outlook22": { +"main": [ +[ +{ +"node": "If1", +"type": "main", +"index": 0 +} +] +] +}, +"Microsoft Outlook23": { +"main": [ +[ +{ +"node": "Filter1", +"type": "main", +"index": 0 +} +] +] +}, +"Microsoft Outlook Move Message1": { +"main": [ +[ +{ +"node": "Merge1", +"type": "main", +"index": 4 +} +] +] +}, +"When clicking ‘Test workflow’": { +"main": [ +[ +{ +"node": "Microsoft Outlook23", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Auto-Categorize blog posts in wordpress using A.I..txt b/Auto-Categorize blog posts in wordpress using A.I..txt new file mode 100644 index 0000000..426ba65 --- /dev/null +++ b/Auto-Categorize blog posts in wordpress using A.I..txt @@ -0,0 +1,214 @@ +{ +"id": "caaf1WFANPKAikiH", +"meta": { +"instanceId": "558d88703fb65b2d0e44613bc35916258b0f0bf983c5d4730c00c424b77ca36a", +"templateCredsSetupCompleted": true +}, +"name": "Auto categorize wordpress template", +"tags": [], +"nodes": [ +{ +"id": "2017403c-7496-48f8-a487-8a017c7adfe3", +"name": "When clicking ‘Test workflow’", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +680, +320 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "82ff288f-4234-4192-9046-33e5ffee5264", +"name": "Wordpress", +"type": "n8n-nodes-base.wordpress", +"position": [ +1500, +320 +], +"parameters": { +"postId": "={{ $('Get All Wordpress Posts').item.json.id }}", +"operation": "update", +"updateFields": { +"categories": "={{ $json.output }}" +} +}, +"credentials": { +"wordpressApi": { +"id": "lGWPwxTdfPDDbFjj", +"name": "Rumjahn.com wordpress" +} +}, +"typeVersion": 1 +}, +{ +"id": "521deb22-62dd-4b5f-8b9a-aab9777821da", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +620, +-100 +], +"parameters": { +"width": 504.88636363636317, +"content": "## How to Auto-Categorize 82 Blog Posts in 2 Minutes using A.I. (No Coding Required)\n\n💡 Read the [case study here](https://rumjahn.com/how-to-use-a-i-to-categorize-wordpress-posts-and-streamline-your-content-organization-process/).\n\n📺 Watch the [youtube tutorial here](https://www.youtube.com/watch?v=IvQioioVqhw)\n\n" +}, +"typeVersion": 1 +}, +{ +"id": "4090d827-f8cd-47ef-ad4f-654ee58216f6", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +860, +180 +], +"parameters": { +"color": 3, +"width": 188.14814814814804, +"height": 327.3400673400663, +"content": "### Get wordpress posts\n\nTurn off return all if you're running into issues.\n" +}, +"typeVersion": 1 +}, +{ +"id": "71585d54-fdcc-42a5-8a0e-0fac3adc1809", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1080, +80 +], +"parameters": { +"color": 4, +"width": 315.1464152082392, +"height": 416.90235690235625, +"content": "### A.I. Categorization\n\n1. you need to set up the categories first in wordpress\n\n2. Edit the message prompt and change the categories and category numbers" +}, +"typeVersion": 1 +}, +{ +"id": "29354054-8600-4e45-99d0-6f30f779a505", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1480, +240 +], +"parameters": { +"color": 5, +"width": 171.64983164983155, +"height": 269.59595959595947, +"content": "### Update category" +}, +"typeVersion": 1 +}, +{ +"id": "d9fe6289-6b97-4830-80aa-754ac4d4b3e0", +"name": "Get All Wordpress Posts", +"type": "n8n-nodes-base.wordpress", +"position": [ +900, +320 +], +"parameters": { +"options": {}, +"operation": "getAll", +"returnAll": true +}, +"credentials": { +"wordpressApi": { +"id": "lGWPwxTdfPDDbFjj", +"name": "Rumjahn.com wordpress" +} +}, +"typeVersion": 1 +}, +{ +"id": "ed40bf13-8294-4b4e-a8b6-5749989d3420", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +1080, +540 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "XO3iT1iYT5Vod56X", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "dafeb935-532e-4067-9dfb-7e9a6bbc4e5a", +"name": "AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +1100, +320 +], +"parameters": { +"text": "=You are an expert content strategist and taxonomy specialist with extensive experience in blog categorization and content organization.\n\nI will provide you with a blog post's title. Your task is to assign ONE primary category ID from this fixed list:\n\n13 = Content Creation\n14 = Digital Marketing\n15 = AI Tools\n17 = Automation & Integration\n18 = Productivity Tools\n19 = Analytics & Strategy\n\nAnalyze the title and return only the single most relevant category ID number that best represents the main focus of the post. While a post might touch on multiple topics, select the dominant theme that would be most useful for navigation purposes.\n\n{{ $json.title.rendered }}\n\nOutput only the category number", +"options": {}, +"promptType": "define" +}, +"typeVersion": 1.7 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "2a753171-425f-4b5a-bd1b-8591ad2d142c", +"connections": { +"AI Agent": { +"main": [ +[ +{ +"node": "Wordpress", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Get All Wordpress Posts": { +"main": [ +[ +{ +"node": "AI Agent", +"type": "main", +"index": 0 +} +] +] +}, +"When clicking ‘Test workflow’": { +"main": [ +[ +{ +"node": "Get All Wordpress Posts", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/⚡AI-Powered YouTube Video Summarization & Analysis.txt b/⚡AI-Powered YouTube Video Summarization & Analysis.txt new file mode 100644 index 0000000..b86f2ce --- /dev/null +++ b/⚡AI-Powered YouTube Video Summarization & Analysis.txt @@ -0,0 +1,326 @@ +{ +"nodes": [ +{ +"id": "9320d08a-4868-4103-abdf-3f8f54a7a0a0", +"name": "Webhook", +"type": "n8n-nodes-base.webhook", +"position": [ +0, +0 +], +"webhookId": "9024e29e-9080-4cf5-9a6b-0d918468f195", +"parameters": { +"path": "ytube", +"options": {}, +"httpMethod": "POST", +"responseMode": "responseNode" +}, +"typeVersion": 2 +}, +{ +"id": "a5cc8922-8124-4269-9cfd-e891b29cc2b7", +"name": "YouTube Transcript", +"type": "n8n-nodes-youtube-transcription.youtubeTranscripter", +"position": [ +800, +0 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "ff3c0fd1-36d8-4d64-b405-0600efd4d93b", +"name": "Split Out", +"type": "n8n-nodes-base.splitOut", +"position": [ +200, +260 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "transcript" +}, +"typeVersion": 1 +}, +{ +"id": "423276e0-81bf-487a-bbdd-26e9b84fa755", +"name": "Respond to Webhook", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +1200, +140 +], +"parameters": { +"options": {} +}, +"typeVersion": 1.1 +}, +{ +"id": "27344649-8029-48ae-867b-7363d904fc59", +"name": "Telegram", +"type": "n8n-nodes-base.telegram", +"position": [ +1200, +380 +], +"parameters": { +"text": "={{ $json.title }}\n{{ $json.youtubeUrl }}", +"additionalFields": { +"parse_mode": "HTML", +"appendAttribution": false +} +}, +"typeVersion": 1.2 +}, +{ +"id": "230c0325-d22a-4070-9460-748a6fef48d5", +"name": "Get YouTube URL", +"type": "n8n-nodes-base.set", +"position": [ +200, +0 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "3ee42e4c-3cee-4934-97e7-64c96b5691ed", +"name": "youtubeUrl", +"type": "string", +"value": "={{ $json.body.youtubeUrl }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "420e90c3-9dfa-4f41-825a-9874b5ebe43a", +"name": "YouTube Video ID", +"type": "n8n-nodes-base.code", +"position": [ +400, +0 +], +"parameters": { +"jsCode": "const extractYoutubeId = (url) => {\n // Regex pattern that matches both youtu.be and youtube.com URLs\n const pattern = /(?:youtube\\.com\\/(?:[^\\/]+\\/.+\\/|(?:v|e(?:mbed)?)\\/|.*[?&]v=)|youtu\\.be\\/)([^\"&?\\/\\s]{11})/;\n const match = url.match(pattern);\n return match ? match[1] : null;\n};\n\n// Input URL from previous node\nconst youtubeUrl = items[0].json.youtubeUrl; // Adjust this based on your workflow\n\n// Process the URL and return the video ID\nreturn [{\n json: {\n videoId: extractYoutubeId(youtubeUrl)\n }\n}];\n" +}, +"typeVersion": 2 +}, +{ +"id": "a4171c3e-1ff2-40de-af7f-b3971a1ebe79", +"name": "Get YouTube Video", +"type": "n8n-nodes-base.youTube", +"position": [ +600, +0 +], +"parameters": { +"options": {}, +"videoId": "={{ $json.videoId }}", +"resource": "video", +"operation": "get" +}, +"typeVersion": 1 +}, +{ +"id": "73e6bfc5-8b62-4880-acd4-292f2f692540", +"name": "gpt-4o-mini", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +620, +440 +], +"parameters": { +"options": {} +}, +"typeVersion": 1 +}, +{ +"id": "ea14e296-b30c-46f7-b283-746822ae1af4", +"name": "Summarize & Analyze Transcript", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +600, +260 +], +"parameters": { +"text": "=Please analyze the given text and create a structured summary following these guidelines:\n\n1. Break down the content into main topics using Level 2 headers (##)\n2. Under each header:\n - List only the most essential concepts and key points\n - Use bullet points for clarity\n - Keep explanations concise\n - Preserve technical accuracy\n - Highlight key terms in bold\n3. Organize the information in this sequence:\n - Definition/Background\n - Main characteristics\n - Implementation details\n - Advantages/Disadvantages\n4. Format requirements:\n - Use markdown formatting\n - Keep bullet points simple (no nesting)\n - Bold important terms using **term**\n - Use tables for comparisons\n - Include relevant technical details\n\nPlease provide a clear, structured summary that captures the core concepts while maintaining technical accuracy.\n\nHere is the text: {{ $json.concatenated_text\n }}", +"promptType": "define" +}, +"typeVersion": 1.4 +}, +{ +"id": "90e3488f-f854-483e-9106-a5760d0c0457", +"name": "Concatenate", +"type": "n8n-nodes-base.summarize", +"position": [ +400, +260 +], +"parameters": { +"options": {}, +"fieldsToSummarize": { +"values": [ +{ +"field": "text", +"separateBy": " ", +"aggregation": "concatenate" +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "9c5c249c-5eeb-4433-ba93-ace4611f4858", +"name": "Response Object", +"type": "n8n-nodes-base.set", +"position": [ +960, +260 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "bf132004-6636-411f-9d85-0c696fda84c4", +"name": "summary", +"type": "string", +"value": "={{ $json.text }}" +}, +{ +"id": "63c8d0e3-685c-488a-9b45-363cf52479ea", +"name": "topics", +"type": "array", +"value": "=[]" +}, +{ +"id": "171f30cf-34e9-42f3-8735-814024bfde0b", +"name": "title", +"type": "string", +"value": "={{ $('Get YouTube Video').item.json.snippet.title }}" +}, +{ +"id": "7f26f5a3-e695-49d1-b1e8-9260c31f1b3d", +"name": "description", +"type": "string", +"value": "={{ $('Get YouTube Video').item.json.snippet.description }}" +}, +{ +"id": "d0594232-cb39-453c-b015-3b039c098e1f", +"name": "id", +"type": "string", +"value": "={{ $('Get YouTube Video').item.json.id }}" +}, +{ +"id": "17b6ca08-ce89-4467-bd25-0d2d182f7a8b", +"name": "youtubeUrl", +"type": "string", +"value": "={{ $('Webhook').item.json.body.youtubeUrl }}" +} +] +} +}, +"typeVersion": 3.4 +} +], +"pinData": {}, +"connections": { +"Webhook": { +"main": [ +[ +{ +"node": "Get YouTube URL", +"type": "main", +"index": 0 +} +] +] +}, +"Split Out": { +"main": [ +[ +{ +"node": "Concatenate", +"type": "main", +"index": 0 +} +] +] +}, +"Concatenate": { +"main": [ +[ +{ +"node": "Summarize & Analyze Transcript", +"type": "main", +"index": 0 +} +] +] +}, +"gpt-4o-mini": { +"ai_languageModel": [ +[ +{ +"node": "Summarize & Analyze Transcript", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Get YouTube URL": { +"main": [ +[ +{ +"node": "YouTube Video ID", +"type": "main", +"index": 0 +} +] +] +}, +"Response Object": { +"main": [ +[ +{ +"node": "Respond to Webhook", +"type": "main", +"index": 0 +}, +{ +"node": "Telegram", +"type": "main", +"index": 0 +} +] +] +}, +"YouTube Video ID": { +"main": [ +[ +{ +"node": "Get YouTube Video", +"type": "main", +"index": 0 +} +] +] +}, +"Summarize & Analyze Transcript": { +"main": [ +[ +{ +"node": "Response Object", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/🔥📈🤖 AI Agent for n8n Creators Leaderboard - Find Popular Workflows.txt b/🔥📈🤖 AI Agent for n8n Creators Leaderboard - Find Popular Workflows.txt new file mode 100644 index 0000000..3e4d562 --- /dev/null +++ b/🔥📈🤖 AI Agent for n8n Creators Leaderboard - Find Popular Workflows.txt @@ -0,0 +1,1179 @@ +{ +"id": "b8a4IwiwD9SlgF42", +"meta": { +"instanceId": "31e69f7f4a77bf465b805824e303232f0227212ae922d12133a0f96ffeab4fef", +"templateCredsSetupCompleted": true +}, +"name": "🔥📈🤖 AI Agent for n8n Creators Leaderboard - Find Popular Workflows", +"tags": [], +"nodes": [ +{ +"id": "fcda047d-b609-4791-b3ae-f359d0c6a071", +"name": "stats_aggregate_creators", +"type": "n8n-nodes-base.httpRequest", +"position": [ +-1240, +1280 +], +"parameters": { +"url": "={{ $json.path }}{{ $json['creators-filename'] }}.json", +"options": {} +}, +"typeVersion": 4.2 +}, +{ +"id": "fa1f51fd-6019-4d47-b17e-8c5621e6ab4c", +"name": "stats_aggregate_workflows", +"type": "n8n-nodes-base.httpRequest", +"position": [ +-1240, +1500 +], +"parameters": { +"url": "={{ $json.path }}{{ $json['workflows-filename'] }}.json", +"options": {} +}, +"typeVersion": 4.2 +}, +{ +"id": "34c2d0d3-0474-4a69-b1a5-14c9021865cd", +"name": "Global Variables", +"type": "n8n-nodes-base.set", +"position": [ +-1660, +1480 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "4bcb91c6-d250-4cb4-8ee1-022df13550e1", +"name": "path", +"type": "string", +"value": "https://raw.githubusercontent.com/teds-tech-talks/n8n-community-leaderboard/refs/heads/main/" +}, +{ +"id": "a910a798-0bfe-41b1-a4f1-41390c7f6997", +"name": "workflows-filename", +"type": "string", +"value": "=stats_aggregate_workflows" +}, +{ +"id": "e977e816-dc1e-43ce-9393-d6488e6832ca", +"name": "creators-filename", +"type": "string", +"value": "=stats_aggregate_creators" +}, +{ +"id": "20efae68-948e-445c-ab89-7dd23149dd50", +"name": "chart-filename", +"type": "string", +"value": "=stats_aggregate_chart" +}, +{ +"id": "14233ab4-3fa4-4e26-8032-6ffe26cb601e", +"name": "datetime", +"type": "string", +"value": "={{ $now.format('yyyy-MM-dd') }}" +}, +{ +"id": "f63dc683-a430-43ec-9c25-53fa5c0a3ced", +"name": "username", +"type": "string", +"value": "={{ $json.query.username }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "7e830263-746f-4909-87aa-5e602d39fc3a", +"name": "Parse Workflow Data", +"type": "n8n-nodes-base.set", +"position": [ +-880, +1560 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "76f4b20e-519e-4d46-aeac-c6c3f98a69fd", +"name": "data", +"type": "array", +"value": "={{ $json.data }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "b112dde6-9194-451f-9c5e-b3f648d215da", +"name": "Parse Creators Data", +"type": "n8n-nodes-base.set", +"position": [ +-880, +1220 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "76f4b20e-519e-4d46-aeac-c6c3f98a69fd", +"name": "data", +"type": "array", +"value": "={{ $json.data }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "877e1988-c85c-49a8-8d56-d3954327c6f6", +"name": "Take Top 25 Creators", +"type": "n8n-nodes-base.limit", +"position": [ +-260, +1220 +], +"parameters": { +"maxItems": 25 +}, +"typeVersion": 1 +}, +{ +"id": "f05db70e-4362-40a4-bc50-6d0c30ea0cc4", +"name": "Aggregate", +"type": "n8n-nodes-base.aggregate", +"position": [ +-680, +1920 +], +"parameters": { +"options": {}, +"aggregate": "aggregateAllItemData" +}, +"typeVersion": 1 +}, +{ +"id": "1d223053-d895-4545-a9b2-6eeab6200568", +"name": "Filter By Creator Username", +"type": "n8n-nodes-base.filter", +"position": [ +-880, +1920 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "21b17fb0-1809-4dc0-b775-cf43a570aa3a", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.username }}", +"rightValue": "={{ $('Global Variables').item.json.username }}" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "c25ff9ea-1905-4bf0-ac71-5d81c25466b7", +"name": "gpt-4o-mini", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +-1960, +600 +], +"parameters": { +"model": { +"__rl": true, +"mode": "list", +"value": "gpt-4o-mini" +}, +"options": { +"temperature": 0.1 +} +}, +"credentials": { +"openAiApi": { +"id": "jEMSvKmtYfzAkhe6", +"name": "OpenAi account" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "b21c51fa-c9b3-4c88-ba7b-fe8a97a951c9", +"name": "When Executed by Another Workflow", +"type": "n8n-nodes-base.executeWorkflowTrigger", +"position": [ +-1980, +1480 +], +"parameters": { +"inputSource": "jsonExample", +"jsonExample": "{\n \"query\": \n {\n \"username\": \n \"joe\"\n }\n}" +}, +"typeVersion": 1.1 +}, +{ +"id": "d26278f5-08d8-4640-82a6-1c3615b6f06b", +"name": "When chat message received", +"type": "@n8n/n8n-nodes-langchain.chatTrigger", +"position": [ +-1980, +240 +], +"webhookId": "c118849f-57c9-40cf-bde6-dddefb9adcf4", +"parameters": { +"options": {} +}, +"typeVersion": 1.1 +}, +{ +"id": "00aac33e-20c1-4b99-b2f1-07311f73e1da", +"name": "Workflow Tool", +"type": "@n8n/n8n-nodes-langchain.toolWorkflow", +"position": [ +-1360, +600 +], +"parameters": { +"name": "n8n_creator_stats", +"workflowId": "={{ $workflow.id }}", +"description": "Call this tool to get n8n Creator Stats.", +"jsonSchemaExample": "{\n \"username\": \"n8n creator username\"\n}", +"specifyInputSchema": true +}, +"typeVersion": 1 +}, +{ +"id": "0a00599a-928d-4399-b17e-336201a67480", +"name": "creator-summary", +"type": "n8n-nodes-base.convertToFile", +"position": [ +-1020, +240 +], +"parameters": { +"options": { +"fileName": "=creator-summary" +}, +"operation": "toText", +"sourceProperty": "output" +}, +"typeVersion": 1.1 +}, +{ +"id": "8e4ae379-749d-44ad-80f8-efc836f2ff55", +"name": "Workflow Response", +"type": "n8n-nodes-base.set", +"position": [ +-420, +1920 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "eeff1310-2e1c-4ea4-9107-a14b1979f74f", +"name": "response", +"type": "string", +"value": "={{ $json.data }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "bc8ea963-a57d-44f1-bcd4-36a1dcb34f0a", +"name": "n8n Creator Stats Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +-1620, +240 +], +"parameters": { +"text": "={{ $json.chatInput }}", +"options": { +"systemMessage": "=You are tasked with generating a **comprehensive Markdown report** about a specific n8n community workflow contributor using the provided tools. Your report should not only address the user's query but also provide meaningful insights into the contributor's impact on the n8n community. Follow the structure below:\n\n## Detailed Summary\n- Provide a thorough summary of the contributor's workflows.\n- Highlight unique features, key use cases, and notable technical components for each workflow.\n\n## Workflows\nCreate a well-formatted markdown table with these columns:\n- **Workflow Name**: The name of the workflow. Keep the emojies of they exist.\n- **Description**: A brief overview of its purpose and functionality.\n- **Unique Weekly Visitors**: The number of unique users who visited this workflow weekly.\n- **Unique Monthly Visitors**: The number of unique users who visited this workflow monthly.\n- **Unique Weekly Inserters**: The number of unique users who inserted this workflow weekly.\n- **Unique Monthly Inserters**: The number of unique users who inserted this workflow monthly.\n- **Why It’s Popular**: Explain what makes this workflow stand out (e.g., innovative features, ease of use, specific use cases).\n\n## Community Analysis\n- Analyze why these workflows are popular and valued by the n8n community.\n- Discuss any trends, patterns, or feedback that highlight their significance.\n\n## Additional Insights\n- If available, provide extra information about the contributor's overall impact, such as their engagement in community forums or other notable contributions.\n\n## Formatting Guidelines\n- Use Markdown formatting exclusively (headers, lists, and tables) for clarity and organization.\n- Ensure your response is concise yet comprehensive, structured for easy navigation.\n\n## Error Handling\n- If data is unavailable or incomplete, clearly state this in your response and suggest possible reasons or next steps.\n\n## TOOLS\n\n### n8n_creator_stats \n- Use this tool to retrieve detailed statistics about the n8n creator.\n\n\n \n" +}, +"promptType": "define" +}, +"typeVersion": 1.7 +}, +{ +"id": "0e2507bf-4509-4423-ad23-bee9de2be68e", +"name": "Save creator-summary.md", +"type": "n8n-nodes-base.readWriteFile", +"position": [ +-820, +240 +], +"parameters": { +"options": { +"append": true +}, +"fileName": "=C:\\\\Users\\\\joe\\Downloads\\\\{{ $binary.data.fileName }}-{{ $now.format('yyyy-MM-dd-hh-mm-ss') }}.md", +"operation": "write" +}, +"typeVersion": 1 +}, +{ +"id": "d3d39dad-d743-4c44-ad46-c6edbad4c82b", +"name": "Summary Report", +"type": "n8n-nodes-base.set", +"position": [ +-1020, +620 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "c44ee9a7-e640-4f5e-acbe-ec559868b74c", +"name": "output", +"type": "string", +"value": "={{ $json.output }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "6c07ee44-408f-4d4a-bade-e051d780d022", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1800, +120 +], +"parameters": { +"color": 6, +"width": 620, +"height": 320, +"content": "## AI Agent for n8n Creator Leaderboard Stats\nhttps://github.com/teds-tech-talks/n8n-community-leaderboard" +}, +"typeVersion": 1 +}, +{ +"id": "a04eb80b-3cb3-44ad-aef2-c622ea2e33eb", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1440, +480 +], +"parameters": { +"width": 260, +"height": 280, +"content": "## Tool Call for n8n Creators Stats" +}, +"typeVersion": 1 +}, +{ +"id": "9b44f6e7-666b-4341-8e04-4cf41a5f986e", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-2060, +480 +], +"parameters": { +"color": 5, +"width": 300, +"height": 460, +"content": "## Local or Cloud LLM" +}, +"typeVersion": 1 +}, +{ +"id": "68fcc9de-f6d5-461c-ae64-8d8cf6892f7a", +"name": "Ollama Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOllama", +"disabled": true, +"position": [ +-1960, +780 +], +"parameters": { +"options": {} +}, +"credentials": { +"ollamaApi": { +"id": "IsSBWGtcJbjRiKqD", +"name": "Ollama account localhost" +} +}, +"typeVersion": 1 +}, +{ +"id": "584dd58a-d97d-45c5-974d-95468a55e359", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1140, +120 +], +"parameters": { +"color": 7, +"width": 540, +"height": 320, +"content": "## Save n8n Creator Report Locally\n(optional for local install)" +}, +"typeVersion": 1 +}, +{ +"id": "4ea35ccb-a4f4-481c-9122-6fc980be48d5", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1140, +480 +], +"parameters": { +"color": 4, +"width": 320, +"height": 340, +"content": "## Summary Report Response" +}, +"typeVersion": 1 +}, +{ +"id": "d48a28e9-041c-4e25-ac38-0f0519566db5", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1760, +1360 +], +"parameters": { +"width": 300, +"height": 320, +"content": "## Global Workflow Variables\n\n" +}, +"typeVersion": 1 +}, +{ +"id": "cb9b62f1-cdc3-4c2a-ba4b-8dc3baecf7e4", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1800, +1120 +], +"parameters": { +"color": 3, +"width": 780, +"height": 640, +"content": "## Daily n8n Leaderboard Stats\nhttps://github.com/teds-tech-talks/n8n-community-leaderboard\n\n### n8n Leaderboard\nhttps://teds-tech-talks.github.io/n8n-community-leaderboard/" +}, +"typeVersion": 1 +}, +{ +"id": "0f12bc26-875e-4cf0-9b87-7459fdfc73e9", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-980, +1120 +], +"parameters": { +"color": 6, +"width": 1120, +"height": 300, +"content": "## n8n Creators Stats" +}, +"typeVersion": 1 +}, +{ +"id": "23abdb9b-3aa3-48a8-987d-c0e0bdcec99f", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-980, +1460 +], +"parameters": { +"color": 4, +"width": 1120, +"height": 300, +"content": "## n8n Workflow Stats" +}, +"typeVersion": 1 +}, +{ +"id": "7b7f14b4-cde2-46b1-a37f-4fd136c57a44", +"name": "Creators Data", +"type": "n8n-nodes-base.set", +"position": [ +-60, +1220 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "02b02023-c5a2-4e22-bcf9-2284c434f5d3", +"name": "name", +"type": "string", +"value": "={{ $json.user.name }}" +}, +{ +"id": "4582435b-3c76-45e7-a251-12055efa890a", +"name": "username", +"type": "string", +"value": "={{ $json.user.username }}" +}, +{ +"id": "b713a971-ce29-43cf-8f42-c426a38c6582", +"name": "bio", +"type": "string", +"value": "={{ $json.user.bio }}" +}, +{ +"id": "19a06510-802e-4bd5-9552-7afa7355ff92", +"name": "sum_unique_weekly_inserters", +"type": "number", +"value": "={{ $json.sum_unique_weekly_inserters }}" +}, +{ +"id": "e436533a-5170-47c2-809b-7d79502eb009", +"name": "sum_unique_monthly_inserters", +"type": "number", +"value": "={{ $json.sum_unique_monthly_inserters }}" +}, +{ +"id": "198fef5d-86b8-4009-b187-6d3e6566d137", +"name": "sum_unique_inserters", +"type": "number", +"value": "={{ $json.sum_unique_inserters }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "f3363202-01ac-4ea1-a015-7c16ac1078af", +"name": "Workflows Data", +"type": "n8n-nodes-base.set", +"position": [ +-60, +1560 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "3bc3cd11-904d-4315-974d-262c0bd5fea7", +"name": "template_url", +"type": "string", +"value": "={{ $json.template_url }}" +}, +{ +"id": "c846c523-f077-40cd-b548-32460124ffb9", +"name": "wf_detais.name", +"type": "string", +"value": "={{ $json.wf_detais.name }}" +}, +{ +"id": "f330de47-56fb-4657-8a30-5f5e5cfa76d7", +"name": "wf_detais.createdAt", +"type": "string", +"value": "={{ $json.wf_detais.createdAt }}" +}, +{ +"id": "f7ed7e51-a7cf-4f2e-8819-f33115c5ad51", +"name": "wf_detais.description", +"type": "string", +"value": "={{ $json.wf_detais.description }}" +}, +{ +"id": "02b02023-c5a2-4e22-bcf9-2284c434f5d3", +"name": "name", +"type": "string", +"value": "={{ $json.user.name }}" +}, +{ +"id": "4582435b-3c76-45e7-a251-12055efa890a", +"name": "username", +"type": "string", +"value": "={{ $json.user.username }}" +}, +{ +"id": "f952cad3-7e62-46b7-aeb7-a5cbf4d46c0d", +"name": "unique_weekly_inserters", +"type": "number", +"value": "={{ $json.unique_weekly_inserters }}" +}, +{ +"id": "6123302b-5bda-48f4-9ef2-71ff52a5f3ba", +"name": "unique_monthly_inserters", +"type": "number", +"value": "={{ $json.unique_monthly_inserters }}" +}, +{ +"id": "92dca169-e03f-42ad-8790-ebb55c1a7272", +"name": "unique_weekly_visitors", +"type": "number", +"value": "={{ $json.unique_weekly_visitors }}" +}, +{ +"id": "ee640389-d396-4d65-8110-836372a51fb0", +"name": "unique_monthly_visitors", +"type": "number", +"value": "={{ $json.unique_monthly_visitors }}" +}, +{ +"id": "9f1c5599-3672-4f4e-9742-d7cc564f6714", +"name": "user.avatar", +"type": "string", +"value": "={{ $json.user.avatar }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "3ce82825-f85c-4fd3-9273-5c5540a40dbe", +"name": "Merge Creators & Workflows", +"type": "n8n-nodes-base.merge", +"position": [ +240, +1560 +], +"parameters": { +"mode": "combine", +"options": {}, +"joinMode": "enrichInput1", +"fieldsToMatchString": "username" +}, +"typeVersion": 3 +}, +{ +"id": "16c383db-c130-484a-8a6b-b927d4c248e9", +"name": "Sticky Note9", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-980, +1800 +], +"parameters": { +"width": 480, +"height": 320, +"content": "## Filter by n8n Creator Username" +}, +"typeVersion": 1 +}, +{ +"id": "7451dc33-8944-47c5-92c3-e70d4ce5d107", +"name": "Split Out Creators", +"type": "n8n-nodes-base.splitOut", +"position": [ +-680, +1220 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "data" +}, +"typeVersion": 1 +}, +{ +"id": "6fa965e1-1474-4154-b4a2-cabdbbb8e90b", +"name": "Split Out Workflows", +"type": "n8n-nodes-base.splitOut", +"position": [ +-680, +1560 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "data" +}, +"typeVersion": 1 +}, +{ +"id": "7805fa8b-6287-442d-ba2c-11ddb81ba54f", +"name": "Sort By Top Weekly Creator Inserts", +"type": "n8n-nodes-base.sort", +"position": [ +-480, +1220 +], +"parameters": { +"options": {}, +"sortFieldsUi": { +"sortField": [ +{ +"order": "descending", +"fieldName": "sum_unique_weekly_inserters" +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "d1651e0d-04c6-4c09-884e-3fd51e885f3d", +"name": "Sort By Top Weekly Workflow Inserts", +"type": "n8n-nodes-base.sort", +"position": [ +-480, +1560 +], +"parameters": { +"options": {}, +"sortFieldsUi": { +"sortField": [ +{ +"order": "descending", +"fieldName": "unique_weekly_inserters" +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "3bcf5f34-80fd-40ec-b88c-8b79b3f1677b", +"name": "Take Top 300 Workflows", +"type": "n8n-nodes-base.limit", +"position": [ +-260, +1560 +], +"parameters": { +"maxItems": 300 +}, +"typeVersion": 1 +}, +{ +"id": "dc7cf074-17a6-411d-8d59-1cfbd23b7bd2", +"name": "Sticky Note10", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-2060, +1040 +], +"parameters": { +"color": 7, +"width": 2510, +"height": 1120, +"content": "## Workflow for n8n Creators Stats" +}, +"typeVersion": 1 +}, +{ +"id": "dacb7e61-7853-47f2-b6fd-3ad611701278", +"name": "Sticky Note11", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1340, +1160 +], +"parameters": { +"color": 7, +"width": 280, +"height": 560, +"content": "## GET n8n Stats from GitHub repo" +}, +"typeVersion": 1 +}, +{ +"id": "a2373c55-9e87-4824-adc8-4d4bbf966544", +"name": "Sticky Note12", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-560, +0 +], +"parameters": { +"color": 2, +"width": 1000, +"height": 1000, +"content": "# n8n Creators Leaderboard Stats Workflow\n\n## Overview\nThis workflow aggregates and processes data from the n8n community to generate detailed statistics about creators and their workflows. It fetches information from JSON files stored on GitHub, merges creator and workflow data, filters the results based on a specified username, and uses an AI agent to output a comprehensive Markdown report.\n\n## Data Retrieval\n- **Creators Data**: \n - An HTTP Request node (\"stats_aggregate_creators\") retrieves a JSON file containing aggregated statistics for workflow creators. \n- **Workflows Data**: \n - A separate HTTP Request node (\"stats_aggregate_workflows\") pulls a JSON file with detailed workflow metrics such as visitor counts and inserter statistics. \n- **Global Variables**: \n - A global variable is set with the GitHub repository base URL housing these JSON files, ensuring that the correct data source is used.\n\n## Data Processing and Merging\n- **Parsing the Data**: \n - The \"Parse Creators Data\" and \"Parse Workflow Data\" nodes extract JSON arrays from the retrieved files for further processing. \n- **Limiting and Sorting**: \n - Nodes like \"Take Top 25 Creators\" and \"Take Top 300 Workflows\" limit the result sets, while nodes such as \"Sort By Top Weekly Creator Inserts\" and \"Sort By Top Weekly Workflow Inserts\" sort the data based on performance metrics. \n- **Merging Records**: \n - Data from creators and workflows is merged by matching the username, enriching the dataset with combined statistics for each creator.\n\n## Filtering and Report Generation\n- **Username Filtering**: \n - A filter node (\"Filter By Creator Username\") allows the workflow to focus on a single creator based on the input username (e.g., \"joe\"). \n- **Generating the Markdown Report**: \n - An AI agent node (\"gpt-4o-mini\") processes the filtered data using a predefined prompt. This prompt instructs the agent to produce a detailed Markdown report that includes: \n - An overall summary of the creator’s workflows \n - A Markdown table listing each workflow along with key metrics (unique weekly/monthly visitors and inserters) and a brief explanation of its popularity \n - Insights into trends or community feedback related to the workflows \n- **Output Conversion and Saving**: \n - The resulting text is converted into a file (using the \"creator-summary\" node) and then saved locally with a filename that includes a timestamp, ensuring easy tracking and retrieval\n" +}, +"typeVersion": 1 +}, +{ +"id": "99078ba8-612d-494a-976a-15f2065754ed", +"name": "Window Buffer Memory", +"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow", +"position": [ +-1640, +600 +], +"parameters": {}, +"typeVersion": 1.3 +}, +{ +"id": "79c67fdc-f56c-4abc-908d-cac11e66790b", +"name": "Sticky Note13", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1740, +480 +], +"parameters": { +"color": 3, +"width": 280, +"height": 280, +"content": "## Chat History Memory" +}, +"typeVersion": 1 +}, +{ +"id": "4be97085-519e-4776-88a1-6d95f97c4aa1", +"name": "Sticky Note14", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-2580, +20 +], +"parameters": { +"width": 480, +"height": 980, +"content": "# Quick Start Guide for the n8n Creators Leaderboard Workflow\n\n## Prerequisites\n- Ensure your n8n instance is running.\n- Verify that the GitHub base URL and file variables (for creators and workflows) are correctly set in the Global Variables node.\n- Confirm that your OpenAI credentials are configured for the AI Agent node.\n\n## How to Start the Workflow\n- **Activate the Workflow:** \n Ensure the workflow is active in your n8n environment.\n\n- **Trigger via Chat:** \n The workflow is initiated by the Chat Trigger node. Send a chat message such as: \n `show me stats for username [desired_username]` \n This input provides the required username for filtering.\n\n- **Processing & Report Generation:** \n Once triggered, the workflow fetches aggregated creator and workflow data from GitHub, processes and merges the information, and then uses the AI Agent to generate a Markdown report.\n\n- **Output:** \n The final Markdown report is saved locally as a file (with a timestamp), which you can review to see detailed leaderboard statistics and insights for the specified creator.\n\n## Summary\nBy sending a chat message with the appropriate username command, you can quickly trigger this workflow, which will then fetch, process, and generate dynamic statistics about n8n community creators. Enjoy exploring your community’s leaderboard data!\n" +}, +"typeVersion": 1 +}, +{ +"id": "db011ff6-359d-4b4a-b5b2-29c15b961f68", +"name": "Sticky Note15", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-2580, +1040 +], +"parameters": { +"width": 480, +"height": 940, +"content": "# Why Use the n8n Creators Leaderboard Workflow?\n\n## Benefits\nThis workflow provides valuable insights into the n8n community by analyzing and presenting detailed statistics about workflow creators and their contributions. It helps users to:\n\n- **Discover Popular Workflows**: Identify the most widely used workflows based on unique visitors and inserters, both weekly and monthly.\n- **Understand Community Trends**: Gain insights into what types of workflows are resonating with the community, enabling better decision-making for creating or improving workflows.\n- **Recognize Top Contributors**: Highlight the most active and impactful creators, fostering collaboration and inspiration within the community.\n- **Save Time with Automation**: Automates data retrieval, processing, and report generation, eliminating manual effort.\n\n## Key Features\n- **Data Aggregation**: Fetches creator and workflow statistics from GitHub repositories.\n- **Custom Filtering**: Allows filtering by specific usernames to focus on individual contributors.\n- **AI-Powered Reports**: Generates comprehensive Markdown reports with detailed summaries, tables, and community analysis.\n- **Output Flexibility**: Saves reports locally for easy access and future reference.\n\n## Use Cases\n- **For Workflow Creators**: Monitor performance metrics of your workflows to understand their impact and optimize them for better engagement.\n- **For Community Managers**: Recognize top contributors and trends to encourage participation and improve community resources.\n- **For New Users**: Explore popular workflows as a starting point for building your own automations.\n\n" +}, +"typeVersion": 1 +} +], +"active": false, +"pinData": { +"When chat message received": [ +{ +"json": { +"action": "sendMessage", +"chatInput": "\tshow me stats for username joe", +"sessionId": "61fd98239a894d969c0b33060f3f9c44" +} +} +], +"When Executed by Another Workflow": [ +{ +"json": { +"query": { +"username": "joe" +} +} +} +] +}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "574ed096-a76c-4cfe-b026-20627f454ddc", +"connections": { +"Aggregate": { +"main": [ +[ +{ +"node": "Workflow Response", +"type": "main", +"index": 0 +} +] +] +}, +"gpt-4o-mini": { +"ai_languageModel": [ +[ +{ +"node": "n8n Creator Stats Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Creators Data": { +"main": [ +[ +{ +"node": "Merge Creators & Workflows", +"type": "main", +"index": 0 +} +] +] +}, +"Workflow Tool": { +"ai_tool": [ +[ +{ +"node": "n8n Creator Stats Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Workflows Data": { +"main": [ +[ +{ +"node": "Merge Creators & Workflows", +"type": "main", +"index": 1 +} +] +] +}, +"creator-summary": { +"main": [ +[ +{ +"node": "Save creator-summary.md", +"type": "main", +"index": 0 +} +] +] +}, +"Global Variables": { +"main": [ +[ +{ +"node": "stats_aggregate_creators", +"type": "main", +"index": 0 +}, +{ +"node": "stats_aggregate_workflows", +"type": "main", +"index": 0 +} +] +] +}, +"Ollama Chat Model": { +"ai_languageModel": [ +[] +] +}, +"Split Out Creators": { +"main": [ +[ +{ +"node": "Sort By Top Weekly Creator Inserts", +"type": "main", +"index": 0 +} +] +] +}, +"Parse Creators Data": { +"main": [ +[ +{ +"node": "Split Out Creators", +"type": "main", +"index": 0 +} +] +] +}, +"Parse Workflow Data": { +"main": [ +[ +{ +"node": "Split Out Workflows", +"type": "main", +"index": 0 +} +] +] +}, +"Split Out Workflows": { +"main": [ +[ +{ +"node": "Sort By Top Weekly Workflow Inserts", +"type": "main", +"index": 0 +} +] +] +}, +"Take Top 25 Creators": { +"main": [ +[ +{ +"node": "Creators Data", +"type": "main", +"index": 0 +} +] +] +}, +"Window Buffer Memory": { +"ai_memory": [ +[ +{ +"node": "n8n Creator Stats Agent", +"type": "ai_memory", +"index": 0 +} +] +] +}, +"Take Top 300 Workflows": { +"main": [ +[ +{ +"node": "Workflows Data", +"type": "main", +"index": 0 +} +] +] +}, +"n8n Creator Stats Agent": { +"main": [ +[ +{ +"node": "Summary Report", +"type": "main", +"index": 0 +}, +{ +"node": "creator-summary", +"type": "main", +"index": 0 +} +] +] +}, +"stats_aggregate_creators": { +"main": [ +[ +{ +"node": "Parse Creators Data", +"type": "main", +"index": 0 +} +] +] +}, +"stats_aggregate_workflows": { +"main": [ +[ +{ +"node": "Parse Workflow Data", +"type": "main", +"index": 0 +} +] +] +}, +"Filter By Creator Username": { +"main": [ +[ +{ +"node": "Aggregate", +"type": "main", +"index": 0 +} +] +] +}, +"Merge Creators & Workflows": { +"main": [ +[ +{ +"node": "Filter By Creator Username", +"type": "main", +"index": 0 +} +] +] +}, +"When chat message received": { +"main": [ +[ +{ +"node": "n8n Creator Stats Agent", +"type": "main", +"index": 0 +} +] +] +}, +"When Executed by Another Workflow": { +"main": [ +[ +{ +"node": "Global Variables", +"type": "main", +"index": 0 +} +] +] +}, +"Sort By Top Weekly Creator Inserts": { +"main": [ +[ +{ +"node": "Take Top 25 Creators", +"type": "main", +"index": 0 +} +] +] +}, +"Sort By Top Weekly Workflow Inserts": { +"main": [ +[ +{ +"node": "Take Top 300 Workflows", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/🤖🧑_💻 AI Agent for Top n8n Creators Leaderboard Reporting.txt b/🤖🧑_💻 AI Agent for Top n8n Creators Leaderboard Reporting.txt new file mode 100644 index 0000000..6e6b22a --- /dev/null +++ b/🤖🧑_💻 AI Agent for Top n8n Creators Leaderboard Reporting.txt @@ -0,0 +1,1301 @@ +{ +"id": "6zSE618gr9fDtAfF", +"meta": { +"instanceId": "31e69f7f4a77bf465b805824e303232f0227212ae922d12133a0f96ffeab4fef", +"templateCredsSetupCompleted": true +}, +"name": "🤖🧑‍💻 AI Agent for Top n8n Creators Leaderboard Reporting", +"tags": [], +"nodes": [ +{ +"id": "5b9537db-41d3-4d8a-bf41-f875e4044224", +"name": "stats_aggregate_creators", +"type": "n8n-nodes-base.httpRequest", +"position": [ +-1240, +1300 +], +"parameters": { +"url": "={{ $json.path }}{{ $json['creators-filename'] }}.json", +"options": {} +}, +"typeVersion": 4.2 +}, +{ +"id": "feb2328b-57b0-4280-98d8-6b946db0c947", +"name": "stats_aggregate_workflows", +"type": "n8n-nodes-base.httpRequest", +"position": [ +-1240, +1500 +], +"parameters": { +"url": "={{ $json.path }}{{ $json['workflows-filename'] }}.json", +"options": {} +}, +"typeVersion": 4.2 +}, +{ +"id": "53f8b825-b030-4541-b12b-6df6702f7d1b", +"name": "Global Variables", +"type": "n8n-nodes-base.set", +"position": [ +-1660, +1460 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "4bcb91c6-d250-4cb4-8ee1-022df13550e1", +"name": "path", +"type": "string", +"value": "https://raw.githubusercontent.com/teds-tech-talks/n8n-community-leaderboard/refs/heads/main/" +}, +{ +"id": "a910a798-0bfe-41b1-a4f1-41390c7f6997", +"name": "workflows-filename", +"type": "string", +"value": "=stats_aggregate_workflows" +}, +{ +"id": "e977e816-dc1e-43ce-9393-d6488e6832ca", +"name": "creators-filename", +"type": "string", +"value": "=stats_aggregate_creators" +}, +{ +"id": "14233ab4-3fa4-4e26-8032-6ffe26cb601e", +"name": "datetime", +"type": "string", +"value": "={{ $now.format('yyyy-MM-dd') }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "202026ea-054f-45ae-84f6-59ec58794f1c", +"name": "Parse Workflow Data", +"type": "n8n-nodes-base.set", +"position": [ +-880, +1540 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "76f4b20e-519e-4d46-aeac-c6c3f98a69fd", +"name": "data", +"type": "array", +"value": "={{ $json.data }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "54ecfc96-0f5e-4275-a53b-f87850926d7f", +"name": "Parse Creators Data", +"type": "n8n-nodes-base.set", +"position": [ +-880, +1200 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "76f4b20e-519e-4d46-aeac-c6c3f98a69fd", +"name": "data", +"type": "array", +"value": "={{ $json.data }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "e590677e-a8ff-4b76-8527-e5bdc0076610", +"name": "Aggregate", +"type": "n8n-nodes-base.aggregate", +"position": [ +-680, +1820 +], +"parameters": { +"options": {}, +"aggregate": "aggregateAllItemData" +}, +"typeVersion": 1 +}, +{ +"id": "7d7ef0f2-dbca-4b24-b2e5-c1236c4beb81", +"name": "gpt-4o-mini", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +-1880, +780 +], +"parameters": { +"model": { +"__rl": true, +"mode": "list", +"value": "gpt-4o-mini" +}, +"options": { +"temperature": 0.1 +} +}, +"credentials": { +"openAiApi": { +"id": "jEMSvKmtYfzAkhe6", +"name": "OpenAi account" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "59e7066f-da3b-4461-9a52-0f8754b696ae", +"name": "When Executed by Another Workflow", +"type": "n8n-nodes-base.executeWorkflowTrigger", +"position": [ +-1980, +1460 +], +"parameters": { +"inputSource": "jsonExample", +"jsonExample": "{\n \"query\": \n {\n \"username\": \n \"joe\"\n }\n}" +}, +"typeVersion": 1.1 +}, +{ +"id": "18734480-3520-4e37-af19-977ec3bfb260", +"name": "Workflow Tool", +"type": "@n8n/n8n-nodes-langchain.toolWorkflow", +"position": [ +-1540, +780 +], +"parameters": { +"name": "n8n_creator_stats", +"workflowId": "={{ $workflow.id }}", +"description": "Call this tool to get n8n Creator Stats.", +"jsonSchemaExample": "{\n \"username\": \"n8n creator username\"\n}", +"specifyInputSchema": true +}, +"typeVersion": 1 +}, +{ +"id": "4b2195bd-d506-4cd5-bb9d-37cf84c8cebf", +"name": "creator-summary", +"type": "n8n-nodes-base.convertToFile", +"position": [ +-1140, +60 +], +"parameters": { +"options": { +"fileName": "=creators-report" +}, +"operation": "toText", +"sourceProperty": "output" +}, +"typeVersion": 1.1 +}, +{ +"id": "ca25473a-0e19-45e0-8de5-00601c95fdf9", +"name": "Workflow Response", +"type": "n8n-nodes-base.set", +"position": [ +-480, +1820 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "eeff1310-2e1c-4ea4-9107-a14b1979f74f", +"name": "response", +"type": "string", +"value": "={{ $json.data }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "c45c9bc8-e0d9-496a-bf8d-71c806c330de", +"name": "Save creator-summary.md", +"type": "n8n-nodes-base.readWriteFile", +"position": [ +-940, +60 +], +"parameters": { +"options": { +"append": true +}, +"fileName": "=C:\\\\Users\\\\joe\\Downloads\\\\{{ $binary.data.fileName }}-{{ $now.format('yyyy-MM-dd-hh-mm-ss') }}.md", +"operation": "write" +}, +"typeVersion": 1 +}, +{ +"id": "0cddb18b-7924-41f6-b429-a00e4c904b47", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-2060, +240 +], +"parameters": { +"color": 5, +"width": 780, +"height": 740, +"content": "## AI Agent for n8n Creator Leaderboard Stats\nhttps://github.com/teds-tech-talks/n8n-community-leaderboard" +}, +"typeVersion": 1 +}, +{ +"id": "6e1a7ffe-bac6-43d8-b7e8-866eb5fcb9f7", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1640, +620 +], +"parameters": { +"width": 280, +"height": 300, +"content": "## Tool Call for n8n Creators Stats\nhttps://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolworkflow/" +}, +"typeVersion": 1 +}, +{ +"id": "892ac156-a276-4697-9b25-768301991996", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1980, +620 +], +"parameters": { +"color": 7, +"width": 300, +"height": 300, +"content": "## OpenAI LLM\nhttps://platform.openai.com/api-keys" +}, +"typeVersion": 1 +}, +{ +"id": "1e3cdf04-b33f-4a64-83c8-f24c424380b2", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1240, +-60 +], +"parameters": { +"width": 540, +"height": 320, +"content": "## Save n8n Creators & Workflows Report Locally\n(optional for local install)" +}, +"typeVersion": 1 +}, +{ +"id": "a01adc65-9425-460b-85ed-fac4c82f1e78", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1760, +1340 +], +"parameters": { +"width": 300, +"height": 320, +"content": "## Global Workflow Variables\n\n" +}, +"typeVersion": 1 +}, +{ +"id": "f7523185-7d36-4839-bfd3-d101fc1164fa", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1800, +1100 +], +"parameters": { +"color": 3, +"width": 780, +"height": 640, +"content": "## Daily n8n Leaderboard Stats\nhttps://github.com/teds-tech-talks/n8n-community-leaderboard\n\n### n8n Leaderboard\nhttps://teds-tech-talks.github.io/n8n-community-leaderboard/" +}, +"typeVersion": 1 +}, +{ +"id": "79381486-6caf-4629-94ac-d7cfef44c437", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-980, +1100 +], +"parameters": { +"color": 6, +"width": 1120, +"height": 300, +"content": "## n8n Creators Stats" +}, +"typeVersion": 1 +}, +{ +"id": "6099f718-37d2-45a6-806c-2196dbf6736b", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-980, +1440 +], +"parameters": { +"color": 4, +"width": 1120, +"height": 300, +"content": "## n8n Workflow Stats" +}, +"typeVersion": 1 +}, +{ +"id": "1270338c-1a9f-4a90-a5f1-7efd7547de4e", +"name": "Creators Data", +"type": "n8n-nodes-base.set", +"position": [ +-60, +1200 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "02b02023-c5a2-4e22-bcf9-2284c434f5d3", +"name": "name", +"type": "string", +"value": "={{ $json.user.name }}" +}, +{ +"id": "4582435b-3c76-45e7-a251-12055efa890a", +"name": "username", +"type": "string", +"value": "={{ $json.user.username }}" +}, +{ +"id": "b713a971-ce29-43cf-8f42-c426a38c6582", +"name": "bio", +"type": "string", +"value": "={{ $json.user.bio }}" +}, +{ +"id": "19a06510-802e-4bd5-9552-7afa7355ff92", +"name": "sum_unique_weekly_inserters", +"type": "number", +"value": "={{ $json.sum_unique_weekly_inserters }}" +}, +{ +"id": "e436533a-5170-47c2-809b-7d79502eb009", +"name": "sum_unique_monthly_inserters", +"type": "number", +"value": "={{ $json.sum_unique_monthly_inserters }}" +}, +{ +"id": "198fef5d-86b8-4009-b187-6d3e6566d137", +"name": "sum_unique_inserters", +"type": "number", +"value": "={{ $json.sum_unique_inserters }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "3fd50542-2067-4dd4-a3ae-006aa4f9b030", +"name": "Workflows Data", +"type": "n8n-nodes-base.set", +"position": [ +-60, +1540 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "3bc3cd11-904d-4315-974d-262c0bd5fea7", +"name": "template_url", +"type": "string", +"value": "={{ $json.template_url }}" +}, +{ +"id": "c846c523-f077-40cd-b548-32460124ffb9", +"name": "wf_detais.name", +"type": "string", +"value": "={{ $json.wf_detais.name }}" +}, +{ +"id": "f330de47-56fb-4657-8a30-5f5e5cfa76d7", +"name": "wf_detais.createdAt", +"type": "string", +"value": "={{ $json.wf_detais.createdAt }}" +}, +{ +"id": "f7ed7e51-a7cf-4f2e-8819-f33115c5ad51", +"name": "wf_detais.description", +"type": "string", +"value": "={{ $json.wf_detais.description }}" +}, +{ +"id": "02b02023-c5a2-4e22-bcf9-2284c434f5d3", +"name": "name", +"type": "string", +"value": "={{ $json.user.name }}" +}, +{ +"id": "4582435b-3c76-45e7-a251-12055efa890a", +"name": "username", +"type": "string", +"value": "={{ $json.user.username }}" +}, +{ +"id": "f952cad3-7e62-46b7-aeb7-a5cbf4d46c0d", +"name": "unique_weekly_inserters", +"type": "number", +"value": "={{ $json.unique_weekly_inserters }}" +}, +{ +"id": "6123302b-5bda-48f4-9ef2-71ff52a5f3ba", +"name": "unique_monthly_inserters", +"type": "number", +"value": "={{ $json.unique_monthly_inserters }}" +}, +{ +"id": "92dca169-e03f-42ad-8790-ebb55c1a7272", +"name": "unique_weekly_visitors", +"type": "number", +"value": "={{ $json.unique_weekly_visitors }}" +}, +{ +"id": "ee640389-d396-4d65-8110-836372a51fb0", +"name": "unique_monthly_visitors", +"type": "number", +"value": "={{ $json.unique_monthly_visitors }}" +}, +{ +"id": "9f1c5599-3672-4f4e-9742-d7cc564f6714", +"name": "user.avatar", +"type": "string", +"value": "={{ $json.user.avatar }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "6ad04027-1df9-402d-b98c-de7ec7e62cae", +"name": "Merge Creators & Workflows", +"type": "n8n-nodes-base.merge", +"position": [ +240, +1540 +], +"parameters": { +"mode": "combine", +"options": {}, +"joinMode": "enrichInput1", +"fieldsToMatchString": "username" +}, +"typeVersion": 3 +}, +{ +"id": "fdf56c84-804a-46e2-8058-8a4374ba21b7", +"name": "Split Out Creators", +"type": "n8n-nodes-base.splitOut", +"position": [ +-680, +1200 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "data" +}, +"typeVersion": 1 +}, +{ +"id": "cac2e121-f0a9-4142-86c7-5549b8b3631d", +"name": "Split Out Workflows", +"type": "n8n-nodes-base.splitOut", +"position": [ +-680, +1540 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "data" +}, +"typeVersion": 1 +}, +{ +"id": "4a32eb8c-07d2-4a71-bb60-9e2c2eeda7f6", +"name": "Sort By Top Weekly Creator Inserts", +"type": "n8n-nodes-base.sort", +"position": [ +-480, +1200 +], +"parameters": { +"options": {}, +"sortFieldsUi": { +"sortField": [ +{ +"order": "descending", +"fieldName": "sum_unique_weekly_inserters" +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "f39b2e87-cc3a-4e90-84dc-18ae663608d6", +"name": "Sort By Top Weekly Workflow Inserts", +"type": "n8n-nodes-base.sort", +"position": [ +-480, +1540 +], +"parameters": { +"options": {}, +"sortFieldsUi": { +"sortField": [ +{ +"order": "descending", +"fieldName": "unique_weekly_inserters" +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "85ae9c6b-50bd-40df-bebd-e7522df61f3c", +"name": "Sticky Note10", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-2060, +1020 +], +"parameters": { +"color": 7, +"width": 2510, +"height": 1000, +"content": "## Workflow for n8n Creators Stats" +}, +"typeVersion": 1 +}, +{ +"id": "7aaf6f1b-a42b-49e6-a9bd-27c8ee2b6e83", +"name": "Sticky Note11", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1340, +1140 +], +"parameters": { +"color": 7, +"width": 280, +"height": 560, +"content": "## GET n8n Stats from GitHub repo\nhttps://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/" +}, +"typeVersion": 1 +}, +{ +"id": "5aa6990b-c764-4d5a-ab68-c6f12b3d3b70", +"name": "Schedule Trigger", +"type": "n8n-nodes-base.scheduleTrigger", +"position": [ +-2260, +380 +], +"parameters": { +"rule": { +"interval": [ +{ +"triggerAtHour": 22 +} +] +} +}, +"typeVersion": 1.2 +}, +{ +"id": "160fa10e-9697-4c84-ba13-d701baaee782", +"name": "Take Top 10 Creators", +"type": "n8n-nodes-base.limit", +"position": [ +-260, +1200 +], +"parameters": { +"maxItems": 10 +}, +"typeVersion": 1 +}, +{ +"id": "09d8cc25-7ea7-4793-a891-90f8b577df81", +"name": "Take Top 50 Workflows", +"type": "n8n-nodes-base.limit", +"position": [ +-260, +1540 +], +"parameters": { +"maxItems": 50 +}, +"typeVersion": 1 +}, +{ +"id": "c3ebbc08-151e-4f18-848f-ddec2a720edc", +"name": "Google Drive", +"type": "n8n-nodes-base.googleDrive", +"position": [ +-1040, +460 +], +"parameters": { +"name": "=n8n Creator Stats Report - {{ $now.format('yyyy-MM-dd:hh:mm:ss') }}", +"content": "={{ $json.output }}", +"driveId": { +"__rl": true, +"mode": "list", +"value": "My Drive" +}, +"options": {}, +"folderId": { +"__rl": true, +"mode": "list", +"value": "root", +"cachedResultName": "/ (Root folder)" +}, +"operation": "createFromText" +}, +"credentials": { +"googleDriveOAuth2Api": { +"id": "UhdXGYLTAJbsa0xX", +"name": "Google Drive account" +} +}, +"typeVersion": 3 +}, +{ +"id": "0a2ff2ea-6120-49e2-adda-547830b4f9f8", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-320, +1060 +], +"parameters": { +"width": 220, +"height": 720, +"content": "## Settings\nChange these settings to suit your needs" +}, +"typeVersion": 1 +}, +{ +"id": "f5db76e5-8058-4771-8a3b-0116f0abb6a3", +"name": "Sticky Note9", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1240, +300 +], +"parameters": { +"color": 6, +"width": 540, +"height": 340, +"content": "## Save n8n Creator & Workflows Report to Google Drive\nhttps://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.googledrive/" +}, +"typeVersion": 1 +}, +{ +"id": "4594d952-8d21-40ac-8654-4a050c96a686", +"name": "Sticky Note12", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1240, +680 +], +"parameters": { +"color": 4, +"width": 540, +"height": 300, +"content": "## Email n8n Creators & Workflows Report\nhttps://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.gmail/" +}, +"typeVersion": 1 +}, +{ +"id": "784b5047-9fdf-40db-ab07-436c12d749d0", +"name": "Convert Markdown to HTML", +"type": "n8n-nodes-base.markdown", +"position": [ +-1140, +780 +], +"parameters": { +"mode": "markdownToHtml", +"options": {}, +"markdown": "={{ $json.output }}" +}, +"typeVersion": 1 +}, +{ +"id": "cab1978f-9aa0-4cd8-901c-f6ad615936c6", +"name": "n8n Creators Stats Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +-1800, +380 +], +"parameters": { +"text": "=Prepare a report about the n8n creators", +"options": { +"systemMessage": "=You are tasked with generating a **comprehensive Markdown report** about n8n community workflows and contributors using the provided tools. Your report should include meaningful insights about the contributors positive impact on the n8n community. Follow the structure below:\n\n## Detailed Summary\n- Provide a thorough summary of ALL contributor's workflows.\n- Highlight unique features, key use cases, and notable technical components for each workflow.\n- Include hyperlinks for each workflow.\n\n## Workflows\nCreate a well-formatted markdown table with these columns:\n- **Workflow Name**: The name of the workflow. Keep the emojies of they exist. Include hyperlinks for each workflow.\n- **Description**: A brief overview of its purpose and functionality.\n- **Unique Weekly Visitors**: The number of unique users who visited this workflow weekly.\n- **Unique Monthly Visitors**: The number of unique users who visited this workflow monthly.\n- **Unique Weekly Inserters**: The number of unique users who inserted this workflow weekly.\n- **Unique Monthly Inserters**: The number of unique users who inserted this workflow monthly.\n- **Why It’s Popular**: Explain what makes this workflow stand out (e.g., innovative features, ease of use, specific use cases).\n\n## Community Analysis\n- Analyze why these workflows are popular and valued by the n8n community.\n- Discuss any trends, patterns, or feedback that highlight their significance.\n\n## Additional Insights\n- If available, provide extra information about the contributor's overall impact, such as their engagement in community forums or other notable contributions.\n\n## Formatting Guidelines\n- Use Markdown formatting exclusively (headers, lists, and tables) for clarity and organization.\n- Ensure your response is concise yet comprehensive, structured for easy navigation.\n\n## Error Handling\n- If data is unavailable or incomplete, clearly state this in your response and suggest possible reasons or next steps.\n\n## TOOLS\n\n### n8n_creator_stats \n- Use this tool to retrieve detailed statistics about the n8n creators.\n\n\n \n" +}, +"promptType": "define" +}, +"typeVersion": 1.7 +}, +{ +"id": "f94de0ba-4d27-4b00-8f6c-b15ea2f37af7", +"name": "Sticky Note13", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-80, +280 +], +"parameters": { +"width": 320, +"height": 340, +"content": "## Telegram \n(Optional)\nhttps://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.telegram/" +}, +"typeVersion": 1 +}, +{ +"id": "f50913c0-6615-4a5d-a4d4-2522280bc978", +"name": "Google Gemini Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini", +"position": [ +-440, +720 +], +"parameters": { +"options": { +"temperature": 0.2 +}, +"modelName": "models/gemini-2.0-flash-exp" +}, +"credentials": { +"googlePalmApi": { +"id": "L9UNQHflYlyF9Ngd", +"name": "Google Gemini(PaLM) Api account" +} +}, +"typeVersion": 1 +}, +{ +"id": "137b191e-9dae-4396-a536-dd77126ef176", +"name": "Create Top 10 Workflows List", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +-520, +380 +], +"parameters": { +"text": "=Create a list with hyperlinks of the top 10 workflows by weekly instertions from this report: {{ $json.output }}\n\nDo not include any preamble or further explanation. ", +"promptType": "define" +}, +"typeVersion": 1.5 +}, +{ +"id": "6249b1e5-2f47-469a-8bcc-16f41ee1da12", +"name": "Sticky Note14", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-660, +280 +], +"parameters": { +"color": 5, +"width": 540, +"height": 700, +"content": "## Create Top 10 Workflows List\n" +}, +"typeVersion": 1 +}, +{ +"id": "9564db34-8b19-474e-812c-8a9d2cd028cb", +"name": "Sticky Note15", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-540, +600 +], +"parameters": { +"color": 7, +"width": 300, +"height": 280, +"content": "## Google Gemini LLM\nhttps://aistudio.google.com/apikey" +}, +"typeVersion": 1 +}, +{ +"id": "065624e9-7f45-4607-94e9-2bf5a4f983ef", +"name": "Sticky Note16", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-80, +680 +], +"parameters": { +"color": 4, +"width": 520, +"height": 300, +"content": "## Email Top 10 Workflows List\nhttps://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.gmail/" +}, +"typeVersion": 1 +}, +{ +"id": "532c071f-3ae0-4afd-9569-2ecc2ccebb02", +"name": "Convert Top 10 Markdown to HTML", +"type": "n8n-nodes-base.markdown", +"position": [ +20, +780 +], +"parameters": { +"mode": "markdownToHtml", +"options": {}, +"markdown": "={{ $json.text }}" +}, +"typeVersion": 1 +}, +{ +"id": "f3aa0206-4449-41b1-aa4e-1fec6c948250", +"name": "Gmail Creators & Workflows Report", +"type": "n8n-nodes-base.gmail", +"position": [ +-940, +780 +], +"webhookId": "2bad33f7-38f8-40ca-9bcd-2f51179c8db5", +"parameters": { +"sendTo": "joe@example.com", +"message": "={{ $json.data }}", +"options": {}, +"subject": "n8n Creator Stats" +}, +"credentials": { +"gmailOAuth2": { +"id": "1xpVDEQ1yx8gV022", +"name": "Gmail account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "2521435a-ad6e-4724-a07c-7762860b3f55", +"name": "Telegram Top 10 Workflows List", +"type": "n8n-nodes-base.telegram", +"onError": "continueRegularOutput", +"position": [ +20, +420 +], +"webhookId": "8406b3d2-5ac6-452d-847f-c0886c8cd058", +"parameters": { +"text": "=n8n Creators Report - Top 10 Workflows\n{{ $now }}\n----------------------------------------------------\n{{ $json.text }}", +"chatId": "={{ $env.TELEGRAM_CHAT_ID }}", +"additionalFields": { +"parse_mode": "HTML", +"appendAttribution": false +} +}, +"credentials": { +"telegramApi": { +"id": "pAIFhguJlkO3c7aQ", +"name": "Telegram account" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "f234a3c1-18ba-488e-a88d-4a05be9eb9f4", +"name": "Gmail Top 10 Workflows List", +"type": "n8n-nodes-base.gmail", +"position": [ +220, +780 +], +"webhookId": "2bad33f7-38f8-40ca-9bcd-2f51179c8db5", +"parameters": { +"sendTo": "joe@example.com", +"message": "={{ $json.data }}", +"options": {}, +"subject": "n8n Top 10 Workflows" +}, +"credentials": { +"gmailOAuth2": { +"id": "1xpVDEQ1yx8gV022", +"name": "Gmail account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "1267b550-5c8a-4fa3-8f0a-4d18f16a57c4", +"name": "Sticky Note17", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-2640, +580 +], +"parameters": { +"width": 540, +"height": 900, +"content": "# n8n Top Creators Leaderboard Reporting Workflow\n\n## Why This Workflow is Important\nThis workflow is a powerful tool for reporting on the n8n community's creators and workflows. It provides valuable insights into the most popular workflows, top contributors, and community trends. By automating data aggregation, processing, and report generation, it saves time and effort while fostering collaboration and inspiration within the n8n ecosystem.\n\n### Key Benefits:\n- **Discover Trends**: Identify top workflows based on unique visitors and inserters.\n- **Recognize Contributors**: Highlight impactful creators driving community engagement.\n- **Save Time**: Automates the entire reporting process, from data retrieval to report creation.\n\n## How to Use It\n1. **Set Up Prerequisites**: Ensure your n8n instance is running, GitHub data files are accessible, Google Gmail/Drive and OpenAI credentials are configured and Google Gemini credentials are configured.\n\n2. **Trigger the Workflow**:\n - Schedule the workflow to run daily or as needed.\n\n3. **Review Reports**:\n - The workflow generates a detailed Markdown report with summaries, tables, and insights.\n - Reports are saved locally or shared via email, Google Drive, or Telegram.\n\n\nThis workflow is ideal for creators, community managers, and new users looking to explore or optimize workflows within the n8n platform.\n" +}, +"typeVersion": 1 +} +], +"active": true, +"pinData": {}, +"settings": { +"timezone": "America/Vancouver", +"callerPolicy": "workflowsFromSameOwner", +"executionOrder": "v1" +}, +"versionId": "619db74b-3f91-4d3b-b85d-e7e6bb972aca", +"connections": { +"Aggregate": { +"main": [ +[ +{ +"node": "Workflow Response", +"type": "main", +"index": 0 +} +] +] +}, +"gpt-4o-mini": { +"ai_languageModel": [ +[ +{ +"node": "n8n Creators Stats Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Creators Data": { +"main": [ +[ +{ +"node": "Merge Creators & Workflows", +"type": "main", +"index": 0 +} +] +] +}, +"Workflow Tool": { +"ai_tool": [ +[ +{ +"node": "n8n Creators Stats Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Workflows Data": { +"main": [ +[ +{ +"node": "Merge Creators & Workflows", +"type": "main", +"index": 1 +} +] +] +}, +"creator-summary": { +"main": [ +[ +{ +"node": "Save creator-summary.md", +"type": "main", +"index": 0 +} +] +] +}, +"Global Variables": { +"main": [ +[ +{ +"node": "stats_aggregate_creators", +"type": "main", +"index": 0 +}, +{ +"node": "stats_aggregate_workflows", +"type": "main", +"index": 0 +} +] +] +}, +"Schedule Trigger": { +"main": [ +[ +{ +"node": "n8n Creators Stats Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Split Out Creators": { +"main": [ +[ +{ +"node": "Sort By Top Weekly Creator Inserts", +"type": "main", +"index": 0 +} +] +] +}, +"Parse Creators Data": { +"main": [ +[ +{ +"node": "Split Out Creators", +"type": "main", +"index": 0 +} +] +] +}, +"Parse Workflow Data": { +"main": [ +[ +{ +"node": "Split Out Workflows", +"type": "main", +"index": 0 +} +] +] +}, +"Split Out Workflows": { +"main": [ +[ +{ +"node": "Sort By Top Weekly Workflow Inserts", +"type": "main", +"index": 0 +} +] +] +}, +"Take Top 10 Creators": { +"main": [ +[ +{ +"node": "Creators Data", +"type": "main", +"index": 0 +} +] +] +}, +"Take Top 50 Workflows": { +"main": [ +[ +{ +"node": "Workflows Data", +"type": "main", +"index": 0 +} +] +] +}, +"Convert Markdown to HTML": { +"main": [ +[ +{ +"node": "Gmail Creators & Workflows Report", +"type": "main", +"index": 0 +} +] +] +}, +"Google Gemini Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Create Top 10 Workflows List", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"n8n Creators Stats Agent": { +"main": [ +[ +{ +"node": "creator-summary", +"type": "main", +"index": 0 +}, +{ +"node": "Google Drive", +"type": "main", +"index": 0 +}, +{ +"node": "Convert Markdown to HTML", +"type": "main", +"index": 0 +}, +{ +"node": "Create Top 10 Workflows List", +"type": "main", +"index": 0 +} +] +] +}, +"stats_aggregate_creators": { +"main": [ +[ +{ +"node": "Parse Creators Data", +"type": "main", +"index": 0 +} +] +] +}, +"stats_aggregate_workflows": { +"main": [ +[ +{ +"node": "Parse Workflow Data", +"type": "main", +"index": 0 +} +] +] +}, +"Merge Creators & Workflows": { +"main": [ +[ +{ +"node": "Aggregate", +"type": "main", +"index": 0 +} +] +] +}, +"Create Top 10 Workflows List": { +"main": [ +[ +{ +"node": "Convert Top 10 Markdown to HTML", +"type": "main", +"index": 0 +}, +{ +"node": "Telegram Top 10 Workflows List", +"type": "main", +"index": 0 +} +] +] +}, +"Convert Top 10 Markdown to HTML": { +"main": [ +[ +{ +"node": "Gmail Top 10 Workflows List", +"type": "main", +"index": 0 +} +] +] +}, +"When Executed by Another Workflow": { +"main": [ +[ +{ +"node": "Global Variables", +"type": "main", +"index": 0 +} +] +] +}, +"Sort By Top Weekly Creator Inserts": { +"main": [ +[ +{ +"node": "Take Top 10 Creators", +"type": "main", +"index": 0 +} +] +] +}, +"Sort By Top Weekly Workflow Inserts": { +"main": [ +[ +{ +"node": "Take Top 50 Workflows", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/🤖🧠 AI Agent Chatbot + LONG TERM Memory + Note Storage + Telegram.txt b/🤖🧠 AI Agent Chatbot + LONG TERM Memory + Note Storage + Telegram.txt new file mode 100644 index 0000000..95f1345 --- /dev/null +++ b/🤖🧠 AI Agent Chatbot + LONG TERM Memory + Note Storage + Telegram.txt @@ -0,0 +1,538 @@ +{ +"id": "QJZLBn9L6NbmjmLK", +"meta": { +"instanceId": "31e69f7f4a77bf465b805824e303232f0227212ae922d12133a0f96ffeab4fef" +}, +"name": "🤖🧠 AI Agent Chatbot + LONG TERM Memory + Note Storage + Telegram", +"tags": [], +"nodes": [ +{ +"id": "20a2d959-5412-447b-a2c4-7736b6b758b3", +"name": "When chat message received", +"type": "@n8n/n8n-nodes-langchain.chatTrigger", +"position": [ +-320, +1600 +], +"webhookId": "8ba8fa53-2c24-47a8-b4dd-67b88c106e3d", +"parameters": { +"options": {} +}, +"typeVersion": 1.1 +}, +{ +"id": "de79c268-bac5-48ff-be4d-18f522861c22", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-100, +1280 +], +"parameters": { +"color": 4, +"width": 340, +"height": 380, +"content": "## Retrieve Long Term Memories\nGoogle Docs" +}, +"typeVersion": 1 +}, +{ +"id": "000a94d1-57ce-4eec-a021-9123685d22bf", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1040, +1840 +], +"parameters": { +"width": 280, +"height": 380, +"content": "## Save To Current Chat Memory (Optional)" +}, +"typeVersion": 1 +}, +{ +"id": "1bf1cade-bb3e-450a-a531-9add259069df", +"name": "Sticky Note9", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1360, +1840 +], +"parameters": { +"color": 4, +"width": 280, +"height": 380, +"content": "## Save Long Term Memories\nGoogle Docs" +}, +"typeVersion": 1 +}, +{ +"id": "8b30f207-8204-4548-8f51-38c387d98ae9", +"name": "gpt-4o-mini", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +820, +1900 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "jEMSvKmtYfzAkhe6", +"name": "OpenAi account" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "50271e59-6dd2-4f54-9b28-dd4a9f33ddc5", +"name": "Chat Response", +"type": "n8n-nodes-base.set", +"position": [ +1440, +1600 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "d6f68b1c-a6a6-44d4-8686-dc4dcdde4767", +"name": "output", +"type": "string", +"value": "={{ $json.output }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "1064a2bf-bf74-44cd-ba8a-48f93700e887", +"name": "Window Buffer Memory", +"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow", +"position": [ +1140, +2000 +], +"parameters": { +"sessionKey": "={{ $('When chat message received').item.json.sessionId }}", +"sessionIdType": "customKey", +"contextWindowLength": 50 +}, +"typeVersion": 1.3 +}, +{ +"id": "280fe3b1-faca-41b6-be0e-2ab906cd1662", +"name": "Save Long Term Memories", +"type": "n8n-nodes-base.googleDocsTool", +"position": [ +1460, +2000 +], +"parameters": { +"actionsUi": { +"actionFields": [ +{ +"text": "={ \n \"memory\": \"{{ $fromAI('memory') }}\",\n \"date\": \"{{ $now }}\"\n}", +"action": "insert" +} +] +}, +"operation": "update", +"documentURL": "[Google Doc ID]", +"descriptionType": "manual", +"toolDescription": "Save Memory" +}, +"credentials": { +"googleDocsOAuth2Api": { +"id": "YWEHuG28zOt532MQ", +"name": "Google Docs account" +} +}, +"typeVersion": 2 +}, +{ +"id": "37baa147-120a-40a8-b92f-df319fc4bc46", +"name": "Retrieve Long Term Memories", +"type": "n8n-nodes-base.googleDocs", +"position": [ +20, +1420 +], +"parameters": { +"operation": "get", +"documentURL": "[Google Doc ID]" +}, +"credentials": { +"googleDocsOAuth2Api": { +"id": "YWEHuG28zOt532MQ", +"name": "Google Docs account" +} +}, +"typeVersion": 2, +"alwaysOutputData": true +}, +{ +"id": "b047a271-d2aa-4a26-b663-6a76d249824a", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +720, +1840 +], +"parameters": { +"color": 3, +"width": 280, +"height": 380, +"content": "## LLM" +}, +"typeVersion": 1 +}, +{ +"id": "15bb5fd5-7dfe-4da9-830c-e1d905831640", +"name": "Telegram Response", +"type": "n8n-nodes-base.telegram", +"position": [ +1440, +1260 +], +"parameters": { +"text": "={{ $json.output }}", +"chatId": "=1234567891", +"additionalFields": { +"parse_mode": "HTML", +"appendAttribution": false +} +}, +"credentials": { +"telegramApi": { +"id": "pAIFhguJlkO3c7aQ", +"name": "Telegram account" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "8cc38a87-e214-4193-9fe6-ba4adc3d5530", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1360, +1160 +], +"parameters": { +"width": 260, +"height": 300, +"content": "## Telegram \n(Optional)" +}, +"typeVersion": 1 +}, +{ +"id": "38121a81-d768-4bb0-a9e6-39de0906e026", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +680, +1500 +], +"parameters": { +"color": 5, +"width": 1320, +"height": 780, +"content": "## AI AGENT with Long Term Memory & Note Storage" +}, +"typeVersion": 1 +}, +{ +"id": "7d5d1466-b4c9-4055-a634-ea7025dc370a", +"name": "DeepSeek-V3 Chat", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +820, +2060 +], +"parameters": { +"model": "=deepseek-chat", +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "MSl7SdcvZe0SqCYI", +"name": "deepseek" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "68303b67-2203-41e8-b370-220d884d2945", +"name": "AI Tools Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +1060, +1600 +], +"parameters": { +"text": "={{ $('When chat message received').item.json.chatInput }}", +"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. \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. **Note Management**: \n - If the user provides information that is intended to be stored as a note (e.g., specific instructions, reminders, or standalone pieces of information), use the **Save Note** tool. \n - Notes should not be stored in memory using the **Save Memory** tool. \n - Ensure that notes are clear, concise, and accurately reflect the user’s input. \n\n3. **Context Awareness**: \n - Use stored memories and notes to provide contextually relevant and personalized responses. \n - Always consider the **date and time** when a memory or note was collected to ensure your responses are up-to-date and accurate.\n\n4. **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 or notes when appropriate but avoid overwhelming the user with unnecessary information.\n\n5. **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 - Never store passwords or usernames.\n\n6. **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 fallback 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### Save Note \n- Use this tool to store specific instructions, reminders, or standalone pieces of information provided by the user. \n- Notes should not include general personal preferences or habits meant for long-term memory storage. \n- Ensure that notes are concise and accurately reflect what the user wants to store.\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**{{ $json.data[0].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## NOTES \n\n### Recent Notes Collected from User: \nHere are the most recent notes collected from the user: \n\n**{{ $json.data[1].content }}**\n\n### Guidelines for Using Notes: \n- Use notes for tasks requiring specific instructions or reminders.\n- Do not mix note content with general memory content; keep them distinct.\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": false +}, +{ +"id": "a6741133-93a1-42f8-83b4-bc29b9f49ae2", +"name": "Sticky Note10", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1680, +1840 +], +"parameters": { +"color": 4, +"width": 280, +"height": 380, +"content": "## Save Notes\nGoogle Docs" +}, +"typeVersion": 1 +}, +{ +"id": "87c88d31-811d-4265-b44e-ab30a45ff88b", +"name": "Save Notes", +"type": "n8n-nodes-base.googleDocsTool", +"position": [ +1780, +2000 +], +"parameters": { +"actionsUi": { +"actionFields": [ +{ +"text": "={ \n \"note\": \"{{ $fromAI('memory') }}\",\n \"date\": \"{{ $now }}\"\n}", +"action": "insert" +} +] +}, +"operation": "update", +"documentURL": "[Google Doc ID]", +"descriptionType": "manual", +"toolDescription": "Save Notes" +}, +"credentials": { +"googleDocsOAuth2Api": { +"id": "YWEHuG28zOt532MQ", +"name": "Google Docs account" +} +}, +"typeVersion": 2 +}, +{ +"id": "b9b97837-d6f2-4cef-89c4-9301973015df", +"name": "Sticky Note11", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-100, +1680 +], +"parameters": { +"color": 4, +"width": 340, +"height": 380, +"content": "## Retrieve Notes\nGoogle Docs" +}, +"typeVersion": 1 +}, +{ +"id": "0002a227-4240-4d3c-9a45-fc6e23fdc7f5", +"name": "Retrieve Notes", +"type": "n8n-nodes-base.googleDocs", +"onError": "continueRegularOutput", +"position": [ +20, +1820 +], +"parameters": { +"operation": "get", +"documentURL": "[Google Doc ID]" +}, +"credentials": { +"googleDocsOAuth2Api": { +"id": "YWEHuG28zOt532MQ", +"name": "Google Docs account" +} +}, +"typeVersion": 2, +"alwaysOutputData": true +}, +{ +"id": "88f7024c-87d4-48b4-b6bb-f68c88202f56", +"name": "Aggregate", +"type": "n8n-nodes-base.aggregate", +"position": [ +520, +1600 +], +"parameters": { +"options": {}, +"aggregate": "aggregateAllItemData" +}, +"typeVersion": 1 +}, +{ +"id": "48d576fc-870a-441e-a7be-3056ef7e1d7a", +"name": "Merge", +"type": "n8n-nodes-base.merge", +"position": [ +340, +1600 +], +"parameters": {}, +"typeVersion": 3 +} +], +"active": false, +"pinData": {}, +"settings": { +"timezone": "America/Vancouver", +"callerPolicy": "workflowsFromSameOwner", +"executionOrder": "v1" +}, +"versionId": "8130e77c-ecbd-470e-afec-ec8728643e00", +"connections": { +"Merge": { +"main": [ +[ +{ +"node": "Aggregate", +"type": "main", +"index": 0 +} +] +] +}, +"Aggregate": { +"main": [ +[ +{ +"node": "AI Tools Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Save Notes": { +"ai_tool": [ +[ +{ +"node": "AI Tools Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"gpt-4o-mini": { +"ai_languageModel": [ +[ +{ +"node": "AI Tools Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"AI Tools Agent": { +"main": [ +[ +{ +"node": "Telegram Response", +"type": "main", +"index": 0 +}, +{ +"node": "Chat Response", +"type": "main", +"index": 0 +} +], +[] +] +}, +"Retrieve Notes": { +"main": [ +[ +{ +"node": "Merge", +"type": "main", +"index": 1 +} +] +] +}, +"DeepSeek-V3 Chat": { +"ai_languageModel": [ +[] +] +}, +"Telegram Response": { +"main": [ +[] +] +}, +"Window Buffer Memory": { +"ai_memory": [ +[ +{ +"node": "AI Tools Agent", +"type": "ai_memory", +"index": 0 +} +] +] +}, +"Save Long Term Memories": { +"ai_tool": [ +[ +{ +"node": "AI Tools Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"When chat message received": { +"main": [ +[ +{ +"node": "Retrieve Long Term Memories", +"type": "main", +"index": 0 +}, +{ +"node": "Retrieve Notes", +"type": "main", +"index": 0 +} +] +] +}, +"Retrieve Long Term Memories": { +"main": [ +[ +{ +"node": "Merge", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file