
Public SEO - Google & Bing Index Automation
Description
Categories
🤖 AI & Machine Learning
Nodes Used
n8n-nodes-base.ifn8n-nodes-base.setn8n-nodes-base.setn8n-nodes-base.setn8n-nodes-base.xmln8n-nodes-base.xmln8n-nodes-base.coden8n-nodes-base.coden8n-nodes-base.coden8n-nodes-base.code
PriceGratuit
Views0
Last Updated11/28/2025
workflow.json
{
"id": "Mbf12LrYQKTF8pv3",
"meta": {
"instanceId": "8e9162e70be518ca153a70a16d8785f5bfc6523821e135712fb7ef93fe97a5dd"
},
"name": "Public SEO - Google & Bing Index Automation",
"tags": [],
"nodes": [
{
"id": "48f2a08a-df7a-4401-99bf-561b9b824706",
"name": "When clicking \"Test workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-6112,
208
],
"parameters": {},
"typeVersion": 1
},
{
"id": "ff55b42e-cf6f-4508-97df-268575e8643c",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-6112,
16
],
"parameters": {
"rule": {
"interval": [
{
"daysInterval": 7,
"triggerAtHour": 2,
"triggerAtMinute": 20
}
]
}
},
"typeVersion": 1.1
},
{
"id": "3d20ee43-72d9-4504-9ba9-a0eb201b10b2",
"name": "Config",
"type": "n8n-nodes-base.set",
"position": [
-5792,
112
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "62b17339-0608-4e32-bdc7-f2842e80c830",
"name": "SITE_URL",
"type": "string",
"value": ""
},
{
"id": "f0e1185a-37b2-424d-9ee4-3c5c7cb4dfdf",
"name": "SITEMAP_URL",
"type": "string",
"value": ""
},
{
"id": "4d32ab5c-66c2-4eb6-8f31-2eef77495c35",
"name": "DAYS_BACK",
"type": "number",
"value": 7
},
{
"id": "e9f9eccc-eaa4-4fbd-af28-12e33c26b01e",
"name": "BATCH_SIZE",
"type": "number",
"value": 500
},
{
"id": "b3ac1b81-77f0-4081-892f-d92f7029a11b",
"name": "USE_GOOGLE",
"type": "boolean",
"value": true
},
{
"id": "b435a0dc-3ec5-4161-a9e0-416869d8c6e5",
"name": "USE_INDEXNOW",
"type": "boolean",
"value": true
},
{
"id": "2481f0c9-dc4f-44dc-97c7-b597bede50f6",
"name": "INDEXNOW_KEY",
"type": "string",
"value": ""
},
{
"id": "d48a7a0f-a2f9-41a9-904e-e5b5686c0e2a",
"name": "INDEXNOW_KEY_URL",
"type": "string",
"value": ""
}
]
}
},
"typeVersion": 3.3
},
{
"id": "7a830e64-deec-4510-896a-dca0061ec92e",
"name": "Get sitemap.xml",
"type": "n8n-nodes-base.httpRequest",
"position": [
-5504,
112
],
"parameters": {
"url": "={{ $json.SITEMAP_URL }}",
"options": {}
},
"typeVersion": 4.1
},
{
"id": "5758fc47-d125-40ae-a114-2419e0625236",
"name": "Convert sitemap to JSON",
"type": "n8n-nodes-base.xml",
"position": [
-5280,
112
],
"parameters": {
"options": {}
},
"typeVersion": 1
},
{
"id": "b549d6c6-978d-4d21-b549-f0975eab16df",
"name": "Get content-specific sitemaps",
"type": "n8n-nodes-base.splitOut",
"position": [
-5056,
112
],
"parameters": {
"options": {},
"fieldToSplitOut": "sitemapindex.sitemap"
},
"typeVersion": 1
},
{
"id": "b83c4ac7-cda3-4487-b0fa-344c2250ee1e",
"name": "Get content of each sitemap",
"type": "n8n-nodes-base.httpRequest",
"position": [
-4832,
112
],
"parameters": {
"url": "={{ $json.loc }}",
"options": {}
},
"typeVersion": 4.1
},
{
"id": "841edc35-aa92-48a6-b6b4-ff0dbf67efd7",
"name": "convert page data to JSON",
"type": "n8n-nodes-base.xml",
"position": [
-4608,
112
],
"parameters": {
"options": {
"explicitArray": false
}
},
"typeVersion": 1
},
{
"id": "d66b327c-f641-4d99-9d5b-7b29b20f8d90",
"name": "Force urlset.url to array",
"type": "n8n-nodes-base.set",
"position": [
-4384,
112
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"name": "urlset.url",
"type": "array",
"value": "={{ $json.urlset && $json.urlset.url ? ($json.urlset.url[0] ? $json.urlset.url : [$json.urlset.url]) : [] }}"
}
]
}
},
"typeVersion": 3.3
},
{
"id": "6b1490a3-f874-4259-887e-6fad9bfc82c9",
"name": "Split Out",
"type": "n8n-nodes-base.splitOut",
"position": [
-4160,
112
],
"parameters": {
"options": {},
"fieldToSplitOut": "urlset.url"
},
"typeVersion": 1
},
{
"id": "4417b088-ab0f-46ce-9b9f-00d31d4748c7",
"name": "Sort",
"type": "n8n-nodes-base.sort",
"position": [
-3936,
112
],
"parameters": {
"options": {},
"sortFieldsUi": {
"sortField": [
{
"order": "descending",
"fieldName": "lastmod"
}
]
}
},
"typeVersion": 1
},
{
"id": "b8363b24-a59c-489f-a940-37377d271cfc",
"name": "Assign mandatory sitemap fields",
"type": "n8n-nodes-base.set",
"position": [
-3712,
112
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"name": "lastmod",
"type": "string",
"value": "={{ $json.lastmod }}"
},
{
"name": "loc",
"type": "string",
"value": "={{ $json.loc }}"
}
]
}
},
"typeVersion": 3.3
},
{
"id": "c3f46292-66c4-4cf5-a526-29c6d0881576",
"name": "Filter: lastmod within DAYS_BACK",
"type": "n8n-nodes-base.code",
"position": [
-3488,
112
],
"parameters": {
"jsCode": "const daysBack = $items('Config')[0].json.DAYS_BACK || 7;\nconst cutoff = new Date(Date.now() - daysBack*24*60*60*1000);\nconst items = $items().filter(i => {\n const lm = i.json.lastmod ? new Date(i.json.lastmod) : null;\n return lm && lm >= cutoff;}).map(i => ({ json: { loc: i.json.loc, lastmod: i.json.lastmod } }));\nreturn items;"
},
"typeVersion": 2
},
{
"id": "1030c52f-fe20-4132-b189-96cd37d0245a",
"name": "Loop Over Items (Google)",
"type": "n8n-nodes-base.splitInBatches",
"position": [
-2992,
-144
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "f86127b7-02df-42a0-8300-94dbee7d3bc6",
"name": "Check status (Google)",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueErrorOutput",
"position": [
-2768,
-128
],
"parameters": {
"url": "=https://indexing.googleapis.com/v3/urlNotifications/metadata?url={{ encodeURIComponent($json.loc) }}",
"options": {
"response": {
"response": {
"fullResponse": true
}
}
},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googleApi"
},
"credentials": {
"googleApi": {
"id": "IakWbbx0a4c1W8qa",
"name": "Google Service Account account"
}
},
"typeVersion": 4.1
},
{
"id": "b8e4756d-20fe-4649-b2b2-34d48c989a7a",
"name": "is new? (Google)",
"type": "n8n-nodes-base.if",
"position": [
-2576,
-224
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "3ab7c657-442a-42cd-8ae8-e540da5d9eb8",
"operator": {
"type": "dateTime",
"operation": "after"
},
"leftValue": "={{ $('Loop Over Items (Google)').item.json.lastmod }}",
"rightValue": "={{ $json.body.latestUpdate.notifyTime }}"
}
]
}
},
"typeVersion": 2
},
{
"id": "92ed404d-d2c9-4a7f-83ff-487102dbc92a",
"name": "URL Updated (Google)",
"type": "n8n-nodes-base.httpRequest",
"position": [
-2352,
-112
],
"parameters": {
"url": "=https://indexing.googleapis.com/v3/urlNotifications:publish",
"method": "POST",
"options": {},
"jsonBody": "={ \"url\": \"{{ $('Loop Over Items (Google)').item.json.loc }}\", \"type\": \"URL_UPDATED\" }",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googleApi"
},
"credentials": {
"googleApi": {
"id": "IakWbbx0a4c1W8qa",
"name": "Google Service Account account"
}
},
"typeVersion": 4.1
},
{
"id": "53dff327-ea63-45d3-9654-cd281f7588b3",
"name": "Wait (Google jitter)",
"type": "n8n-nodes-base.wait",
"position": [
-2128,
-112
],
"webhookId": "edc2dccb-7bcb-4f01-a5c5-fb0ce0d46176",
"parameters": {
"unit": "seconds",
"amount": "={{ (0.25 + Math.random()*0.75).toFixed(2) }}"
},
"typeVersion": 1
},
{
"id": "904715c5-ddb7-40cc-b256-1b7c80b5a736",
"name": "Split In Batches (IndexNow ≤500)",
"type": "n8n-nodes-base.splitInBatches",
"position": [
-2976,
320
],
"parameters": {
"options": {},
"batchSize": "={{ Math.min(($items('Config')[0].json.BATCH_SIZE || 500), 500) }}"
},
"typeVersion": 3
},
{
"id": "55fe2b25-1683-4761-9c22-f5f5bb880bfb",
"name": "Build IndexNow payload",
"type": "n8n-nodes-base.code",
"position": [
-2720,
336
],
"parameters": {
"jsCode": "const batch = $items();\nif (!batch.length) return [];\n\n// 1) Pull & sanitize raw URLs\nlet urls = batch\n .map(i => (i && i.json && i.json.loc) ? String(i.json.loc).trim() : null)\n .filter(u => !!u); // remove null/empty\n\n// 2) Keep only absolute http/https\nurls = urls.filter(u => /^https?:\\/\\//i.test(u));\n\n// 3) Ensure they match your site host (precompute host once)\nconst siteUrl = $items('Config')[0].json.SITE_URL || '';\nconst m = siteUrl.match(/^https?:\\/\\/([^/]+)/i);\nconst host = m ? m[1] : '';\n\n// If you prefer to pass HOST explicitly in Config, replace host above with:\n// const host = $items('Config')[0].json.HOST;\n\nurls = urls.filter(u => {\n const h = (u.match(/^https?:\\/\\/([^/]+)/i) || [])[1] || '';\n return h.toLowerCase() === host.toLowerCase();\n});\n\n// 4) De-dupe\nurls = Array.from(new Set(urls));\n\n// 5) Guard: IndexNow expects at least 1 valid URL\nif (!urls.length || !host) return [];\n\nreturn [{\n json: {\n host,\n key: $items('Config')[0].json.INDEXNOW_KEY,\n keyLocation: $items('Config')[0].json.INDEXNOW_KEY_URL,\n urlList: urls\n }\n}];\n"
},
"typeVersion": 2
},
{
"id": "78e5c981-997b-4918-9af5-579a79d1c208",
"name": "IndexNow Submit",
"type": "n8n-nodes-base.httpRequest",
"position": [
-2528,
336
],
"parameters": {
"url": "https://api.indexnow.org/indexnow",
"method": "POST",
"options": {
"response": {
"response": {
"fullResponse": true
}
}
},
"jsonBody": "={{ $json }}",
"sendBody": true,
"specifyBody": "json"
},
"typeVersion": 4.1
},
{
"id": "7355c015-2233-4fe4-9395-bc8044367ac1",
"name": "Wait (IndexNow jitter)",
"type": "n8n-nodes-base.wait",
"position": [
-2336,
336
],
"webhookId": "76b904af-d359-47cb-9692-eba41ab10efe",
"parameters": {
"unit": "seconds",
"amount": "={{ (0.25 + Math.random()*0.75).toFixed(2) }}"
},
"typeVersion": 1
},
{
"id": "653fecfe-62f7-4cb3-9a28-2aee8db93bb9",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-5952,
-384
],
"parameters": {
"width": 416,
"height": 688,
"content": "## Config File\n**You MUST** update these variables:\n* SITE_URL\n* SITEMAP_URL\n* INDEXNOW_KEY: you can create it in the Bing Webmaster tools here https://www.bing.com/indexnow/getstarted \n* INDEXNOW_KEY_URL: it's usually your domain and the INDEXNOW_KEY: wwww.example.com/<INDEXNOW_KEY>\n\nVariables you can update depending on your specs:\n* DAYS_BACK: 7 by default. For Google it's checking the status of the page before submitting but for Indexnow it will ask to index all the pages that been last updated in the last 7 days \n* BATCH_SIZE: 500 it's the default recommended by IndexNow\n* USE_GOOGLE, USE_INDEXNOW: by default it's true which means the process will run for both Google and IndexNow\n"
},
"typeVersion": 1
},
{
"id": "1bc88f9f-1ae1-4d0e-afc2-817134d54d89",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-5520,
-192
],
"parameters": {
"color": 3,
"width": 2160,
"height": 496,
"content": "## Parsing the sitemap and generating a list of the urls order by last modification date.\n* No need to edit anything here"
},
"typeVersion": 1
},
{
"id": "2bf423e4-f723-401d-adab-610a5ce47a57",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-3312,
-592
],
"parameters": {
"color": 4,
"width": 1360,
"height": 720,
"content": "## Google Autosubmitting\n* You need to update the \"Check status (Google)\" and \"URL updated (Google)\" node with your credentials\n* To create your credentials I recommend the following:\n** Create a service account here https://console.cloud.google.com/iam-admin/serviceaccounts\n** Permissions: Owner\n** Once created you go in the \"Keys\" tab, and create key. That will download a JSON file with your private key and the service account email you created\n* In the two nodes:\n** Authentication: Select \"Predefined credential type\"\n** Credential Type: Select \"Google Service Account API\"\n** Google Service Account API: Create new credential\n* To create the new credential:\n** Region: chose the one corresponding to your project\n** Service account email / Private Key: you can find it in the JSON key you downloaded from the Google Console\n** Toogle \"Set up for use in HTTP Request node\" and input https://www.googleapis.com/auth/indexing\n\n**Important** - once you have created a \"Service account email\" you need to add a user with this email and permission \"Owner\" in your Google Search Console: https://search.google.com/search-console/users"
},
"typeVersion": 1
},
{
"id": "b03f0533-05de-4259-b3e9-d580dfd7e29c",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-3312,
192
],
"parameters": {
"color": 5,
"width": 1360,
"height": 512,
"content": "## IndexNow Autosubmitting\n* No need to change anything here"
},
"typeVersion": 1
},
{
"id": "625b956c-7149-4963-9f19-fd4ab227db0e",
"name": "Gate: Google",
"type": "n8n-nodes-base.code",
"position": [
-3264,
-144
],
"parameters": {
"jsCode": "// Gate: Google\nconst cfg = $items('Config')[0]?.json ?? {};\nconst on = (cfg.USE_GOOGLE === true) || String(cfg.USE_GOOGLE).toLowerCase() === 'true';\nreturn on ? $items() : [];"
},
"typeVersion": 2
},
{
"id": "ac2028ca-4a70-414c-b962-cfb79f9f4f84",
"name": "Gate: IndexNow",
"type": "n8n-nodes-base.code",
"position": [
-3248,
320
],
"parameters": {
"jsCode": "const cfg = $items('Config')[0]?.json ?? {};\nconst on = (cfg.USE_INDEXNOW === true) || String(cfg.USE_INDEXNOW).toLowerCase() === 'true';\nreturn on ? $items() : [];"
},
"typeVersion": 2
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "06347cfd-c610-4edb-96d3-cf04ce434f75",
"connections": {
"Sort": {
"main": [
[
{
"node": "Assign mandatory sitemap fields",
"type": "main",
"index": 0
}
]
]
},
"Config": {
"main": [
[
{
"node": "Get sitemap.xml",
"type": "main",
"index": 0
}
]
]
},
"Split Out": {
"main": [
[
{
"node": "Sort",
"type": "main",
"index": 0
}
]
]
},
"Gate: Google": {
"main": [
[
{
"node": "Loop Over Items (Google)",
"type": "main",
"index": 0
}
]
]
},
"Gate: IndexNow": {
"main": [
[
{
"node": "Split In Batches (IndexNow ≤500)",
"type": "main",
"index": 0
}
]
]
},
"Get sitemap.xml": {
"main": [
[
{
"node": "Convert sitemap to JSON",
"type": "main",
"index": 0
}
]
]
},
"IndexNow Submit": {
"main": [
[
{
"node": "Wait (IndexNow jitter)",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Config",
"type": "main",
"index": 0
}
]
]
},
"is new? (Google)": {
"main": [
[
{
"node": "URL Updated (Google)",
"type": "main",
"index": 0
}
]
]
},
"URL Updated (Google)": {
"main": [
[
{
"node": "Wait (Google jitter)",
"type": "main",
"index": 0
}
]
]
},
"Wait (Google jitter)": {
"main": [
[
{
"node": "Loop Over Items (Google)",
"type": "main",
"index": 0
}
]
]
},
"Check status (Google)": {
"main": [
[
{
"node": "is new? (Google)",
"type": "main",
"index": 0
}
],
[
{
"node": "URL Updated (Google)",
"type": "main",
"index": 0
}
]
]
},
"Build IndexNow payload": {
"main": [
[
{
"node": "IndexNow Submit",
"type": "main",
"index": 0
}
]
]
},
"Wait (IndexNow jitter)": {
"main": [
[
{
"node": "Split In Batches (IndexNow ≤500)",
"type": "main",
"index": 0
}
]
]
},
"Convert sitemap to JSON": {
"main": [
[
{
"node": "Get content-specific sitemaps",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items (Google)": {
"main": [
[],
[
{
"node": "Check status (Google)",
"type": "main",
"index": 0
}
]
]
},
"Force urlset.url to array": {
"main": [
[
{
"node": "Split Out",
"type": "main",
"index": 0
}
]
]
},
"convert page data to JSON": {
"main": [
[
{
"node": "Force urlset.url to array",
"type": "main",
"index": 0
}
]
]
},
"Get content of each sitemap": {
"main": [
[
{
"node": "convert page data to JSON",
"type": "main",
"index": 0
}
]
]
},
"Get content-specific sitemaps": {
"main": [
[
{
"node": "Get content of each sitemap",
"type": "main",
"index": 0
}
]
]
},
"When clicking \"Test workflow\"": {
"main": [
[
{
"node": "Config",
"type": "main",
"index": 0
}
]
]
},
"Assign mandatory sitemap fields": {
"main": [
[
{
"node": "Filter: lastmod within DAYS_BACK",
"type": "main",
"index": 0
}
]
]
},
"Filter: lastmod within DAYS_BACK": {
"main": [
[
{
"node": "Gate: Google",
"type": "main",
"index": 0
},
{
"node": "Gate: IndexNow",
"type": "main",
"index": 0
}
]
]
},
"Split In Batches (IndexNow ≤500)": {
"main": [
[],
[
{
"node": "Build IndexNow payload",
"type": "main",
"index": 0
}
]
]
}
}
}