ChatGPTCreativeWritingAI score · PendingAI-assisted edit · no obvious prompt-injection riskn8n.io

Auto-Categorize Blog Posts with GPT-4, GitHub & Google Sheets in n8n

Read Markdown posts from a GitHub repo → compare against a Google Sheets log to find new articles → AI Agent analyzes content and outputs structured category/tag suggestions → append results to Google Sheets for review

Some experienceStepsWorkflowPromptTip
Who
Content creators, SEO specialists, or dev teams running a static blog (Astro/Next.js) on GitHub who want AI-assisted metadata tagging.
You get
Identifies new, unanalyzed articles; uses an AI Agent to read frontmatter and body, then proposes categories and tags, logging everything to Google Sheets without reprocessing old posts.
You need
n8n · GitHub · Google Sheets

Constraints

Prerequisites: an n8n instance; credentials openAiApi, githubApi, and googleSheetsOAuth2Api configured. A Google Sheet with columns FileName, Categories, Proposed Categories, Tags, Proposed Tags must exist. GitHub repo should store .md/.mdx blog posts. Costs depend on OpenAI API usage and n8n hosting.

What they did

Author argone published an n8n official template that automatically assigns categories and tags to Astro/Next.js static blog posts stored in a GitHub repository. The workflow starts with a Form Trigger, reads existing records from Google Sheets and lists repo files in parallel, uses Code nodes to diff the two lists and find unprocessed articles, then passes each new article through an AI Agent (OpenAI GPT-4.1-mini with LangChain Memory and Structured Output Parser) to analyze frontmatter and body, and finally appends the proposed metadata to Google Sheets. Sticky Notes are included throughout to document each section.

How it went

No specific runtime metrics or accuracy figures are provided by the source. The template page shows 319 total views at time of collection; actual articles processed or tag-consistency scores are not reported.

Worth knowing

1. The default model is gpt-4.1-mini, but the OpenAI Chat Model node supports switching to gpt-4.1 or gpt-4 (user must select manually). 2. The workflow only writes suggestions to Google Sheets; it does not modify GitHub files automatically. To enable auto write-back, add a GitHub Commit node yourself. 3. The AI Agent systemMessage includes a concrete article example (Grace Hopper/debug); this serves as a format reference only—the Agent processes the actual incoming article content at runtime. 4. The two Code nodes handle deduplication and set difference; losing either would cause duplicate analysis. 5. This site has not imported or executed the workflow (reproduction=not_tested). After building, test with a single article first to verify Switch branching and Sheets output.

n8n workflow template

Structure checked · Not run-tested

Use “Import from File” in n8n, or copy the JSON and paste it into the editor. Connect your own accounts, then try test data. The template is inactive by default.

Setup and test checklist

Credentials to connect

  • OpenAI Chat Model node: connect OpenAI API credentials.
  • List posts/articles/pages node: connect GitHub API credentials.
  • Append rows with posts / article analysis node: connect Google Sheets OAuth2 credentials.
  • Get post/article file node: connect GitHub API credentials.
  • Get row(s) in sheet node: connect Google Sheets OAuth2 credentials.

Configuration to replace

  • Source template is n8n public workflow #9983 (~29 nodes). Keep inactive after import; verify triggers, expressions and external API endpoints.
  • Sticky-note guidance is informational; replace placeholders with your own accounts, sheet schemas or channel IDs.

Test input and expected output

  • Manually run the main path once in a test workspace and confirm credentialed nodes authenticate without errors.
  • Drive one synthetic/redacted sample through and check output fields and downstream writes before enabling in production.

Template changes

  • Author credential bindings, webhookId and execution data are removed; the workflow is inactive. Nodes, connections and original prompts are preserved. Not run-tested in n8n.
  • No business-logic edits; verify keys, quotas and privacy compliance before use.

Template retrieved: 2026-10-24

Steps

  1. Prepare data sources: read Google Sheets and list GitHub files

    Run two branches in parallel: 1) Google Sheets node reads existing records (Get row(s) in sheet), then a Code node extracts FileName and removes duplicates, followed by an Aggregate node to build the googlesheetsPaths array. 2) GitHub node lists .md/.mdx files in the target repo path (List posts/articles/pages), then an Aggregate node builds the githubPaths array. You should see: two arrays—one with filenames already logged, the other with all current article paths from the repo.

  2. Compare and identify new articles

    Merge the two arrays, then use a Code node (Check new repo files for AI processing) to compute the difference: paths present in githubPaths but not in googlesheetsPaths. A Switch node checks if the result is empty. - If empty (no new posts), the workflow ends at a Form node showing "List is empty". - If not empty, continue to the next step. You should see: an array containing only the paths of unprocessed articles.

    Execution prompt · Source text。n8n Code node 'Check new repo files for AI processing' JS Code field

    const allItems = $input.all();
    
    // Extract arrays 
    const googlePaths = allItems.find(i => i.json.googlesheetsPaths)?.json.googlesheetsPaths || [];
    const githubPaths = allItems.find(i => i.json.githubPaths)?.json.githubPaths || [];
    
    // Compute difference: elements in githubPaths not in googlesheetsPaths
    const difference = githubPaths.filter(path => !googlePaths.includes(path));
    
    // Return as n8n item array
    return difference.map(path => ({ json: { path } }));
  3. Fetch each article's content

    Feed the new-article path array into a Split In Batches node (Loop Over Posts/Pages) to process one at a time. Each path is passed to a GitHub node (Get post/article file) that dynamically reads $json.path. You should see: each batch outputs the full Markdown source (frontmatter + body) of one article.

  4. AI Agent analyzes and proposes categories and tags

    Send the article content to the AI Agent node, which connects to: - OpenAI Chat Model (model set to gpt-4.1-mini, responseFormat set to json_object) - Simple Memory (contextWindowLength=2, for contextual consistency across batches) - Structured Output Parser (to enforce output shape) The Agent's systemMessage defines the task: parse frontmatter, suggest new categories and tags based on content, and return the result in a specific JSON format.

    Execution prompt · Source text。n8n AI Agent node Options > System Message field

    You are a helpful assistant which helps to assign proper tags and categories for post. Example of post is added in section <post>.  
    
    Each post has a section which starts with "---" and ands with next ocurance of "---". This section is metadata which describes the post. After second ocurance of "---" file has a content. 
    
    Read tags and categories and assign them to <tags> and <categories> variables used later in response.
    
    Based on content please provide categories assigned to <new_assigned_categories> and tags list assigned to <new_assigned_tags> as example below:
    
    <example>
    categories: ["business"] 
    tags: ["DigitalGirls", "ITPioneers", "WomenInIT", "IT", "FemalePower", "Debugging", "GraceHopper"] 
    </example>
    
    Final result should be post with updated metadata passed to variable <content>.
    
    <post> 
    --- 
    title: "Where Did the Term ‘Debug’ Come From? – Women in IT" 
    pubDate: 2024-07-23 description: "Did you know that the term ‘debug’ was coined by Admiral Grace Hopper?" 
    categories: ["business"] 
    tags: ["DigitalGirls", "ITPioneers", "WomenInIT", "IT", "FemalePower", "Debugging", "GraceHopper"] 
    coverImage: "@assets/2024-07-23-skad-sie-wzielo-okreslenie-debug-kobiety-w-it.jpeg" 
    ---
    
    Did you know that the term debug was coined by Admiral Grace Hopper?
    While working on the Mark II computer at Harvard University, a moth got trapped in a relay, interfering with the machine’s operation. Removing the dead insect was humorously referred to by Admiral Hopper as debugging.
    
    PS. After a conversation with Wioletta Klimczak, I got my hands on the book “Digital Girls. Pioneers of Polish Computer Science” by Karolina Wasielewska. The story above comes from that book. It’s proof that women are an important part of the IT world!
    
    #DigitalGirls #ITPioneers #WomenInIT #IT #FemalePower #Debugging #GraceHopper
    </post>
  5. Parse structured output and map to sheet columns

    The AI Agent output is constrained by the Structured Output Parser to this JSON Schema: { "old_categories": ["category1"], "categories": ["category1","category2"], "old_tags": ["tag1","tag2"], "tags": ["tag1","tag2","tag3","tag4"] } In the Append rows node, map fields to Google Sheets columns: - FileName = {{ $('Get post/article file').item.json.path }} - Categories = {{ JSON.stringify($json.output.old_categories) }} - Proposed Categories = {{ JSON.stringify($json.output.categories) }} - Tags = {{ JSON.stringify($json.output.old_tags) }} - Proposed Tags = {{ JSON.stringify($json.output.tags) }} You should see: a new row appended to Google Sheets with original and proposed values.

    Setup guidance · Source text。Structured Output Parser node JSON Schema Example field; AI Agent output must match this shape

    {
      "old_categories": ["category1"],
      "categories": ["category1","category2"],
      "old_tags": ["tag1","tag2"],
      "tags": ["tag1","tag2","tag3","tag4"]
    }
  6. Loop until all posts are processed

    The Split In Batches node controls iteration: after each article, return to Loop Over Posts/Pages for the next batch. When complete, the workflow reaches a Form node displaying "Categories and tags added". You should see: every new article has a corresponding record in Google Sheets.

  7. Review and optional write-back (suggested)

    Manually review the Proposed Categories and Proposed Tags columns in Google Sheets. Once verified, update the blog frontmatter manually, or extend the workflow with a GitHub Commit node for automatic write-back (mentioned in source as a customization direction, not the template default).

Prompt you can copy

Setup guidance · Editorial suggestion。Give to a setup assistant to confirm inputs and permissions first

This block is the prompt. Ads are never placed here.

You are a setup assistant familiar with n8n and static-site content management. Help the user reproduce this workflow:

1. Prerequisites: confirm the user has an n8n instance, OpenAI API key, GitHub repo access, and Google Sheets OAuth2 credentials.
2. Guide the user to create a Google Sheet with five columns: FileName, Categories, Proposed Categories, Tags, Proposed Tags.
3. After importing the template from https://n8n.io/workflows/9983/, update the GitHub node's owner/repository/filePath to the user's actual repo path.
4. In the AI Agent node, the systemMessage already contains the task definition and example; to adjust categorization style, edit that field while keeping the Structured Output Parser JSON constraint intact.
5. For the first run, use the Form Trigger manually and check whether the Switch branches and Sheets output behave as expected.

Note: this prompt is an editorial setup starter, not a node-runtime prompt.

To change tagging style, edit the AI Agent systemMessage and ensure the output still matches the Structured Output Parser JSON Schema.

Source

Auto-categorize blog posts with OpenAI GPT-4, GitHub, and Google Sheets for Astro/Next.js · argone · n8n.io · 2025-10-21

Comments & feedback

Tried this method? Share results, problems or improvements. Comments appear after moderation. Please avoid sensitive information.

Loading…

    Related