This workflow corresponds to n8n.io template #9250 — we link there as the canonical source.
This workflow follows the Form Trigger → Gmail 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 →
{
"id": "hUVV8GAakci58M8p",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Generate Blog Post from a Keyword Using Dumpling AI and GPT-4",
"tags": [],
"nodes": [
{
"id": "8d72a1ca-42cf-40eb-9b08-d69901beef75",
"name": "Trigger: Receive Keyword from Form",
"type": "n8n-nodes-base.formTrigger",
"position": [
-432,
-80
],
"parameters": {
"options": {},
"formTitle": "ideas",
"formFields": {
"values": [
{
"fieldLabel": "search key"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "fdafc512-8d73-4679-ba2c-77148c88efe6",
"name": "Search Google via Dumpling AI",
"type": "n8n-nodes-base.httpRequest",
"position": [
-208,
-80
],
"parameters": {
"url": "https://app.dumplingai.com/api/v1/search",
"method": "POST",
"options": {},
"sendBody": true,
"sendHeaders": true,
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "query",
"value": "={{ $json['search key'] }}"
},
{
"name": "scrapeResults",
"value": "true"
}
]
},
"genericAuthType": "httpHeaderAuth",
"headerParameters": {
"parameters": [
{}
]
}
},
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "1d5ebcd4-944c-42a1-bf98-fe2ff07f9ea8",
"name": "Extract Top Results, PAA & Related Searches",
"type": "n8n-nodes-base.code",
"position": [
16,
-80
],
"parameters": {
"jsCode": "// n8n JavaScript Code to Extract Search Results Data\n\n// Get the input data (assuming it's in $input.all()[0].json)\nconst inputData = $input.all()[0].json;\n\n// Initialize the output object\nconst output = {\n query: inputData.searchParameters?.q || \"N/A\",\n topTwoResults: [],\n peopleAlsoAskExists: \"No\",\n topThreeRelatedSearches: []\n};\n\n// Extract top 2 search results\nif (inputData.organic && Array.isArray(inputData.organic)) {\n const topTwo = inputData.organic.slice(0, 2);\n \n output.topTwoResults = topTwo.map(result => ({\n position: result.position,\n title: result.title,\n url: result.link,\n snippet: result.snippet,\n date: result.date || \"N/A\",\n sitelinks: result.sitelinks || [],\n scrapeOutput: result.scrapeOutput ? {\n title: result.scrapeOutput.title,\n description: result.scrapeOutput.metadata?.description || \"N/A\",\n ogTitle: result.scrapeOutput.metadata?.ogTitle || \"N/A\",\n ogDescription: result.scrapeOutput.metadata?.ogDescription || \"N/A\",\n url: result.scrapeOutput.url,\n language: result.scrapeOutput.metadata?.language || \"N/A\"\n } : null\n }));\n}\n\n// Check if \"People Also Ask\" exists and extract questions\nif (inputData.peopleAlsoAsk && Array.isArray(inputData.peopleAlsoAsk) && inputData.peopleAlsoAsk.length > 0) {\n output.peopleAlsoAskExists = \"Yes\";\n output.peopleAlsoAskQuestions = inputData.peopleAlsoAsk.map(item => ({\n question: item.question,\n snippet: item.snippet,\n title: item.title,\n link: item.link\n }));\n} else {\n output.peopleAlsoAskQuestions = [];\n}\n\n// Extract top 3 related searches\nif (inputData.relatedSearches && Array.isArray(inputData.relatedSearches)) {\n output.topThreeRelatedSearches = inputData.relatedSearches\n .slice(0, 3)\n .map(search => search.query);\n}\n\n// Return the output\nreturn output;"
},
"typeVersion": 2
},
{
"id": "5c7c27bb-debc-45b8-954f-96932eb0f831",
"name": "Check if People Also Ask Exists",
"type": "n8n-nodes-base.filter",
"position": [
240,
-80
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "664cac06-e941-41cb-8ef1-e3345a5dd68d",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.peopleAlsoAskExists }}",
"rightValue": "Yes"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "66ad7710-c5a1-4abf-95da-417d1f39e7f9",
"name": "Generate Blog Post with GPT-4",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
464,
-80
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "chatgpt-4o-latest",
"cachedResultName": "CHATGPT-4O-LATEST"
},
"options": {},
"messages": {
"values": [
{
"role": "system",
"content": "=You are given the following data:\n\nA search key representing the topic of interest.\n\nThe top two ranking search results for that search key, including their descriptions.\n\nA list of People Also Ask (PAA) questions and their answers from the same search.\n\nYour task:\nCarefully review the People Also Ask questions and their answers. Choose one question that is insightful, unique, or has the potential to generate a valuable and engaging blog post. Using that question as the core theme, write a detailed, well structured, and original blog post that is informative, clear, and engaging.\n\nThe blog post must reflect the context of the search key and take into account the top ranking pages and their descriptions, ensuring the final content is competitive and provides additional value to readers.\n\nThe output must be returned strictly in this JSON format:\n\n{\n \"title\": \"string\",\n \"blog_post\": \"string\"\n}"
},
{
"content": "=Data provided:\nSearch Key:{{ $('Check if People Also Ask Exists').item.json.query }}\nTop Results:\n\nTitle: {{ $json.topTwoResults[0].title }} \nDescription: {{ $json.topTwoResults[0].scrapeOutput.description }}\n\nTitle: {{ $json.topTwoResults[1].title }}\nDescription: {{ $json.topTwoResults[1].scrapeOutput.description }}\n\nPeople Also Ask:{{ JSON.stringify($json.peopleAlsoAskQuestions) }}\n"
}
]
},
"jsonOutput": true
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.8
},
{
"id": "dd1f86fb-f6b0-4e9b-8a9b-84a42abf198a",
"name": "Send Blog Post for Review via Gmail",
"type": "n8n-nodes-base.gmail",
"position": [
816,
-80
],
"parameters": {
"sendTo": "user@example.com",
"message": "=<body bgcolor=\"#f6f9fc\" style=\"margin:0; padding:0;\">\n <table width=\"100%\" bgcolor=\"#f6f9fc\" cellpadding=\"0\" cellspacing=\"0\">\n <tr>\n <td align=\"center\">\n <table width=\"620\" bgcolor=\"#ffffff\" cellpadding=\"0\" cellspacing=\"0\" style=\"border:1px solid #e5e7eb;\">\n <tr>\n <td align=\"left\" style=\"padding:24px;\">\n <font face=\"Arial, Helvetica, sans-serif\" size=\"5\" color=\"#111827\">\n Workflow review needed\n </font>\n </td>\n </tr>\n\n <tr>\n <td align=\"left\" style=\"padding:0 24px 8px 24px;\">\n <font face=\"Arial, Helvetica, sans-serif\" size=\"3\" color=\"#374151\">\n Hello, please review this workflow run carefully. Your input will determine the next step in the process.\n </font>\n </td>\n </tr>\n\n <tr>\n <td align=\"left\" style=\"padding:8px 24px 16px 24px;\">\n <font face=\"Arial, Helvetica, sans-serif\" size=\"3\" color=\"#6b7280\">\n Below is the generated blog content for your review.\n </font>\n </td>\n </tr>\n\n <tr>\n <td style=\"padding:0 24px 16px 24px;\">\n <table width=\"100%\" cellpadding=\"8\" cellspacing=\"0\" style=\"border:1px solid #e5e7eb;\">\n <tr bgcolor=\"#f9fafb\">\n <td width=\"30%\">\n <font face=\"Arial, Helvetica, sans-serif\" size=\"2\" color=\"#6b7280\">Blog Title</font>\n </td>\n <td>\n <font face=\"Arial, Helvetica, sans-serif\" size=\"2\" color=\"#111827\">\n {{ $json.message.content.title }}\n </font>\n </td>\n </tr>\n <tr>\n <td width=\"30%\" valign=\"top\">\n <font face=\"Arial, Helvetica, sans-serif\" size=\"2\" color=\"#6b7280\">Blog Body</font>\n </td>\n <td>\n <font face=\"Arial, Helvetica, sans-serif\" size=\"2\" color=\"#111827\">\n {{ $json.message.content.blog_post }}\n </font>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n\n <tr>\n <td align=\"left\" style=\"padding:0 24px 24px 24px;\">\n <font face=\"Arial, Helvetica, sans-serif\" size=\"3\" color=\"#111827\">\n Thank you for reviewing. Please use the provided approval options in the workflow to continue.\n </font>\n </td>\n </tr>\n\n </table>\n </td>\n </tr>\n </table>\n</body>\n",
"options": {
"appendAttribution": false
},
"subject": "Workflow review needed",
"operation": "sendAndWait",
"approvalOptions": {
"values": {
"approvalType": "double"
}
}
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "f6ba8847-b50e-46f7-9d96-c6fbd738fcb0",
"name": "Check if Approved",
"type": "n8n-nodes-base.if",
"position": [
1040,
-80
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "a3de7dcb-5fc4-4ef8-a37f-a0f53e8a6fc8",
"operator": {
"type": "boolean",
"operation": "equals"
},
"leftValue": "={{ $json.data.approved }}",
"rightValue": true
}
]
}
},
"typeVersion": 2.2
},
{
"id": "8ea14b45-7c8a-491d-9d0a-e3d9a4d35eff",
"name": "Publish Blog Post to WordPress",
"type": "n8n-nodes-base.wordpress",
"position": [
1216,
-240
],
"parameters": {
"title": "={{ $('Generate Blog Post with GPT-4').item.json.message.content.title }}",
"additionalFields": {
"content": "={{ $('Generate Blog Post with GPT-4').item.json.message.content.blog_post }}"
}
},
"credentials": {
"wordpressApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "409fa6a7-4655-4fee-9ed8-7bcfadcb2661",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-416,
-560
],
"parameters": {
"width": 736,
"height": 688,
"content": "## \ud83d\udcdd Generate Blog Post from Keyword Using Dumpling AI + GPT-4\n\nThis workflow creates and publishes a blog post from a single keyword, using AI for research, writing, and publishing.\n\n### \ud83d\udd04 How it works:\n1. Keyword is submitted via form \n2. Dumpling AI searches Google for related content \n3. Extracts:\n - Top 2 results \n - People Also Ask (PAA) questions \n - Related searches \n4. GPT-4 uses the most useful PAA to generate a detailed blog post \n5. Blog draft is emailed for review \n6. If approved \u2192 post is auto-published to WordPress\n\n\u2705 Requires: Dumpling AI, OpenAI, Gmail, WordPress credentials \n\u2705 Ideal for SEO writers, niche bloggers, and content automation\n"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "4b63b037-77e1-4fd5-928c-ce4aff0ac039",
"connections": {
"Check if Approved": {
"main": [
[
{
"node": "Publish Blog Post to WordPress",
"type": "main",
"index": 0
}
],
[
{
"node": "Generate Blog Post with GPT-4",
"type": "main",
"index": 0
}
]
]
},
"Generate Blog Post with GPT-4": {
"main": [
[
{
"node": "Send Blog Post for Review via Gmail",
"type": "main",
"index": 0
}
]
]
},
"Search Google via Dumpling AI": {
"main": [
[
{
"node": "Extract Top Results, PAA & Related Searches",
"type": "main",
"index": 0
}
]
]
},
"Check if People Also Ask Exists": {
"main": [
[
{
"node": "Generate Blog Post with GPT-4",
"type": "main",
"index": 0
}
]
]
},
"Trigger: Receive Keyword from Form": {
"main": [
[
{
"node": "Search Google via Dumpling AI",
"type": "main",
"index": 0
}
]
]
},
"Send Blog Post for Review via Gmail": {
"main": [
[
{
"node": "Check if Approved",
"type": "main",
"index": 0
}
]
]
},
"Extract Top Results, PAA & Related Searches": {
"main": [
[
{
"node": "Check if People Also Ask Exists",
"type": "main",
"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.
gmailOAuth2httpHeaderAuthopenAiApiwordpressApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This template is perfect for SEO writers, niche bloggers, and content marketers who want to generate high-quality blog posts from a single keyword without spending hours on research and writing. If you often find yourself stuck at the research stage or manually drafting blog…
Source: https://n8n.io/workflows/9250/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
100% autonomous workflow that transforms YouTube videos into unique, high-quality, SEO-optimized blog articles and automatically publishes them to WordPress. No human intervention required: it uses Yo
This workflow automates the end-to-end process of creating, optimizing, and publishing content on WordPress.
Write a WordPress post with AI (starting from a few keywords). Uses formTrigger, stickyNote, splitOut, wordpress. Event-driven trigger; 37 nodes.
Splitout Code. Uses stickyNote, formTrigger, splitOut, openAi. Event-driven trigger; 37 nodes.
This n8n workflow template allows you to write WordPress posts by just providing a few keywords. It uses AI technology to write the text and to create the post's featured image. The text includes an i