AutomationFlowsEmail & Gmail › Detect Toxic Backlinks and Build a Disavow File with Dataforseo, Google…

Detect Toxic Backlinks and Build a Disavow File with Dataforseo, Google…

Original n8n title: Detect Toxic Backlinks and Build a Disavow File with Dataforseo, Google Drive, and Gmail

ByDataForSEO @dataforseo on n8n.io

This workflow helps you quickly identify and disavow harmful backlinks without spending hours on manual exports and backlink reports.

Event trigger★★★★☆ complexity17 nodesGoogle DriveGmailN8N Nodes Dataforseo
Email & Gmail Trigger: Event Nodes: 17 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #13538 — we link there as the canonical source.

This workflow follows the Gmail → Google Drive 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 →

Download .json
{
  "id": "HJ2IazyTALHEVZ5B",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Detect toxic backlinks and build a disavow file in one click with DataForSEO",
  "tags": [],
  "nodes": [
    {
      "id": "2616d002-3206-4b9d-93f2-f75d95ea5bc3",
      "name": "When clicking \u2018Execute workflow\u2019",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -16,
        80
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "bea8a572-2829-440a-a01a-1b2cdc9a2ff9",
      "name": "Create file from text",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        2224,
        -32
      ],
      "parameters": {
        "name": "disavow.txt",
        "content": "={{ $json.text }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "root",
          "cachedResultName": "/ (Root folder)"
        },
        "operation": "createFromText"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "4a8b7cad-c624-43b6-b0e3-cfabd0bd8d51",
      "name": "Send a message (success)",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2448,
        -32
      ],
      "parameters": {
        "sendTo": "user@example.com",
        "message": "=<html>\n<body>\n\n<p>Your disavow file for {{ $('Get spam backlinks').item.json.tasks[0].data.target }} has been generated: <a href=\"https://drive.google.com/file/d/{{ $json.id }}\">Your disavow file</a><p>\n\n<p>Please review it before uploading to Google Search Console.<p/>\n</body>\n</html>",
        "options": {},
        "subject": "=Disavow File Generated \u2013 {{ $('Get spam backlinks').item.json.tasks[0].data.target }} \u2013 {{new Date().toDateTime().format('yyyy-MM-dd')}}"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "e37168db-ad9a-47c8-922c-aaad502ae15d",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        160,
        -144
      ],
      "parameters": {
        "color": 6,
        "width": 1536,
        "height": 432,
        "content": "## Get spam backlinks with DataForSEO\nCreate a DataForSEO connection, specify a Target Domain, and set up additional parameters if needed.\nCreate a Gmail connection and set a receiver."
      },
      "typeVersion": 1
    },
    {
      "id": "acf5d358-ef23-4594-a630-75804a3ed1d7",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1728,
        -144
      ],
      "parameters": {
        "color": 6,
        "width": 848,
        "height": 496,
        "content": "## Generate a disavow file and send it via email\nCreate a Google Drive connection and set a destination folder.\nCreate a Gmail connection and set a receiver."
      },
      "typeVersion": 1
    },
    {
      "id": "d0c0f064-55f1-4a7c-a7b1-384478947e32",
      "name": "Get spam backlinks",
      "type": "n8n-nodes-dataforseo.dataForSeoBacklinksApi",
      "position": [
        656,
        0
      ],
      "parameters": {
        "limit": 1000,
        "offset": "={{ $runIndex * 1000 }}",
        "target": "=dataforseo.com",
        "filters": "[\"backlink_spam_score\", \">\", 50]",
        "operation": "get-backlinks",
        "include_indirect_links": false
      },
      "credentials": {
        "dataForSeoApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "29d1ec3f-a1ae-4f38-ae0a-cf2d2769e0da",
      "name": "Initialize \"items\" field",
      "type": "n8n-nodes-base.set",
      "position": [
        208,
        80
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "0126c659-03a5-4fc8-bd76-62d2ecea1195",
              "name": "items",
              "type": "array",
              "value": "={{ [] }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "5bf461b0-715e-4179-8050-a8d076f65267",
      "name": "Set \"items\" field",
      "type": "n8n-nodes-base.set",
      "position": [
        432,
        80
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "4b3c95a2-4e38-4e37-8e2f-a7e4544808d6",
              "name": "items",
              "type": "array",
              "value": "={{ $json.items }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "11e1be10-2a2c-4d53-9341-d946b388f220",
      "name": "Less than 100K links?",
      "type": "n8n-nodes-base.if",
      "position": [
        880,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "8e73ceaf-24f0-44f9-b817-d03e39818a1c",
              "operator": {
                "type": "number",
                "operation": "lt"
              },
              "leftValue": "={{ $json.tasks[0].result[0].total_count }}",
              "rightValue": 100000
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "19e3b970-0c5c-4d51-8583-0814bcd2021c",
      "name": "Merge \"items\" with DFS response",
      "type": "n8n-nodes-base.set",
      "position": [
        1104,
        -96
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "ddd82419-e43e-44d8-919c-2d6602704da5",
              "name": "items",
              "type": "array",
              "value": "={{ [ ...$('Set \"items\" field').item.json.items, ...$json.tasks[0].result[0].items.map(item => imtem.url_from)] }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "6b1aa169-1664-44e3-a1fb-0051acca92f8",
      "name": "Send a message (too many links)",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1104,
        96
      ],
      "parameters": {
        "sendTo": "user@example.com",
        "message": "You have too many disavow links. Please change the request parameters to generate a valid disavow file.",
        "options": {},
        "subject": "=Disavow File Error \u2013 {{ $json.tasks[0].data.target }} \u2013 {{new Date().toDateTime().format('yyyy-MM-dd')}}",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "fa7af35e-317f-4f22-bb82-9dc379024898",
      "name": "Has more pages?",
      "type": "n8n-nodes-base.if",
      "position": [
        1328,
        80
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cd5943f7-df0b-4329-8436-9a1af3ec7caf",
              "operator": {
                "type": "number",
                "operation": "lt"
              },
              "leftValue": "={{ $runIndex }}",
              "rightValue": "={{ $('Get spam backlinks').item.json.tasks[0].result[0].total_count / 1000 - 1}}"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "12f98583-4b4c-4810-b963-8ce8b7d5723b",
      "name": "Merge \"items\" with last response",
      "type": "n8n-nodes-base.set",
      "position": [
        1552,
        80
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "1e2c8353-5628-4948-abe6-35f8d0f660a5",
              "name": "items",
              "type": "array",
              "value": "={{ [...$('Set \"items\" field').item.json.items, ... $('Get spam backlinks').item.json.tasks[0].result[0].items.map(item => item.url_from)]}}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "e7568448-6d60-412c-a054-4296041a5a24",
      "name": "File size < 2MB",
      "type": "n8n-nodes-base.if",
      "position": [
        2000,
        80
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "d58f601e-584b-40b8-96a1-ac80502a11cf",
              "operator": {
                "type": "number",
                "operation": "lt"
              },
              "leftValue": "={{ $json.fileSize }}",
              "rightValue": 2000000
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "f7ffc34c-ab3b-481d-93c8-26ce6840f858",
      "name": "Calculate file size",
      "type": "n8n-nodes-base.code",
      "position": [
        1776,
        80
      ],
      "parameters": {
        "jsCode": "const text = $json.items.join(\"\\n\");\n\n// \u0420\u0430\u0445\u0443\u0454\u043c\u043e \u0431\u0430\u0439\u0442\u0438 \u0447\u0435\u0440\u0435\u0437 Buffer (\u0432 Code node \u0432\u0456\u043d \u043f\u0440\u0430\u0446\u044e\u0454)\nconst sizeInBytes = Buffer.byteLength(text, 'utf8');\n\nreturn [{\n  json: {\n    text: text,\n    fileSize: sizeInBytes\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "6bbfc262-aa4c-4711-895c-fb8bb02841d1",
      "name": "Send a message (file too large)",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2224,
        176
      ],
      "parameters": {
        "sendTo": "user@example.com",
        "message": "The file size is more than 2MB. Please change the request parameters to generate a valid disavow file.",
        "options": {},
        "subject": "=Disavow File Error \u2013 {{ $('Get spam backlinks').item.json.tasks[0].data.target }} \u2013 {{new Date().toDateTime().format('yyyy-MM-dd')}}",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "6030eef0-942e-44c7-b947-ffd492e343cc",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -464,
        -176
      ],
      "parameters": {
        "width": 400,
        "height": 560,
        "content": "This workflow retrieves toxic backlinks pointing to your domain using the DataForSEO Backlinks API, automatically generates a Google-compliant disavow file, and emails you a link to the file, ready for review and upload into Google Search Console.\n\n## How it works\n1. Triggers manually.\n2. Fetches backlinks for your domain using the DataForSEO Backlinks API.\n3. Filters backlinks by spam score above the threshold (default: >50).\n4. Extracts toxic backlinks along with their key metrics.\n5. Formats all suspicious links into a disavow.txt file aligned with Google\u2019s rules.\n6. Uploads the file to your Google Drive.\n7. Emails you a link for checking the file.\n\n## Setup steps\n1. Create or select your DataForSEO connection (use [your API login and password](https://app.dataforseo.com/api-access)).\n2. Indicate your target domain.\n3. Connect Google Drive and choose a folder. \n4. Connect Gmail and choose who gets the message.\n"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "9a128186-b0ce-475a-85d3-599682a38f1e",
  "connections": {
    "File size < 2MB": {
      "main": [
        [
          {
            "node": "Create file from text",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send a message (file too large)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has more pages?": {
      "main": [
        [
          {
            "node": "Set \"items\" field",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge \"items\" with last response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set \"items\" field": {
      "main": [
        [
          {
            "node": "Get spam backlinks",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get spam backlinks": {
      "main": [
        [
          {
            "node": "Less than 100K links?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate file size": {
      "main": [
        [
          {
            "node": "File size < 2MB",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create file from text": {
      "main": [
        [
          {
            "node": "Send a message (success)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Less than 100K links?": {
      "main": [
        [
          {
            "node": "Merge \"items\" with DFS response",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send a message (too many links)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Initialize \"items\" field": {
      "main": [
        [
          {
            "node": "Set \"items\" field",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge \"items\" with DFS response": {
      "main": [
        [
          {
            "node": "Has more pages?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge \"items\" with last response": {
      "main": [
        [
          {
            "node": "Calculate file size",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \u2018Execute workflow\u2019": {
      "main": [
        [
          {
            "node": "Initialize \"items\" field",
            "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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow helps you quickly identify and disavow harmful backlinks without spending hours on manual exports and backlink reports.

Source: https://n8n.io/workflows/13538/ — original creator credit. Request a take-down →

More Email & Gmail workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Email & Gmail

AICARE Email Blast System. Uses googleDrive, httpRequest, googleSheets, gmail. Event-driven trigger; 39 nodes.

Google Drive, HTTP Request, Google Sheets +2
Email & Gmail

Telegram Code. Uses stickyNote, telegramTrigger, telegram, googleDrive. Event-driven trigger; 37 nodes.

Telegram Trigger, Telegram, Google Drive +2
Email & Gmail

Recruiting agency. Uses typeformTrigger, airtable, httpRequest, googleDrive. Event-driven trigger; 36 nodes.

Typeform Trigger, Airtable, HTTP Request +4
Email & Gmail

Categories: Payments, Project Operations, Client Onboarding

Stripe Trigger, Google Drive, ClickUp +4
Email & Gmail

🎥 Analyze YouTube Video for Summaries, Transcripts & Content + Google Gemini AI. Uses stickyNote, httpRequest, googleDrive, gmail. Event-driven trigger; 33 nodes.

HTTP Request, Google Drive, Gmail +2