AutomationFlowsAI & RAG › Discover & Analyze N8n Workflows From Github with Openai and Google Sheets

Discover & Analyze N8n Workflows From Github with Openai and Google Sheets

ByYusuke @yusuke-matsuba on n8n.io

Discover and analyze the most valuable community-built n8n workflows on GitHub. This automation searches public repositories, analyzes JSON workflows using AI, and saves a ranked report to Google Sheets — including summaries, use cases, difficulty, stars, node count, and…

Cron / scheduled trigger★★★★☆ complexityAI-powered20 nodesNotionHTTP RequestAgentOpenAI ChatOutput Parser StructuredGoogle Sheets
AI & RAG Trigger: Cron / scheduled Nodes: 20 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #10538 — we link there as the canonical source.

This workflow follows the Agent → Google Sheets recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "422d9d8c-60a6-4b05-b608-7180436c5085",
      "name": "Create a database page",
      "type": "n8n-nodes-base.notion",
      "position": [
        576,
        224
      ],
      "parameters": {
        "options": {},
        "resource": "databasePage",
        "databaseId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "credentials": {
        "notionApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "7e30dccc-90f1-4d1f-beaf-53d80bff07b0",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1792,
        128
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "3816aa60-8b5f-4bfb-8bf1-c6b409cc3cc5",
      "name": "Config1",
      "type": "n8n-nodes-base.set",
      "position": [
        -1568,
        128
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={\n  \"search_query\": \"extension:json n8n in:file\",\n  \"max_results\": 50,\n  \"ai_analysis_top\": 10,\n  \"SPREADSHEET_ID\": \"YOUR_SHEET_ID\",\n  \"SHEET_NAME\": \"Sheet1\"\n}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "4a1a3eb6-1152-47c2-89ea-b803a5f8f4a0",
      "name": "GitHub Search1",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1344,
        128
      ],
      "parameters": {
        "url": "https://api.github.com/search/code",
        "options": {
          "timeout": 15000
        },
        "sendQuery": true,
        "sendHeaders": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "q",
              "value": "={{ $('Config1').item.json.search_query }}"
            },
            {
              "name": "per_page",
              "value": "={{ $('Config1').item.json.max_results }}"
            },
            {
              "name": "sort",
              "value": "indexed"
            },
            {
              "name": "order",
              "value": "desc"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Accept",
              "value": "application/vnd.github.v3+json"
            },
            {
              "name": "User-Agent",
              "value": "n8n-workflow-finder"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "427ec2cf-36fe-4ec7-b29b-1a3714b1b2f3",
      "name": "Split Results1",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -1120,
        128
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "items"
      },
      "typeVersion": 1
    },
    {
      "id": "2f4c107f-bdbe-4dfd-8749-b03cf29cfca2",
      "name": "Fetch Workflow JSON1",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -896,
        128
      ],
      "parameters": {
        "url": "={{ $json.url }}",
        "options": {
          "timeout": 15000,
          "response": {
            "response": {
              "responseFormat": "text"
            }
          }
        },
        "sendHeaders": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "Accept",
              "value": "application/vnd.github.v3.raw"
            },
            {
              "name": "User-Agent",
              "value": "n8n-workflow-finder"
            }
          ]
        }
      },
      "typeVersion": 4.2,
      "continueOnFail": true
    },
    {
      "id": "9df2b0ad-e26c-4658-8241-94993149b904",
      "name": "Process Workflows1",
      "type": "n8n-nodes-base.code",
      "position": [
        -672,
        128
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\nconst splitItems = $('Split Results1').all();\nconst results = [];\nfor (let i = 0; i < items.length; i++) {\n  const item = items[i];\n  const splitItem = splitItems[i];\n  const repo = splitItem?.json?.repository;\n  if (!repo) continue;\n  try {\n    let txt = item.json.data || item.json;\n    let wf = null;\n    if (typeof txt === 'string') {\n      try { wf = JSON.parse(txt); } catch { continue; }\n    } else if (typeof txt === 'object' && txt.nodes) {\n      wf = txt;\n    } else { continue; }\n    const nodes = wf?.nodes || [];\n    if (!nodes.length) continue;\n    const filePath = splitItem.json.path || '';\n    const workflowName = wf.name || filePath.split('/').pop().replace(/\\.json$/,'') || 'Untitled Workflow';\n    const nodeTypes = [...new Set(nodes.map(n => n.type).filter(Boolean))];\n    const nodeTypeNames = nodeTypes.map(t => String(t).toLowerCase());\n    const hasAI = nodeTypeNames.some(t => t.includes('openai') || t.includes('langchain') || t.includes('agent') || t.includes('anthropic') || t.includes('gemini') || t.includes('groq') || t.includes('claude'));\n    const keyNodes = nodes.slice(0,3).map(n => n.name).filter(Boolean).join(', ');\n    results.push({ json: {\n      workflow_name: workflowName,\n      repository: repo.full_name || '',\n      stars: repo.stargazers_count || 0,\n      nodes: nodes.length,\n      node_types: nodeTypes.length,\n      has_ai: hasAI ? 'Yes' : 'No',\n      key_nodes: keyNodes || 'N/A',\n      description: (repo.description || '').substring(0,200),\n      repo_url: repo.html_url || '',\n      file_url: splitItem.json.html_url || '',\n      _sort_stars: repo.stargazers_count || 0\n    }});\n  } catch {}\n}\nresults.sort((a,b)=>b.json._sort_stars-a.json._sort_stars);\nreturn results.length ? results : [{json:{error:'No workflows found',message:'Adjust the search query'}}];"
      },
      "typeVersion": 2
    },
    {
      "id": "ac6d2def-02c9-47e9-b5fb-a3a2cc7e597a",
      "name": "Aggregate All1",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        -448,
        128
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "341aae78-be07-49e1-915c-f00aab142c06",
      "name": "Prepare AI Analysis1",
      "type": "n8n-nodes-base.code",
      "position": [
        -224,
        128
      ],
      "parameters": {
        "jsCode": "let workflows = $json.data || [];\nlet topCount = ($nodes['Config'].data?.json?.ai_analysis_top) || 10;\nconst toS = v => (v==null?'':String(v));\nconst clean = (s,max=240)=>toS(s).replace(/[^\\x00-\\x7F]/g,'').replace(/\\s+/g,' ').trim().slice(0,max);\nconst n = v => Number.isFinite(Number(v))?Number(v):0;\nconst top = workflows.slice(0, topCount);\nconst items = top.map((w,i)=>`${i+1}. ${clean(w.workflow_name,120)}\\n   Repository: ${clean(w.repository,120)}\\n   Nodes: ${n(w.nodes)}, Stars: ${n(w.stars)}\\n   Key Nodes: ${clean(w.key_nodes,160)}\\n   Description: ${clean(w.description,220)}`);\nconst prompt = `Analyze the following n8n workflows and provide brief insights.\\nAlways respond in ENGLISH (en-US) only. If any input text is not English, translate it to concise English first.\\n\\n${items.join('\\n\\n')}\\n\\nFor each workflow, provide:\\n- description: one sentence (<= 25 words)\\n- use_case: one sentence (<= 20 words)\\n- difficulty: one of [\"Beginner\",\"Intermediate\",\"Advanced\"]\\n\\nSTRICT OUTPUT REQUIREMENTS:\\n- Return ONLY a valid JSON array (no markdown)\\n- ASCII characters only\\n- Schema example: [{\"index\":1,\"description\":\"...\",\"use_case\":\"...\",\"difficulty\":\"Beginner\"}]`;\nreturn [{json:{prompt, all_workflows:workflows, analyzed_count: top.length, total_count: workflows.length}}];"
      },
      "typeVersion": 2
    },
    {
      "id": "9782df9b-1a17-4630-aa12-74cedb62fb1f",
      "name": "AI Analysis1",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        0,
        128
      ],
      "parameters": {
        "text": "={{ $json.prompt }}",
        "options": {
          "systemMessage": "You are a workflow analyst. Return ONLY a valid JSON array where each item has exactly: index (int), description (string), use_case (string), difficulty (\"Beginner\"|\"Intermediate\"|\"Advanced\"). No extra fields or prose."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.6
    },
    {
      "id": "24386018-3b8b-4ac6-a80c-f3cee3c68356",
      "name": "OpenAI Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        16,
        352
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "24ba95a3-73f5-44a1-82d4-7a4965b16a1d",
      "name": "Structured Output Parser1",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        144,
        352
      ],
      "parameters": {
        "jsonSchemaExample": "[{\"index\":1,\"description\":\"string\",\"use_case\":\"string\",\"difficulty\":\"Beginner|Intermediate|Advanced\"}]"
      },
      "typeVersion": 1.2
    },
    {
      "id": "a8305a37-6dd2-4c74-9a0a-9a2a812cb237",
      "name": "Merge AI Results1",
      "type": "n8n-nodes-base.code",
      "position": [
        352,
        128
      ],
      "parameters": {
        "jsCode": "const aiOutput = $input.first().json; const prep = $('Prepare AI Analysis1').first().json; const all = prep.all_workflows||[]; const topN = Number(prep.analyzed_count||0);\nlet arr=[]; try{const raw=aiOutput.output??aiOutput; arr=Array.isArray(raw)?raw:JSON.parse(raw);}catch{arr=[]}\nconst map=new Map(); for(const it of arr){ if(it&&Number.isFinite(Number(it.index))) map.set(Number(it.index)-1,it); }\nconst S=v=>v==null?'':String(v); const clean=s=>S(s).replace(/[^\\x00-\\x7F]/g,'').replace(/\\s+/g,' ').trim();\nreturn all.map((wf,i)=>{ const a=i<topN?map.get(i):undefined; const aiDesc=clean(a?.description||''); const finalDesc=clean(wf.description||'')||aiDesc; const use=i<topN?clean(a?.use_case||''):''; const diff=i<topN?clean(a?.difficulty||''):'';\n  return {json:{workflow_name:wf.workflow_name,repository:wf.repository,stars:wf.stars,nodes:wf.nodes,node_types:wf.node_types,has_ai:wf.has_ai,key_nodes:wf.key_nodes,description:finalDesc,repo_url:wf.repo_url,file_url:wf.file_url,ai_description:aiDesc,ai_use_case:use,ai_difficulty:diff}}; });"
      },
      "typeVersion": 2
    },
    {
      "id": "90b1957e-816a-451a-a0ea-4b15de25dae9",
      "name": "Save to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        576,
        32
      ],
      "parameters": {
        "columns": {
          "value": {
            "Nodes": "={{ $json.nodes }}",
            "Stars": "={{ $json.stars }}",
            "File URL": "={{ $json.file_url }}",
            "Repo URL": "={{ $json.repo_url }}",
            "Use Case": "={{ $json.ai_use_case }}",
            "Workflow": "={{ $json.workflow_name }}",
            "Key Nodes": "={{ $json.key_nodes }}",
            "AI Powered": "={{ $json.has_ai }}",
            "AI Summary": "={{ $json.description }}",
            "Difficulty": "={{ $json.ai_difficulty }}",
            "Node Types": "={{ $json.node_types }}",
            "Repository": "={{ $json.repository }}"
          },
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Workflow"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": "={{ $('Config1').item.json.SHEET_NAME }}",
        "documentId": "={{ $('Config1').item.json.SPREADSHEET_ID }}"
      },
      "typeVersion": 4.5
    },
    {
      "id": "797c78a7-d273-430b-9a36-9b3305a783b4",
      "name": "Sticky: Overview (yellow)",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2480,
        -496
      ],
      "parameters": {
        "color": 7,
        "width": 560,
        "height": 456,
        "content": "## Overview \u2013 GitHub n8n Workflow Analyzer\n\n**What this workflow does**  \n- Finds public n8n workflows on GitHub  \n- Analyzes them with AI to add a short description, use case, and difficulty  \n- Saves everything into Google Sheets (+ optional Notion DB) for later review\n\n**Why this is useful**  \n- Saves hours of manually browsing repos and opening JSON files one by one  \n- Gives you a curated \u201cinspiration database\u201d of real n8n workflows  \n- Helps creators spot patterns, AI usage, and ideas worth turning into templates\n\n**High-level flow**  \n1. Schedule trigger starts the run (or execute manually while testing)  \n2. GitHub search finds n8n JSON files  \n3. Code nodes parse workflows and detect AI-related nodes  \n4. LLM summarizes the most interesting ones  \n5. Results are logged to Google Sheets and optionally mirrored into Notion"
      },
      "typeVersion": 1
    },
    {
      "id": "68335719-9bc1-4a17-8704-e8f43747d310",
      "name": "Sticky: Step 1 \u2014 Fetch & Parse",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1696,
        -304
      ],
      "parameters": {
        "width": 672,
        "height": 304,
        "content": "## STEP 1 \u2013 Fetch & Parse Workflows\n\n**What happens here**  \n- `Schedule Trigger` runs this on a cadence (or via manual execute).  \n- `Config1` holds the search query, result limit, and spreadsheet settings.  \n- `GitHub Search1` searches for public n8n JSON files.  \n- `Split Results1` + `Fetch Workflow JSON1` download each file.  \n- `Process Workflows1` parses JSON, counts nodes, and flags AI-powered flows.\n\n**Why this section matters**  \n- Keeps all search settings in one place so you can tweak scope without editing nodes.  \n- Ensures only valid n8n workflows move forward to AI analysis."
      },
      "typeVersion": 1
    },
    {
      "id": "867f6b02-8731-4d0f-a1e9-abb12a38be41",
      "name": "Sticky: Step 2 \u2014 AI Analysis",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -752,
        -304
      ],
      "parameters": {
        "width": 592,
        "height": 352,
        "content": "## STEP 2 \u2013 AI Analysis\n\n**What happens here**  \n- `Aggregate All1` collects all parsed workflows.  \n- `Prepare AI Analysis1` builds a compact prompt from the top N workflows.  \n- `AI Analysis1` (LLM + structured parser) returns JSON with:  \n  - `description` \u2013 one-sentence summary  \n  - `use_case` \u2013 what the workflow is good for  \n  - `difficulty` \u2013 Beginner / Intermediate / Advanced  \n- `Merge AI Results1` combines AI insights back into each workflow record.\n\n**Why this section matters**  \n- Converts raw technical JSON into human-readable insights.  \n- The structured output parser keeps the data clean so Sheets/Notion stay reliable."
      },
      "typeVersion": 1
    },
    {
      "id": "c5a9bf2a-ba46-4c6d-8878-869572c7cb7e",
      "name": "Sticky: Step 3 \u2014 Save & Share",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        144,
        -288
      ],
      "parameters": {
        "width": 752,
        "height": 272,
        "content": "## STEP 3 \u2013 Save & Share\n\n**What happens here**  \n- `Save to Google Sheets` appends or updates rows with the latest analysis.  \n- Each row includes stars, node count, AI flag, difficulty, and links.  \n- `Create a database page` (Notion) can mirror selected workflows into a Notion DB.\n\n**Why this section matters**  \n- Google Sheets acts as your living catalog of interesting n8n workflows.  \n- Optional Notion sync lets you review, tag, and curate workflows for content, docs, or team sharing."
      },
      "typeVersion": 1
    },
    {
      "id": "4dce4b29-cbec-44b4-a18a-0e70f4a9dedc",
      "name": "Sticky: Setup Checklist",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2480,
        16
      ],
      "parameters": {
        "color": 4,
        "width": 592,
        "height": 476,
        "content": "## Setup checklist (3\u20135 minutes)\n\n1\ufe0f\u20e3 **GitHub credentials**  \n- Add `Authorization: Bearer <token>` in both `GitHub Search1` and `Fetch Workflow JSON1`.  \n- Use a personal access token with `repo` and `code` read permissions.\n\n2\ufe0f\u20e3 **OpenAI / LLM**  \n- Connect credentials in `OpenAI Chat Model1` (or swap in another supported model).  \n- Keep `ai_analysis_top` modest (e.g. 10) to control token usage.\n\n3\ufe0f\u20e3 **Google Sheets**  \n- In `Config1`, set `SPREADSHEET_ID` and `SHEET_NAME`.  \n- Make sure the sheet has matching column names (Workflow, Stars, Nodes, etc.).\n\n4\ufe0f\u20e3 **Notion (optional)**  \n- Connect your Notion credential.  \n- Select the database in `Create a database page` to store curated entries.\n\n5\ufe0f\u20e3 **First run**  \n- Start with a small `max_results` (10\u201320) and execute manually to verify everything works before scheduling."
      },
      "typeVersion": 1
    },
    {
      "id": "4112f328-b6f6-4b75-a327-c8a83d1e3a1f",
      "name": "Sticky: Troubleshooting1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2512,
        576
      ],
      "parameters": {
        "color": 5,
        "width": 668,
        "height": 372,
        "content": "## Troubleshooting\n\n- **401 / 403 from GitHub**  \n  \u2192 Check your token, scopes, and `Authorization` header in both GitHub nodes.\n\n- **Empty or \u201cNo workflows found\u201d**  \n  \u2192 Relax the search query in `Config1` or increase `max_results`.\n\n- **LLM / JSON errors**  \n  \u2192 Lower `ai_analysis_top` or shorten the prompt in `Prepare AI Analysis1`.\n\n- **Rows not updating in Sheets**  \n  \u2192 Confirm column names match exactly and that `Workflow` is used as the key.\n\n\ud83d\udcd8 Security tip: keep all tokens in n8n Credentials \u2014 never hardcode keys inside Code nodes or Set nodes."
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Config1": {
      "main": [
        [
          {
            "node": "GitHub Search1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Analysis1": {
      "main": [
        [
          {
            "node": "Merge AI Results1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate All1": {
      "main": [
        [
          {
            "node": "Prepare AI Analysis1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GitHub Search1": {
      "main": [
        [
          {
            "node": "Split Results1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Results1": {
      "main": [
        [
          {
            "node": "Fetch Workflow JSON1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Config1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge AI Results1": {
      "main": [
        [
          {
            "node": "Save to Google Sheets",
            "type": "main",
            "index": 0
          },
          {
            "node": "Create a database page",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "AI Analysis1",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Process Workflows1": {
      "main": [
        [
          {
            "node": "Aggregate All1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Workflow JSON1": {
      "main": [
        [
          {
            "node": "Process Workflows1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare AI Analysis1": {
      "main": [
        [
          {
            "node": "AI Analysis1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser1": {
      "ai_outputParser": [
        [
          {
            "node": "AI Analysis1",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

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

About this workflow

Discover and analyze the most valuable community-built n8n workflows on GitHub. This automation searches public repositories, analyzes JSON workflows using AI, and saves a ranked report to Google Sheets — including summaries, use cases, difficulty, stars, node count, and…

Source: https://n8n.io/workflows/10538/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

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

AI & RAG

This n8n automation workflow automates the creation, scripting, production, and posting of YouTube videos. It leverages AI (OpenAI), image generation (PIAPI), video rendering (Shotstack), and platform

Agent, OpenAI Chat, Airtable Tool +7
AI & RAG

This workflow is designed for: Content creators and marketers E-commerce and product-based businesses Agencies producing social media visuals and videos Automation builders looking for AI-powered crea

HTTP Request, Edit Image, Google Drive +7
AI & RAG

Generate product images with NanoBanana Pro to Veo videos and Blotato - vide 2 ok. Uses httpRequest, editImage, googleDrive, googleSheets. Scheduled trigger; 76 nodes.

HTTP Request, Edit Image, Google Drive +7
AI & RAG

Created by: Peyton Leveillee Last updated: October 2025

OpenAI Chat, Google Sheets, HTTP Request +5
AI & RAG

SEO Blog Article Generation Workflow. Uses outputParserStructured, httpRequest, agent, lmChatOpenAi. Scheduled trigger; 56 nodes.

Output Parser Structured, HTTP Request, Agent +4