{
  "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
          }
        ]
      ]
    }
  }
}