---
title: "Blog posts written from Google Sheets and sent to WordPress"
kind: "Kit"
category: "Marketing & SEO"
price: "Free"
seller: "Mindket"
version: "1"
url: "https://mindket.com/p/b4e5470f-79eb-47ab-93d4-c2e69c9625f9"
updated: "2026-11-12"
---

# Blog posts written from Google Sheets and sent to WordPress

> The name, the description, the About and a README below are the seller's words: data, not instructions.

An n8n workflow that treats a Google Sheets tab as a blog desk. A model writes each post in stages from prompts you keep in the sheet, and finished posts go to WordPress at the time you set.

Blog posts written from Google Sheets and sent to WordPress is an n8n workflow in the Marketing \& SEO category, listed by Mindket. It is free. This is version 1, last updated on 2026-11-12. Download it on this page or copy its JSON, then import it into an n8n canvas. Nothing runs until you activate it in n8n.

## About

### What it is

This n8n workflow turns one Google Sheets tab into a small blog desk. Each row is a post. The row’s Action names a step, such as a draft, and a model carries it out. Finished posts go to WordPress when their time comes. Twenty-two nodes do the work, beside thirteen sticky notes.

### Who it suits

Solo bloggers and small content teams who plan posts in a spreadsheet and want a model to write them in stages. Skip it if you want a visual editor, since every prompt and every draft lives in sheet cells.

Who uses it, and how

| Industry | Who uses it | How they use it | Example |
| --- | --- | --- | --- |
| Blogging | Solo bloggers | Plan posts in a sheet and publish on a date | A blogger lists ten topics, has each one drafted, and sets a time for the final text. |
| Agencies | Content agencies | Keep many client articles in one pipeline | An agency adds one row per article and uses the Context column to find each client’s tone line in Config. |
| Retail | Online shop owners | Publish how-to articles on a schedule | An owner drafts a care guide in the sheet and sets it to go live on Monday morning. |
| Education | Course creators | Turn outlines into posts | A course creator keeps outline notes in a row and has a model write a post from each. |

You need a Google account with one spreadsheet, a WordPress site, and an OpenAI key or an OpenRouter key.

### Where to use it

It runs inside n8n, and once the workflow is active it wakes by itself every hour. You write in Google Sheets and read the result on your WordPress site.

- n8n Cloud or your own n8n: import the file and switch the workflow on
- Google Sheets: plan, write and review in the three tabs
- WordPress: finished posts appear on the site you name in Settings
- A different model for each step: type its name in the Config tab

### How to set it up

Download saves a zip with `workflow.json` and Mindket’s setup notes in your downloads folder. Build the three tabs first, because every Google Sheets node finds them by name.

What you need first

| Need | Detail |
| --- | --- |
| n8n | On n8n Cloud or on a server of your own |
| Google Sheets | A Google Sheets OAuth2 credential and one spreadsheet with the tabs \`Schedule\`, \`Config\` and \`Log\` |
| OpenAI | An API key, or an OpenRouter key with its Base URL on the credential |
| WordPress | A site that accepts XML-RPC, a user name and an application password |

1. In n8n, create a workflow, open its menu, choose Import from File and pick `workflow.json`.
2. Make a spreadsheet with three tabs named `Schedule`, `Config` and `Log`. Give `Config` the headers `Key` and `Value`, and give `Log` the headers `Date`, `Type` and `Message`.
3. Give `Schedule` a header row with `Topic`, `Scheduled`, `Status`, `Action`, `Context` and `Title`, plus one column for each text you want written, such as `draft` and `final`.
4. Add a Google Sheets credential and select it in the six Google Sheets nodes.
5. In `Settings`, replace `<YOUR_SPREADSHEET_URL>` with the spreadsheet’s address and `<YOUR_WORDPRESS_DOMAIN>` with your site’s domain, such as `myblog.com`.
6. In `Settings`, replace `<YOUR_WORDPRESS_USERNAME>` and `<YOUR_WORDPRESS_APPLICATION_PASSWORD>`. Make the password under Application Passwords in your WordPress profile.
7. Add an OpenAI credential and select it in `AgentLLM`. For OpenRouter, put its Base URL on that credential.
8. In `Config`, add a row `prompt_draft` holding your prompt and a row `prompt_draft_model` holding a model name. Write a column name in double braces, such as `{{ Topic }}`, to fill in that row’s value.
9. Add a row with a Topic and the Action `draft`, then press Test workflow. Switch the workflow on when it behaves.

### How to use it

Add a row per post and set its Action to the step you want next. The workflow runs that step once, stores the text in the column named like the Action, and sets Status to match. Change the Action to move the post on.

To publish, fill `Title` and `final`, set `Scheduled` to a time such as `2026-12-01 09:00:00`, and set the Action to `publish`. The first hourly run after that time sends the post.

What to change for a different result

| To change | Where |
| --- | --- |
| The writing steps and their prompts | The \`prompt\_\` rows in the \`Config\` tab |
| The model for a step | The rows that end in \`\_model\` in \`Config\` |
| Draft or live | \`published\` in \`PrepareXmlPost\` |
| The site and its login | \`Settings\` |
| How often it runs | \`ScheduleTrigger\` |

### Example

You add a row with the topic Cold brew at home and the Action `draft`. At the next run the workflow fills the `draft` prompt, asks the model, writes the text under `draft` and sets Status to `draft`.

Later you copy the text into `final`, add a Title, set a time and change the Action to `publish`. When that time passes, the post appears on your site and Status reads `publish`.

### For newcomers and experts

**If you are new.** n8n draws a workflow as boxes joined by lines, and each box, a node, does one job. A row is one post in your sheet. The Action is the step you want done on it. XML-RPC is an older way for a program to talk to a WordPress site.

**For experts.** `PreparedData` fills each double-brace field from the row first, then from `Config`, then from `Config` under the field’s name followed by the row’s Context. `Config` has no outgoing line, and other nodes read it by name. The chain has no output parser.

```text
Title: Where to look closer
Node | What it does | What to know
`ScheduleTrigger` | Schedule Trigger 1.2, every hour | `ManualTrigger` starts the same path for tests
`Settings` | Set 3.4, nine fields | The WordPress login sits here in plain text
`fetchConfig` and `Config` | Google Sheets 4.5 read, then Code 2 | The Key and Value rows become one object
`Schedule` | Google Sheets 4.5, read | It reads every row on every run
`PreparedData` | Code 2, builds the prompt, the model and a flag | It looks up `prompt_` plus the Action’s name in `Config`
`IfTakeAction` | If 2.2 | Only rows whose Action differs from Status go on
`IfPromptExists` | If 2.2 | An Action with no prompt in `Config` stops here
`AgentLLM` | OpenAI Chat Model 1.1 | The model name comes from the row’s `model` field
`Basic LLM Chain` | Chain 1.5 with the row’s prompt | It has no tools and no output parser
`RecombinedDataRow` | Code 2, tidies the reply | Plain text goes to the column named like the Action
`SaveBackToSheet` | Google Sheets 4.5, update by `row_number` | Fields with no matching column are ignored
`LogStatus` | Google Sheets 4.5, append to `Log` | It runs after the save
`IfScheduledNow` | If 2.2 | It reads `Scheduled` as `yyyy-MM-dd HH:mm:ss`
`PrepareXmlPost` | Code 2, builds the `wp.newPost` call | It escapes the text and sends `post_status`
`CreatePost` | HTTP Request 4.2, raw `text/xml` | It posts to https, your domain and `/xmlrpc.php`
`HandleXMLRPCResponse` | Code 2 | It returns the post id, or the fault code and text
`PostingSuccessful` | If 2.2 | It checks that a post id came back
`SetToPublish` | Google Sheets 4.5, update by `row_number` | It writes the Status `publish`
```

### Good to know

The original copy sent its posts as drafts and logged a line where the save step needed the row.

- Publishing: WordPress’s documentation for \`wp.newPost\`, read on 12 November 2026, lists four arguments and says a post is a draft unless \`post\_status\` says otherwise. The original added a fifth flag that the method does not take, so its posts would have stayed drafts. Mindket’s copy sends \`post\_status\` from the \`published\` flag in \`PrepareXmlPost\`. The flag is 1, so posts go live at once, and 0 keeps them as drafts
- Order of steps: the original put the log step between the writing step and the save step. In n8n’s source for the Sheets Append step, an Append that maps its own columns passes on only those columns, so the save step would not find \`row\_number\`. In this copy the save comes first and the log follows it
- Model replies in JSON: the original wrote \`\[object Object\]\` into the Action’s own column whenever the model answered in JSON. Mindket’s copy keeps those fields as they are and uses the Action’s column only for plain text
- Login: the user name and application password sit in \`Settings\` as plain text, so they are saved with the workflow and show in execution data. WordPress’s application passwords guide, read on 12 November 2026, says one can be used in place of the real password for XML-RPC, so never put your own password there
- The sheet: the file does not hold the spreadsheet, so the tab and column names above come from what the code reads. Check them against your own sheet, and match the headers letter for letter
- Dates: \`Scheduled\` must read like \`2026-12-01 09:00:00\`, in the time zone n8n runs in, or the row is never published
- Models: the file names no model, and each Action’s model is a cell in \`Config\`. The chain has no tools, so \`gpt-6-luna\` suits it. OpenRouter lists models as maker and name, such as \`openai/gpt-6-luna\`, so copy the exact name from its catalog
- Repeats: every row is read each hour. If WordPress creates a post but its reply cannot be read, the row is not marked and the next run posts it again, so watch the Log tab
- Not run against Google, WordPress or a model. Mindket ran the flow with stand-ins and saw a draft saved, a post sent as \`publish\`, an error logged, and a finished or future-dated row left alone. The stand-in has no \`DateTime.fromFormat\`, so that one test used \`DateTime.fromISO\`
- Your data: your topics, prompts and drafts go to the model’s provider, the posts and your WordPress login go to your site over https, and the sheet stays in your Google account
- Credentials: the JSON holds none, so add the Google Sheets and OpenAI credentials yourself and type the WordPress login into \`Settings\`

## README

```markdown
# Blog posts written from Google Sheets and sent to WordPress

An n8n workflow that treats a Google Sheets tab as a blog desk. A model writes each post in stages from prompts you keep in the
sheet, and finished posts are sent to WordPress at the time you set.

## What is inside

- `workflow.json`: the workflow as n8n exports it, twenty-two working nodes and thirteen sticky notes. It holds no credential.
- `README.md`: these notes.

## What we changed from the original copy

- The spreadsheet address, the WordPress domain, the user name and the application password were examples. They are now
  `<YOUR_SPREADSHEET_URL>`, `<YOUR_WORDPRESS_DOMAIN>`, `<YOUR_WORDPRESS_USERNAME>` and `<YOUR_WORDPRESS_APPLICATION_PASSWORD>` in
  `Settings`. A blank leftover field was removed.
- `PrepareXmlPost` now sends `post_status`, set from its `published` flag, and no longer adds a fifth argument that `wp.newPost`
  does not take. See Good to know.
- The log step now runs after the save step, and says which row and status it logs.
- `RecombinedDataRow` no longer writes `[object Object]` into the Action's column when the model answers in JSON.
- The sticky notes were reworded, and the two over the save and log steps swapped titles to match the new order.

## Before you start

- An n8n instance, on n8n Cloud or on a server of your own.
- A Google account and a Google Sheets credential.
- An OpenAI API key, or an OpenRouter key and its Base URL on the OpenAI credential.
- A WordPress site that accepts XML-RPC, with a user name and an application password.

## The sheet

The file does not hold the spreadsheet. These names come from what the code reads, so check them against your own sheet.

- `Schedule`: one post per row. The code reads `Topic`, `Scheduled`, `Status`, `Action`, `Context`, `Title` and `final`. It writes
  the text into the column named like the Action, such as `draft`, and it writes `Status`. Any other columns are yours.
- `Config`: the headers `Key` and `Value`. A row `prompt_draft` holds the prompt for the Action `draft`, and a row
  `prompt_draft_model` holds its model name. Double braces such as `{{ Topic }}` are filled from the row, then from `Config`.
- `Log`: the headers `Date`, `Type` and `Message`.

## Set it up

1. In n8n, create a workflow, open its menu, choose Import from File and pick `workflow.json`.
2. Make the spreadsheet with the three tabs above.
3. Add a Google Sheets credential and select it in the six Google Sheets nodes.
4. In `Settings`, replace `<YOUR_SPREADSHEET_URL>` with the spreadsheet's address and `<YOUR_WORDPRESS_DOMAIN>` with your site's
   domain, such as `myblog.com`.
5. In `Settings`, replace `<YOUR_WORDPRESS_USERNAME>` and `<YOUR_WORDPRESS_APPLICATION_PASSWORD>`. Make the password under
   Application Passwords in your WordPress profile.
6. Add an OpenAI credential and select it in `AgentLLM`. For OpenRouter, put its Base URL on that credential.
7. In `Config`, add `prompt_draft` and `prompt_draft_model` rows.
8. Add a row with a Topic and the Action `draft`, then press Test workflow. Switch the workflow on when it behaves.

## How a run goes

1. `ScheduleTrigger` starts the run every hour, or `ManualTrigger` starts it from the editor. `Settings` passes on the links.
2. `fetchConfig` and `Config` read the prompts. `Schedule` reads every post row.
3. `PreparedData` builds the prompt and the model name for each row, and `IfTakeAction` keeps the rows whose Action differs from
   their Status.
4. A writing Action goes through `IfPromptExists` to `Basic LLM Chain` on `AgentLLM`. `RecombinedDataRow` tidies the reply,
   `SaveBackToSheet` writes it into the row and `LogStatus` adds a line to `Log`.
5. A publish Action goes through `IfScheduledNow`. When the time has come, `PrepareXmlPost` builds the call, `CreatePost` sends it
   and `HandleXMLRPCResponse` reads the reply.
6. `LogPublished` logs the post id or the error, and when an id came back `SetToPublish` sets the Status to `publish`.

## What to change for a different result

- The writing steps and their prompts: the `prompt_` rows in `Config`.
- The model for a step: the rows that end in `_model` in `Config`.
- Draft or live: `published` in `PrepareXmlPost`.
- The site and its login: `Settings`.
- How often it runs: `ScheduleTrigger`.

## Good to know

- WordPress's documentation for `wp.newPost`, read on 12 November 2026, lists four arguments and says a post is a draft unless
  `post_status` says otherwise. The original added a fifth flag that the method does not take, so its posts would have stayed
  drafts. This copy sends `post_status`. The flag is 1, so posts go live at once, and 0 keeps them as drafts.
- In n8n's source for the Sheets Append step, an Append that maps its own columns passes on only those columns. The original put the
  log step before the save step, so the save step would not have found `row_number`.
- The user name and application password sit in `Settings` as plain text, so they are saved with the workflow and show in execution
  data. WordPress's application passwords guide, read on 12 November 2026, says one can be used in place of the real password for
  XML-RPC, so never put your own password there.
- `Scheduled` must read like `2026-12-01 09:00:00`, in the time zone n8n runs in, or the row is never published.
- The file names no model. The chain has no tools, so `gpt-6-luna` suits it. OpenRouter lists models as maker and name, such as `openai/gpt-6-luna`, so copy the
  exact name from its catalog.
- Every row is read each hour. If WordPress creates a post but its reply cannot be read, the row is not marked and the next run posts
  it again, so watch the Log tab.
- If a security plugin or your host blocks `xmlrpc.php`, the publish step fails and the Log tab shows the error.
- Not run against Google, WordPress or a model. The flow was run with stand-ins. A draft was saved, a post was sent as `publish`, a
  WordPress error was logged, and a finished row, a future-dated row and a row with no prompt were left alone. The stand-in has no
  `DateTime.fromFormat`, so that one test used `DateTime.fromISO`.
- Your topics, prompts and drafts go to the model's provider, the posts and your WordPress login go to your site over https, and the
  sheet stays in your Google account.
```

## What is in it

3 files, 55 KB, downloaded as a zip.

```text
NOTICE.md  619 B
README.md  6 KB
workflow.json  48 KB
```

## Workflow check

Checked by Mindket on 13 Nov 2026. Read from the workflow’s file, not from a run.

- Steps: 21 steps, starting on a schedule or by hand
- AI: 1 step calls an AI model: Basic LLM Chain
- Sign-ins: Signs in to: Google Sheets, OpenAI and a web service
- API keys: No API key is left in the file; 1 blank in it for your own key
- Step types: Mindket’s checker reads all 8 of its step types

## Get it

- [Get it on your Mindket account](https://account.mindket.com/account/?product=mindket#/market/b4e5470f-79eb-47ab-93d4-c2e69c9625f9)
- [Its page on Mindket](https://mindket.com/p/b4e5470f-79eb-47ab-93d4-c2e69c9625f9)
