Rank on Gemini and Chatgpt
Vicky.Dev
  • Tutorials
  • Tech
  • Camera & Photography
  • Themes
  • Plugins
  • SEO
  • Free Tools
  • Misc
  • Contact Me
No Result
View All Result
  • Tutorials
  • Tech
  • Camera & Photography
  • Themes
  • Plugins
  • SEO
  • Free Tools
  • Misc
  • Contact Me
No Result
View All Result
Vicky.Dev
No Result
View All Result

Automate WordPress Publishing with n8n and OpenAI

Vicky Bhandari by Vicky Bhandari
November 12, 2025
in Misc
0
Automate WordPress Publishing with n8n and OpenAI

Source: Unsplash

I was managing 15 WordPress sites and spending 20-30 hours weekly on content creation, editing, publishing, and image handling. The bottleneck was obvious: content production couldn’t scale without hiring writers or sacrificing quality.

I wondered what if I could automate WordPress publishing with n8n and Then I built something that changed everything: a fully automated AI-powered content system using n8n, OpenAI’s GPT-4, and WordPress REST API. Now the system publishes 720+ articles monthly across multiple sites while I focus on strategy and growth.

This isn’t theory. I’m going to show you the exact system I built, complete with the n8n workflow JSON, code snippets, costs, results, and everything you need to replicate it.

Fair warning: This is advanced automation. You’ll need technical comfort with APIs, JSON, and server management. But if you’re ready to scale content production 10x without hiring a team, keep reading.

Got it. Here’s your section rewritten in a clean, professional blog tone — no emojis, no m-dashes, just simple, clear English and proper formatting:


Table of Contents

Toggle
  • What This System Actually Does
    • The Result
  • The Complete System Architecture
    • Key design decisions
  • 2: Configuring GNews API Integration
    • Why GNews API?
    • Setting Up GNews API
  • 3: GNews API & Google Sheets Integration in n8n
    • GNews API Node Configuration
      • Configuration Details
  • 4. Google Sheets for Duplicate Prevention & Index Management
    • Setting Up Google Sheets
      • Sheet 1: Article Tracking (yoursite_post_check)
  • 5. Index Tracking Sheet (yoursite_index)
  • 6. Configuring Google Sheets Nodes in n8n
    • Node 1: Read Last Index
    • Node 2: Check for Duplicates
    • Node 3: Add New Article URL
    • Node 4: Update Index After Processing
  • 7. Duplicate Detection Logic (Code Node)
    • Why this approach works
  • 8. IF Node: Skip or Process
  • 9. OpenAI Integration and Prompt Engineering
    • Setting Up OpenAI API
  • 10. Why I Chose GPT-4o-mini
    • GPT-4o-mini stood out for a few key reasons
  • 11. The Rewriting Prompt That Actually Works
    • 1. Why This Prompt Works
    • 2. OpenAI Node Configuration in n8n
    • 3. Key processing logic
  • 12. WordPress REST API Integration
    • ⚙️ Preparing WordPress for the REST API
      • ✅ Method: Application Passwords (Recommended)
    • 1. Setting Up Authentication in n8n
    • 2. Body Parameters (from Code2 Node Output)
    • 3. Error Handling
  • 13. Image Processing & Upload
    • 🖼️ Step 1: Download the Image
    • ☁️ Step 2: Upload Image to WordPress
    • How This Works
    • Handling Image Upload Failures
  • Part 14: Complete Workflow Breakdown
    • Workflow Execution Flow
    • Workflow Timing
  • Ethical Considerations and Google’s Content Policies
    • My Approach to Ethical Automation
    • When NOT to Use This System
    • Do automate:
    • My understanding (not legal advice)
    • Troubleshooting Common Issues
    • Common Workflow Issues (and How to Fix Them)
      • Issue 1: Workflow Fails at the OpenAI Node
      • Issue 2: Images Fail to Upload
      • Issue 3: WordPress Authentication Fails
      • ⚙️ Issue 5: OpenAI Returns Invalid JSON
      • Issue 6: Google Sheets Quota Exceeded
      • Issue 7: Index Gets Out of Sync
    • Scaling to Multiple Sites
      • Multi-Site Architecture
      • Monitoring and Management
    • Legal and Compliance Considerations
      • DMCA and Copyright
      • GDPR and Data Privacy
      • Advertising Disclosures
      • 🔑 Terms of Service for APIs
      • 💭 Final Thoughts: Is This System Right for You?
    • My recommendation
    • What’s Next?

What This System Actually Does

Let’s be clear about what this system is. It is not a basic “post to WordPress when I publish on Medium” type of automation.

This setup is a complete AI-powered content pipeline that handles everything from fetching raw news to publishing fully formatted articles on WordPress without manual work.

Here is what happens automatically every two minutes:

  1. Fetches trending news articles from the GNews API across ten random categories.
  2. Retrieves the last processed article index from Google Sheets.
  3. Selects the next article from the current batch.
  4. Checks whether the article URL already exists in your database to prevent duplicates.

If the article is new, the workflow performs the following steps:

  1. Sends the raw content to OpenAI GPT-4o-mini.
  2. Rewrites the article completely in your preferred tone and style.
  3. Generates an SEO-friendly title and slug.
  4. Creates a short, clear excerpt for previews.
  5. Automatically assigns the article to the correct category.
  6. Downloads the original article’s featured image.
  7. Uploads that image to your WordPress media library.
  8. Creates a new WordPress post with proper formatting, category, and featured image.
  9. Updates Google Sheets with the article URL and increments the index.

If the article is a duplicate, it is skipped and the system moves to the next one.

The Result

Within a day, the system can publish between 24 and 30 original, high-quality articles across one or more WordPress sites. The process requires no manual intervention once configured. It operates quietly in the background, keeping your websites updated with fresh, SEO-ready content around the clock.

[convertkit form=8760512]

The Complete System Architecture

Before diving into implementation, let’s understand how all the pieces fit together.

Schedule Trigger (Every 2 minutes)
↓
Check WordPress Status (is automation enabled?)
↓
Interval Check (respect posting frequency limits)
↓
Random Category Selection
↓
GNews API → Fetch 100 articles
↓
Google Sheets → Get last processed index
↓
Pick Next Article from batch
↓
Prepare Metadata (extract title, content, URL)
↓
Google Sheets → Get all processed URLs
↓
Duplicate Check (does URL exist?)
YES → Skip, increment index, repeat
└─ NO → Continue to processing
↓
Add URL to Google Sheets (claim this article)
↓
OpenAI GPT-4o-mini → Rewrite article
↓
Process AI Response (parse JSON, validate)
↓
Download Featured Image
↓
Upload Image to WordPress Media Library
↓
Create WordPress Post (with image, category)
↓
Increment Index in Google Sheets

Key design decisions

Why Google Sheets for tracking? Could have used a database, but Sheets offers:

  • Visual debugging (see every processed URL)
  • No additional infrastructure
  • Easy manual intervention if needed
  • Free and reliable

Why check duplicates BEFORE OpenAI? Saves API costs. OpenAI charges per token, so checking duplicates first prevents wasting money rewriting articles we’ll discard.

Why increment the index regardless of success? Prevents infinite loops. If an article fails (bad image, API error), we still move forward rather than getting stuck retrying the same article.

Why schedule every 2 minutes instead of continuously? Respects API rate limits and allows monitoring. Also prevents WordPress from getting hammered if something goes wrong.

2: Configuring GNews API Integration

The system needs a constant stream of fresh content. I chose GNews API after testing News API, Mediastack, and NewsData.io.

Why GNews API?

Advantages:

  • 60,000+ news sources globally
  • Full article content included (expand=content parameter)
  • 100 results per request (vs competitors’ 10-20)
  • Fast response times (100-200ms average)
  • Clean, well-structured JSON
  • Reliable uptime
  • Pricing (as of November 2025):
  • Free plan: 100 requests/day (development only, NOT commercial)
  • Essential: $49/month, 10,00 requests/day
  • Business: $99/month, 5,000 requests/day
  • Enterprise: $249/month, 25,000 requests/day
  • My usage: ~1,500 reuests/month (fetching 100 articles every 2 days, cycling through) = Starter plan sufficient.

Setting Up GNews API

  • Sign up at gnews.io
  • Verify email
  • Subscribe to the Essential plan
  • Get your API key from the dashboard
  • Test the API:
    curl “https://gnews.io/api/v4/top-headlines?apikey=YOUR_API_KEY&lang=en&country=us&max=100&expand=content”

You should get JSON with 100 articles, including full content.


3: GNews API & Google Sheets Integration in n8n

In this part, we’ll configure two important pieces of the automation:

  1. GNews API — to fetch fresh, trending news articles.
  2. Google Sheets — to manage duplicates and track progress between executions.

GNews API Node Configuration

In your n8n workflow, start by adding an HTTP Request node.

Configuration Details

Method: GET
URL: https://gnews.io/api/v4/top-headlines

Query Parameters:

ParameterValueDescription
apikeyYOUR_API_KEYYour GNews API key
q={{ $json.category }}Pulls a random category from the previous node
langenEnglish articles
countryusOr replace with your target country
from={{ new Date(Date.now() - 48 * 60 * 60 * 1000).toISOString() }}Fetches articles from the last 48 hours
max100Number of articles per request
expandcontentCritical – includes full article text
page1Page number
sortbypublishedAtSorts by publication date

Options → Batching

  • Enable batching ✅
  • Batch size: 1
  • Batch interval: 3000ms (to avoid rate limits)

Why These Parameters Matter

  • expand=content gives you the entire article text, not just snippets. Without this, the OpenAI node won’t have enough data to rewrite effectively.
  • max=100 lets you fetch up to 100 articles per API call — enough for roughly two days of content if you post one article per execution.
  • The The from parameter ensures only recent (last 48 hours) news is used, keeping your site up to date.

Random Category Selection

To keep your content diverse, add a Code node before the API call to select a random category.

Here’s a simple example:

const categories = ["cat1", "cat2", "cat3", "cat4, "cat5", "cat6"];
const randomIndex = Math.floor(Math.random() * categories.length);
return [{ json: { category: categories[randomIndex] } }];

This ensures that each run fetches articles from a different topic, helping your content mix stay balanced and fresh.


4. Google Sheets for Duplicate Prevention & Index Management

Once the GNews data is flowing, you’ll need to make sure the same article isn’t published twice. Google Sheets will help you:

  1. Track every processed article.
  2. Store and update the current index to know which article comes next.

Setting Up Google Sheets

Sheet 1: Article Tracking (yoursite_post_check)

Create a simple sheet with one column:

A (Header)
url

This will store each processed article’s URL.

5. Index Tracking Sheet (yoursite_index)

Create a second sheet with two columns:

A (Header)B (Header)
last_indexrow_number
02
  • last_index tracks the current article number (0–99).
  • row_number is always 2 — the data row.

6. Configuring Google Sheets Nodes in n8n

  1. Add Google Sheets credentials and complete the OAuth flow.
  2. Grant n8n access to your sheets.

Node 1: Read Last Index

  • Operation: Read
  • Document: yoursite_index
  • Sheet: Sheet1
  • Range: A1:B2
  • Under Options → Data Location, specify range A1:A2

This retrieves the last processed index.


Node 2: Check for Duplicates

  • Operation: Read
  • Document: yoursite_post_check
  • Sheet: Sheet1
  • Options: Read all rows

This reads all previously processed URLs to avoid republishing them.


Node 3: Add New Article URL

  • Operation: Append
  • Document: yoursite_post_check
  • Sheet: Sheet1
  • Columns:
    • url: ={{ $json.news_url }}

This saves each new article URL once it’s processed.


Node 4: Update Index After Processing

  • Operation: Update
  • Document: yoursite_index
  • Sheet: Sheet1
  • Columns:
    • last_index: ={{ $json.last_index }}
    • row_number: ={{ $json.row_number }}
  • Match On: row_number

This ensures the system always knows where it left off after each post.


7. Duplicate Detection Logic (Code Node)

This piece of code ensures that your system never republishes the same article twice.

const metadata = $('Prepare Metadata').first().json || {};
let newsUrl = metadata.news_url?.trim().toLowerCase();

// Normalize trailing slash
if (newsUrl?.endsWith('/')) {
  newsUrl = newsUrl.slice(0, -1);
}

// Get all processed URLs from Google Sheets
const sheetUrls = $input.all()
  .map(item => item.json.url?.trim().toLowerCase())
  .filter(url => typeof url === 'string')
  .map(url => url.endsWith('/') ? url.slice(0, -1) : url);

// Check if current URL exists
const exists = sheetUrls.includes(newsUrl);

// Clean up unwanted headers
let cleaned_content = metadata.content || '';
cleaned_content = cleaned_content.replace(/^[A-Z\s\-–]+—\s+/i, '');

const title = metadata.title || '';

return [{
  json: {
    ...metadata,
    exists,
    title,
    cleaned_content
  }
}];

This node checks if the current article already exists in your Google Sheet.
If it does, it skips the post; if not, it cleans the content and moves to the publishing step.

Why this approach works

URL normalization (removing trailing slashes, lowercase) prevents false negatives where “example.com/article/” and “example.com/article” are treated as different URLs.

Checking the entire list is O(n), but with <10,000 URLs in the sheet, performance is negligible (<50ms).
Content cleaning removes common news article prefixes like “WASHINGTON — ” that bloat the rewritten content.

8. IF Node: Skip or Process

  • After duplicate check, add an IF node:
  • Condition: {{ $json.exists }} equals false
  • True path: Continue to OpenAI (new article)
  • False path: Skip to index increment (duplicate)
  • This ensures we only spend OpenAI credits on new content.

9. OpenAI Integration and Prompt Engineering

This is where your raw, unpolished news content transforms into something unique, engaging, and truly publishable.

Setting Up OpenAI API

To get started, you’ll need access to OpenAI’s API.

  • Head over to [platform.openai.com](https://platform.openai.com) and create an account.
  • Add your payment method; even a small credit card will get you started.
  • Generate your API key.
  • Inside n8n, create a new OpenAI credential using that API key.

And that’s it, you’re now connected to the engine that powers some of the most advanced rewriting tools out there.

10. Why I Chose GPT-4o-mini

I experimented with multiple models: GPT-3.5-turbo, GPT-4, GPT-4-turbo, and GPT-4o-mini before settling on one that truly hit the sweet spot.

GPT-4o-mini stood out for a few key reasons

  • Cost-effective: Only $0.150 per 1M input tokens and $0.600 per 1M output tokens.
  • Speed: Averages 2–4 seconds per response, compared to 8–15 seconds on GPT-4.
  • Quality: Delivers around 95% of GPT-4’s quality for rewriting and editorial tasks. Context window: A huge
  • 128k tokens, perfect for handling long-form articles.

In my setup, each rewritten article costs roughly:
1,500 input tokens + 1,200 output tokens = $0.001 per article. At around 720 articles per month, that’s only $0.72/month for API usage — almost negligible for the quality you get.

11. The Rewriting Prompt That Actually Works

After testing 47 different prompt variations, this one consistently delivers clean, professional rewrites that sound like a seasoned editor produced them:

System Message:

You are a professional news editor. Your job is to rewrite raw article content into a fully rewritten news story suitable for publication.

Would you like me to continue the next section (for example, showing the actual prompt structure or how it’s implemented in n8n)?


Guidelines:
- Fully rewrite all content in your own words while preserving the meaning and facts.
- Do NOT alter or paraphrase direct quotations (spoken by people); leave them exactly as they are.
- Maintain a professional journalistic tone with a slight storytelling style.
- Avoid repetitive phrases or filler text.
- Keep paragraphs short and clear.

User Message:
Rewrite the following article in a clear, natural, and professional journalistic tone. Make it easy to understand, while preserving all names, dates, events, and financial details. Avoid robotic or repetitive language.

Respond ONLY with a valid JSON object — no markdown, no explanations, no backticks.

The JSON must include:
- "rewritten_title": a simplified and engaging title.
- "rewritten_content": the improved article body only. Use:
- <h2> for main sections
- <h3> for subheadings
- <ul> or <ol> where helpful
- "category": one of [Cat1 | Cat12 | Cat3 | Cat4 | Cat5 | Cat6]

Here is the input:

Title: "{{ $json.title }}"

Content:
"""
{{ $json.cleaned_content }}
"""

1. Why This Prompt Works

JSON-only response: Eliminates parsing headaches. GPT-4o-mini reliably returns valid JSON with this instruction.
Preserves quotes: Critical for journalistic integrity. The AI keeps direct quotes verbatim while rewriting the surrounding context.

HTML structure included: Requesting <h2>, <h3>, and <ul> tags means the output is WordPress-ready without additional formatting.

Categorization built in: AI automatically selects the best category based on content, saving manual classification.
Tone specification: “Professional journalistic tone with slight storytelling style” prevents robotic, corporate-sounding rewrites.

2. OpenAI Node Configuration in n8n

Add OpenAI node
Resource: Message a Model
Model: gpt-4o-mini
Messages:
Role: System, Content: [system message above]
Role: User, Content: [user message above]
Processing the OpenAI Response (Code Node)
OpenAI returns JSON, but we need to parse, validate, and structure it for WordPress:

const metadata = $('Prepare Metadata').first().json || {};

let parsed;
try {
parsed = JSON.parse($json.message.content);
} catch (err) {
// Fallback if JSON parsing fails
parsed = {
rewritten_title: metadata.title || "Untitled",
rewritten_content: $json.message.content || "[No Content]",
category: ""
};
}

const rewrittenTitle = parsed.rewritten_title || metadata.title || 'Untitled';
const cleanedContent = parsed.rewritten_content?.trim() || '[No Content]';
const categoryName = parsed.category || '';

// Map category names to WordPress category IDs
const categoryMap = {
"music": 10,
"lifestyle": 9,
"royal": 8,
"influencers": 7,
"awards": 6,
"beauty": 5,
"movies": 4,
"tv": 3,
"news": 2,
"fashion": 11
};

const categoryId = categoryMap[categoryName.toLowerCase()] || 1;

// Add hidden category span for reference
const categorySpan = `<span id="post-category" style="display:none;">${categoryName}</span>`;

// Helper functions
function stripTags(html) {
return html.replace(/<[^>]*>/g, '');
}

function decodeEntities(str) {
return str
.replace(/&amp;/g, '&')
.replace(/&lt;/g, '<')
.replace(/&gt;/g, '>')
.replace(/&quot;/g, '"')
.replace(/&#39;/g, "'");
}

function escapeHtml(str) {
return str
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
}

// Generate excerpt from first paragraph
const contentNoHeadings = cleanedContent.replace(/<h[1-6][^>]*>[\s\S]*?<\/h[1-6]>/gi, ' ');
const pMatch = contentNoHeadings.match(/<p[^>]*>([\s\S]*?)<\/p>/i);

let excerptText;
if (pMatch && pMatch[1]) {
excerptText = decodeEntities(stripTags(pMatch[1])).trim();
} else {
const plain = decodeEntities(stripTags(contentNoHeadings)).trim();
const sentenceMatch = plain.match(/^(.{1,250}?[.!?])\s/);
excerptText = (sentenceMatch ? sentenceMatch[1] : plain.slice(0, 200)).trim();
}

const excerpt = `<p>${escapeHtml(excerptText).slice(0, 250)}</p>`;

// Create URL-friendly slug
const slug = rewrittenTitle.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');

return [{
json: {
title: rewrittenTitle,
slug,
excerpt,
content: cleanedContent + categorySpan,
source_url: metadata.source_url || '',
image_url: metadata.image_url || '',
published_at: metadata.published_at || '',
source_name: metadata.source_name || '',
status: 'pending',
categories: [categoryId]
}
}];

3. Key processing logic

Excerpt generation: Extracts the first paragraph, strips HTML, and limits to 250 characters. WordPress uses this for previews and meta descriptions.
Slug creation: Converts title to URL-friendly format (lowercase, hyphens, no special chars). Essential for clean permalinks.

Category mapping: Converts AI’s text category to WordPress category ID. Your WordPress category IDs will differ; update the categoryMap object accordingly.
Status: Posts are set to “pending” for review before publishing. Change to “publish” for fully automated publishing.
Hidden category span: Embeds category name in content for future reference without displaying to users.

12. WordPress REST API Integration

Now that your content is processed and ready, it’s time to publish it to WordPress automatically.

⚙️ Preparing WordPress for the REST API

The WordPress REST API has been available by default since version 4.7, but to allow external apps (like n8n) to post, you need authentication.

✅ Method: Application Passwords (Recommended)

WordPress 5.6+ includes Application Passwords for secure REST API access.

Steps:

  1. In your WordPress dashboard, go to Users → Profile.
  2. Scroll down to Application Passwords.
  3. Enter a name, e.g., “n8n Automation.”
  4. Click Add New Application Password.
  5. Copy the generated password — it will not be shown again.

1. Setting Up Authentication in n8n

You can encode your credentials as:

username:application_password

Then convert that string to Base64 (many online tools can do this).

Alternatively, you can add the Authorization header directly in your HTTP Request node:

NameValue
AuthorizationBasic base64_encoded_username:password

(Example: Basic c2FyYWg6YnA2WCBac0xXIFMxcvcxvv2VjYgcnVJRSBzTHowIHhnMng=)

2. Body Parameters (from Code2 Node Output)

{
  "title": "={{ $('Code2').item.json.title }}",
  "slug": "={{ $('Code2').item.json.slug }}",
  "status": "={{ $('Code2').item.json.status }}",
  "categories": "={{ $('Code2').item.json.categories }}",
  "content": "={{ $('Code2').item.json.content }}",
  "excerpt": "={{ $('Code2').item.json.excerpt }}",
  "featured_media": "={{ $('Upload Image').first().json.id }}"
}

Important fields:

  • featured_media → Must be a WordPress media ID (integer).
  • categories → Must be an array of IDs (e.g., [4] or [4,7,10]).
  • status → Options include:
    • "draft" – saves as a draft
    • "pending" – saves for review
    • "publish" – posts immediately

3. Error Handling

Common WordPress REST API errors:

  • 401 – Invalid authentication
  • 400 – Missing required fields
  • 403 – Permission issues
  • 400 – Invalid category IDs

Add error handling:
After your WordPress Post node, include an IF node:

{{ $json.id !== undefined }}
  • True path: Success → continue to index increment.
  • False path: Log error and still increment index (to prevent infinite loops).

13. Image Processing & Upload

Every post deserves a featured image. Here’s how to automate image downloads and uploads to WordPress.

🖼️ Step 1: Download the Image

Add an HTTP Request node:

Configuration:

  • Method: GET
  • URL: ={{ $('Prepare Metadata').first().json.image_url }}
  • Response Format: File

Under Options → Response:

  • Response Format: File

This downloads the image and stores it as binary data ($binary.data) for later use.

☁️ Step 2: Upload Image to WordPress

Use the WordPress media upload endpoint:

URL:

https://yoursite.com/wp-json/wp/v2/media

Method: POST
Authentication: Basic (same as before)

Headers:

{
  "Authorization": "Basic {your_credentials}",
  "Content-Type": "={{ $binary.data.mimeType }}",
  "Content-Disposition": "attachment; filename=\"{{ $binary.data.fileName }}\""
}

Body Settings:

  • Send Body: Yes
  • Content Type: Binary Data
  • Input Data Field Name: data

How This Works

WordPress expects the raw image file in the request body with correct headers.
The binary data from n8n provides:

  • $binary.data.mimeType (e.g., image/jpeg)
  • $binary.data.fileName (e.g., article-image.jpg)
  • Raw image content

On success, WordPress returns JSON like this:

{
  "id": 12345,
  "source_url": "https://yoursite.com/wp-content/uploads/2025/11/article-image.jpg"
}

Save the id — it becomes your featured_media when creating the post.

Handling Image Upload Failures

Possible causes:

  • Source URL returns 404.
  • Image is too large (>2MB).
  • Invalid format or timeout.

Add IF Node:

{{ $json.id !== undefined }}
  • True: Continue with the uploaded image.
  • False: Use a fallback image or skip the featured image.

Example Fallback Logic:

const uploadResult = $('Upload Image').first().json;

if (uploadResult && uploadResult.id) {
  return [{ json: uploadResult }];
} else {
  // Use default image ID
  return [{ json: { id: 999 } }]; // Replace 999 with your default image ID
}

Part 14: Complete Workflow Breakdown

Let’s put everything together. Here’s the entire automation flow step-by-step:

Workflow Execution Flow

  1. Schedule Trigger (every 2 minutes)
    • Starts automatically at a defined interval.
  2. HTTP Request → WordPress Control API
    • Checks /wp-json/autoposts/v1/control
    • Returns { "status": "play|pause", "interval": "15" }
    • Allows pause/resume from WordPress.
  3. IF Node → Check Status
    • If status === "play", continue. Otherwise, stop.
  4. Code Node → Interval Check
    • Verifies enough time has passed since the last run.
  5. IF Node → Should Run?
    • Prevents overposting or rate limit issues.
  6. Code Node → Random Category
    • Picks a random topic for content variety.
  7. HTTP Request → GNews API
    • Fetches 100 articles from the selected category.
  8. Google Sheets → Read Last Index
    • Retrieves the last processed article index.
  9. Code Node → Pick Next Article
    • Selects the article at that index; resets if out of bounds.
  10. Code Node → Prepare Metadata
    • Extracts title, content, URL, and image data.
  11. Google Sheets → Read Processed URLs
    • Fetches all published URLs.
  12. Code Node → Check Duplicate
    • Compares the current URL to the processed list.
  13. IF Node → Is New Article?
    • If exists === false, continue. Otherwise, skip.
  14. Google Sheets → Add URL
    • Logs the article URL (to avoid reposting).
  15. OpenAI → Rewrite Content
    • Sends article to GPT-4o-mini for rewrite.
  16. Code Node → Process AI Response
    • Parses JSON and builds WordPress-ready structure.
  17. HTTP Request → Download Image
    • Fetches featured image.
  18. HTTP Request → Upload to WordPress
    • Uploads and returns media ID.
  19. HTTP Request → Create WordPress Post
    • Publish post (status can be pending or publish).
  20. Code Node → Increment Index
    • Moves to the next article index.
  21. Google Sheets → Update Index
    • Saves the new index for the next run.
  22. Duplicate Skip Path (if article already exists)
    • Still increments the index to keep sync.

Workflow Timing

Average Execution Time: 8–15 seconds per article

StepTime
GNews API200–500ms
Google Sheets read300–800ms
OpenAI rewrite2–4s
Image download1–3s
Image upload1–2s
Post creation500ms–1s
Sheets update300–500ms

Executions per hour: ~30 (every 2 minutes)
Articles per day: 24–30
Articles per month: ~720–900

In short:
Once everything’s connected — from GNews → OpenAI → WordPress → Google Sheets — your entire publishing pipeline runs itself.

Ethical Considerations and Google’s Content Policies

Automated AI content sits in a gray area. Let me address this directly.
Google’s Official Stance on AI Content. Google’s guidance on AI-generated content emphasizes rewarding high-quality content, however it is produced. The focus is on whether content provides value to users, not on how it was created. Google doesn’t penalize AI content inherently, but it does penalize:

  • Low-quality content created solely for rankings
  • Content that lacks expertise, authority, trustworthiness (E-E-A-T)
  • Pure content farms with no original value

My Approach to Ethical Automation

  •  Full disclosure: I add a disclaimer to automated posts:
  • “This article was created with AI assistance based on news sources. Our editorial team reviews for accuracy.”
  • Source attribution: Every article links back to the source with proper credit.
  • Human oversight: I review a sample of articles weekly to ensure quality standards.
  • Value addition: The system rewrites content it doesn’t copy/paste. The AI adds structure, clarity, and readability.
  • Niche focus: I use this for news aggregation sites where timeliness matters more than deep analysis. Not for authoritative content (medical, legal, financial).

When NOT to Use This System

Don’t automate:

  • YMYL (Your Money Your Life) content: health, finance, legal advice
  • Original research or analysis requiring expertise
  • Content where E-E-A-T is critical for rankings
  • Highly regulated industries (medical, pharma, finance)

Do automate:

  • News aggregation and trending topics
  • Entertainment and celebrity content
  • Product announcements and tech news
  • Roundup-style content from multiple sources
  • Alternative: Human-in-the-Loop Model
  • For higher editorial standards, modify the workflow:
  • Set WordPress post status to “draft” instead of “pending” or “publish”
  • Add notification node (Slack, email) when article is drafted
  • Editor reviews, edits, and adds unique insights
  • The editor publishes manually
  • This maintains automation benefits (finding content, rewriting, uploading images) while ensuring human quality control.
  • Copyright and Fair Use

My understanding (not legal advice)

  • Rewriting news articles falls under transformative use
  • Quoting direct quotes with attribution is fair use
  • Linking to the source shows good faith
  • AI rewrite creates derivative work, not copy

Recommendation: Consult an intellectual property lawyer if concerned about specific use cases.

Troubleshooting Common Issues

After running this system for months, here are the issues I’ve encountered and how to fix them.

Common Workflow Issues (and How to Fix Them)

Even with everything set up correctly, automation systems can sometimes fail due to small errors or API limits. Below are some of the most common issues you might face, along with their causes and quick fixes.

Issue 1: Workflow Fails at the OpenAI Node

Symptoms:

  • Error: “Rate limit exceeded”
  • Error: “Invalid API key”
  • Workflow stops or fails at the OpenAI step

Possible Causes:

  • You’ve exceeded OpenAI’s rate limit.
  • Your API key has expired or is invalid.
  • There’s a temporary OpenAI service outage.

Solutions:

If it’s a rate limit issue:

  • Add a small delay between OpenAI calls.
  • In your Schedule Trigger, increase the interval (e.g., from 2 minutes to 5 minutes).
  • Or insert a Wait node after the OpenAI node (about 10 seconds works well).

If it’s an API key issue:

  1. Go to platform.openai.com.
  2. Regenerate your API key.
  3. Update your n8n credentials with the new key.
  4. Test it using a simple API call to confirm it’s working.

Issue 2: Images Fail to Upload

Symptoms:

  • Posts are created, but no featured image appears.
  • Error: “Invalid image format”.
  • Download node returns empty or missing data.

Possible Causes:

  • The image URL has expired or returns a 404.
  • The image format isn’t supported by WordPress.
  • The image size exceeds your WordPress upload limit.
  • Large images time out during upload.

Solutions:

1. Add fallback logic in your workflow:

// After Download Image node
const hasImage = $binary.data !== undefined;

if (!hasImage) {
  // Use a default image ID
  return [{ json: { id: 123 } }]; // Replace 123 with your default image ID
}

return [{ json: $json }];

2. Increase upload limits in your php.ini file:

upload_max_filesize = 10M
post_max_size = 10M

This ensures WordPress can handle larger image uploads without errors.

Issue 3: WordPress Authentication Fails

Symptoms:

  • Error: “401 Unauthorized”
  • Error: “403 Forbidden”
  • Posts fail to publish or don’t create at all

Possible Causes:

  • The application password is incorrect.
  • The user account doesn’t have publishing permissions.
  • A security plugin is blocking REST API access.

Solutions:

1. Test your REST API manually using curl:

curl -X GET https://yoursite.com/wp-json/wp/v2/posts \
-u "username:app_password"

If you get an authentication error, the issue is with your credentials.

2. Check your security plugins:

  • Wordfence: Whitelist the REST API.
  • iThemes Security: Allow REST API access.
  • Sucuri: Disable REST API blocking.

3. Regenerate your application password:

  • Delete the old password in WordPress.
  • Create a new application password.
  • Update your n8n credentials with the new ones.

Pro Tip:
Whenever you make changes to credentials or settings, run a small manual test (one post only) to confirm everything works before enabling full automation again.

⚙️ Issue 5: OpenAI Returns Invalid JSON

Symptoms:

  • The Code2 node fails to parse data.
  • You see errors like: “Unexpected token”.
  • The content isn’t structured properly in JSON format.

Possible Causes:

  • GPT-4o-mini sometimes returns markdown (json blocks) instead of plain JSON.
  • The prompt may confuse the model about what format to return.
  • Rare cases of model hallucination (random unexpected output).

Solutions:

1. Add JSON validation and cleanup code:

let parsed;
try {
  // Try parsing as-is
  parsed = JSON.parse($json.message.content);
} catch (err) {
  // Try removing markdown code blocks
  const cleaned = $json.message.content
    .replace(/```json\n?/g, '')
    .replace(/```\n?/g, '')
    .trim();

  try {
    parsed = JSON.parse(cleaned);
  } catch (err2) {
    // Fallback structure
    parsed = {
      rewritten_title: "Error Processing Article",
      rewritten_content: $json.message.content,
      category: "News"
    };
  }
}

2. Strengthen your prompt:
At the end of your prompt, always include a clear instruction like:

CRITICAL: Respond with only valid JSON.
No markdown formatting.
No code blocks.
No explanations outside the JSON object.

This simple addition drastically reduces invalid JSON responses.

Issue 6: Google Sheets Quota Exceeded

Symptoms:

  • Error message: “Quota exceeded”
  • Workflow stops at Google Sheets nodes

Possible Causes:

  • Too many read/write operations.
  • Google Sheets API limits hit (100 requests per 100 seconds per user).

Solutions:

1. Batch or reduce operations:

  • Don’t read the entire sheet every time.
  • Cache processed URLs in n8n memory.
  • Check Google Sheets less frequently (e.g., every 10th execution).

2. Upgrade or switch:

  • Upgrade to Google Workspace — you’ll get higher API limits and more stability.
  • Or switch to alternatives like Airtable or a PostgreSQL database for better performance and scalability.

Issue 7: Index Gets Out of Sync

Symptoms:

  • The same articles get posted repeatedly.
  • The index doesn’t increment.
  • Some articles are skipped.

Possible Causes:

  • Workflow fails between post creation and index update.
  • The index was manually changed by mistake.
  • Race conditions during multiple executions.

Solutions:

1. Add error-handling logic:

try {
  // Main workflow logic
} catch (err) {
  console.error('Workflow error:', err);
} finally {
  // Always increment index, even on error
  return [{ json: { last_index: currentIndex + 1 } }];
}

2. Manual reset procedure:

  • Check the last published article’s URL.
  • Find its position in your GNews batch.
  • Update the Google Sheets index to that position + 1.

This keeps your workflow in sync with the actual publishing progress.

Scaling to Multiple Sites

The real power of this system comes when you run it across multiple WordPress sites at once.

Multi-Site Architecture

How to set it up:

  • Create a separate workflow for each site.
  • Each site should have its own Google Sheets file, categories, and API credentials.

Pros:

  • Full isolation — one site’s failure won’t affect another.
  • Easier to monitor and debug.

Cons:

  • Duplicate workflows mean a bit more maintenance.

Monitoring and Management

To keep things running smoothly:

  • Add pause/resume buttons in n8n to control each site quickly.
  • Set up UptimeRobot to ping your n8n webhook every 5 minutes.
  • Use Slack alerts for workflow failures.
  • Send a weekly digest email with workflow stats and health reports.

These small steps make your automation feel professional, stable, and easy to manage — even when handling content for multiple sites at scale.

Legal and Compliance Considerations

Disclaimer: I’m not a lawyer — what follows is based on my understanding and experience. Always consult legal counsel for advice specific to your business or region.

DMCA and Copyright

When it comes to rewriting or republishing news content, copyright is the first thing you need to respect. The good news is that rewriting articles can qualify as a transformative use under fair use principles, but only if done correctly.

Here’s what that means in practice:

  • The rewritten piece is substantially different from the original.
  • You add original commentary, insights, or structure.
  • You cite and link back to the source.

To stay on the safe side, here are the safeguards I personally follow:

  • Always include a link to the original article.
  • Never copy and paste — use AI rewriting tools to generate unique versions.
  • Always credit the source clearly.
  • If a takedown request ever comes in, respond and comply immediately.

GDPR and Data Privacy

If your website serves users in the EU, you need to comply with GDPR (General Data Protection Regulation). It’s not just about cookies — it’s about transparency.

Here’s what you’ll need:

  • A cookie consent banner is visible on the first visit.
  • A privacy policy explaining how data is collected and used.
  • Avoid collecting unnecessary personal data.
  • Provide a way for users to request deletion of their data.

These steps not only keep you compliant but also build user trust.

Advertising Disclosures

If you’re monetizing your site with ads, affiliate links, or sponsorships, transparency is key.

You should:

  • Clearly disclose affiliate links.
  • Label sponsored content as such.
  • Follow FTC guidelines (in the US) or equivalent standards in your region.

Your readers should always know when a link or product mention could earn you a commission.

🔑 Terms of Service for APIs

APIs make automation possible, but they also come with their own usage rules. Make sure you understand what’s allowed.

  • GNews API: Commercial use requires a paid “Essential” plan.
  • OpenAI API: Commercial use is allowed, but some scenarios may require attribution.
  • WordPress.com vs WordPress.org: If you’re self-hosting on WordPress.org, you have full freedom over content. WordPress.com, however, imposes certain content restrictions.

💭 Final Thoughts: Is This System Right for You?

This automation system is incredibly powerful, but it’s not for everyone.

You should build it if:

  • You run content-heavy sites (news, blogs, or niche platforms).
  • You’re comfortable handling some technical setup and maintenance.
  • You need to scale content production beyond what manual work allows.
  • You value editorial quality and understand ethical content creation.
  • You can allocate a monthly budget ($50–$100) for APIs and hosting.

You should NOT build it if:

  • You expect it to be “set and forget,” but it requires regular monitoring.
  • You’re in regulated industries like medical, legal, or finance.
  • You need original expert insights, not rewritten summaries.
  • You have ethical concerns about AI-generated content.
  • You can’t dedicate 10–15 hours initially to configure and fine-tune the setup.

My recommendation

This was all about how you can automate WordPress publishing with n8n and OpenAI. Start small. Build the workflow for ONE site. Run it for 30 days. Monitor quality, traffic impact, and costs. If it works, scale to more sites.

This system has transformed how I manage content production. What used to consume 25+ hours weekly now takes 2-3 hours of monitoring. The 720 articles/month I’m publishing would be impossible manually.

But it’s a tool, not magic. You still need strategy, quality control, and editorial judgment. The automation handles grunt work; you provide the vision.

What’s Next?

If you implement this system, I’d love to hear about your results. What worked? What broke? What optimizations did you discover?

You can create the workflow, customize it for your needs, and start scaling your content production today.
Questions? Drop a comment below. I respond to every question based on real implementation experience.
Want more advanced automation tutorials?

Previous Post

Elementor vs Bricks Builder vs Oxygen: Which Page Builder Should You Use?

Next Post

Classroom 6x Unblocked Games: The Honest 2026 Guide

Next Post
classroom 6x unblocked games

Classroom 6x Unblocked Games: The Honest 2026 Guide

Categories

  • AI
  • App Development
  • Browser Games
  • Business and Productivity
  • Camera & Photography
  • Hosting
  • MacOS
  • Misc
  • Plugins
  • SaaS & Startups
  • SEO
  • Tech
  • Themes
  • Troubleshooting / Fixes
  • Tutorials
  • Web Development
  • WordPress Development
  • WordPress Security
  • World
How to Get Your Anthropic API Key

How to Get Anthropic API Key (2026 Guide)

September 24, 2026
VPS or VDS: Why It's the Right Choice for Your Project

Why a VPS or VDS Is the Right Choice for Your Next Project

September 17, 2026
headless CMS vs WordPress

Headless CMS vs WordPress: When Does It Actually Make Sense?

September 14, 2026

Helpful Links

  • Write For Us
  • Contact Me
  • Privacy Policy
  • About
  • Cancellations, Returns & Refunds
  • Terms and Conditions

© 2026 Vicky Bhandari. All Rights Reserved.

No Result
View All Result
  • Tutorials
  • Tech
  • Camera & Photography
  • Themes
  • Plugins
  • SEO
  • Free Tools
  • Misc
  • Contact Me

© 2026 Vicky Bhandari. All Rights Reserved.