{
  "name": "webhook trigger cdn domain auto create",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "auto-create-cdn",
        "responseMode": "responseNode",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        -3168,
        -2288
      ],
      "id": "d674d148-e031-4bbe-b5d7-4731a2a51c6e",
      "name": "Webhook"
    },
    {
      "parameters": {
        "jsCode": "const token = $json.headers[\"x-sync-token\"];\nconst oldDomain = $json.body?.old_domain?.trim();\nconst expectedToken = $env.WEBHOOK_TOKEN;\n\nif (!expectedToken) {\n  throw new Error(\"WEBHOOK_TOKEN is not configured in environment\");\n}\n\nif (!token) {\n  throw new Error(\"Missing X-Sync-Token header\");\n}\n\nif (token !== expectedToken) {\n  throw new Error(\"Unauthorized\");\n}\n\nif (!oldDomain) {\n  throw new Error(\"old_domain is required\");\n}\n\nreturn [\n  {\n    json: {\n      old_domain: oldDomain\n    }\n  }\n];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -3120,
        -1904
      ],
      "id": "bc04821e-f5d1-450e-b773-8b0860dc2462",
      "name": "auth"
    },
    {
      "parameters": {
        "documentId": {
          "__rl": true,
          "value": "18Q41382yWFsqtJLUYnjXWOnNJMDSkErGuZ_39QEvAmI",
          "mode": "list",
          "cachedResultName": "HT-\u76f8\u95dc\u8cc7\u8a0a",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/18Q41382yWFsqtJLUYnjXWOnNJMDSkErGuZ_39QEvAmI/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": 428803027,
          "mode": "list",
          "cachedResultName": "CDN\u57df\u540d",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/18Q41382yWFsqtJLUYnjXWOnNJMDSkErGuZ_39QEvAmI/edit#gid=428803027"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        -2896,
        -1904
      ],
      "id": "35f52b55-d45b-4fc4-984b-15cb26d1019d",
      "name": "get cdn list",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const oldDomain = $('auth').first().json.old_domain;\n\nconst match = items.find(item =>\n  String(item.json.old_domain || '').trim() === String(oldDomain || '').trim()\n);\n\nif (!match) {\n  const preview = items.slice(0, 10).map(item => ({\n    old_domain: String(item.json.old_domain || '').trim(),\n    source_domain: String(item.json.source_domain || '').trim(),\n  }));\n\n  throw new Error(\n    '\u627e\u4e0d\u5230 old_domain=' + oldDomain + '\u3002\u524d10\u7b46\u8cc7\u6599\uff1a' + JSON.stringify(preview)\n  );\n}\n\nconst sourceDomain = String(match.json.source_domain || '').trim();\n\nif (!sourceDomain) {\n  throw new Error(\n    'old_domain=' + oldDomain + ' \u5c0d\u61c9\u5217\u7684 source_domain \u662f\u7a7a\u7684'\n  );\n}\n\nreturn [\n  {\n    json: {\n      old_domain: String(oldDomain || '').trim(),\n      source_domain: sourceDomain\n    }\n  }\n];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -2672,
        -1904
      ],
      "id": "2468aeac-fe97-4aaf-91f3-bb3dcf3b8b25",
      "name": "query source_domain"
    },
    {
      "parameters": {
        "documentId": {
          "__rl": true,
          "value": "18Q41382yWFsqtJLUYnjXWOnNJMDSkErGuZ_39QEvAmI",
          "mode": "list",
          "cachedResultName": "HT-\u76f8\u95dc\u8cc7\u8a0a",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/18Q41382yWFsqtJLUYnjXWOnNJMDSkErGuZ_39QEvAmI/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": 1536449518,
          "mode": "list",
          "cachedResultName": "\u5099\u6848\u57df\u540d\u81ea\u52d5\u7e8c\u671f",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/18Q41382yWFsqtJLUYnjXWOnNJMDSkErGuZ_39QEvAmI/edit#gid=1536449518"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        -2032,
        -1904
      ],
      "id": "599f9fb0-5bac-47fa-ab09-457fd03f3cf5",
      "name": "get backup domain list",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const domains = [];\n\nfor (const item of items) {\n  if (item.json[\"domain\"]) {\n    domains.push(item.json[\"domain\"]);\n  }\n}\n\nreturn [\n  {\n    json: {\n      text_base64: Buffer.from(domains.join(\"\\n\")).toString(\"base64\")\n    }\n  }\n];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1776,
        -1904
      ],
      "id": "45bcd0f3-6cf6-4871-ae90-09bce70c3357",
      "name": "fliter results"
    },
    {
      "parameters": {
        "authentication": "privateKey",
        "command": "=set -e\n\nOUTPUT_FILE=\"/opt/n8n/n8n/cdnautomation/root_domains.txt\"\nTMP_FILE=\"/opt/n8n/n8n/cdnautomation/root_domains.txt.tmp\"\n\nBASE64_DATA='{{$json[\"text_base64\"]}}'\n\nif [ -z \"$BASE64_DATA\" ]; then\n  echo \"text_base64 is empty\"\n  exit 1\nfi\n\necho \"$BASE64_DATA\" | base64 -d > \"$TMP_FILE\"\n\nif [ ! -s \"$TMP_FILE\" ]; then\n  echo \"Decoded file is empty\"\n  exit 1\nfi\n\nmv \"$TMP_FILE\" \"$OUTPUT_FILE\"\n\nls -l \"$OUTPUT_FILE\"\nwc -l \"$OUTPUT_FILE\"\nhead -n 20 \"$OUTPUT_FILE\""
      },
      "type": "n8n-nodes-base.ssh",
      "typeVersion": 1,
      "position": [
        -3136,
        -1584
      ],
      "id": "62462f2b-0b47-4fad-8895-46334b8cfb0c",
      "name": "renew root_domains file",
      "credentials": {
        "sshPrivateKey": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "authentication": "privateKey",
        "command": "=set -e\n\nDOMAIN='{{$node[\"query source_domain\"].json[\"source_domain\"]}}'\n\nif [ -z \"$DOMAIN\" ]; then\n  echo \"source_domain is empty\"\n  exit 1\nfi\n\ncd /opt/n8n/n8n/cdnautomation\n\necho \"PWD: $(pwd)\"\necho \"USER: $(whoami)\"\necho \"Start create CDN for: $DOMAIN\"\n\ntimeout 300 bash ./auto_create_tcCdn.sh \"$DOMAIN\"\n\necho \"Done\""
      },
      "type": "n8n-nodes-base.ssh",
      "typeVersion": 1,
      "position": [
        -2912,
        -1584
      ],
      "id": "e594bbf7-5ca7-4dcd-8d98-33fa48542ff4",
      "name": "execute auto create cdn domain script",
      "credentials": {
        "sshPrivateKey": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "return [\n  {\n    json: {\n      accepted: true,\n      old_domain: $json.old_domain,\n      source_domain: $json.source_domain\n    }\n  }\n];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -2480,
        -1904
      ],
      "id": "2c013961-6539-43ae-a9a8-2d1886f1a3f5",
      "name": "prepare webhook response"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ $json }}",
        "options": {
          "responseCode": 200
        }
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.5,
      "position": [
        -2272,
        -1904
      ],
      "id": "75b7af58-e6ed-49df-a975-e0018468d917",
      "name": "Respond to Webhook"
    },
    {
      "parameters": {
        "jsCode": "const exitCode = Number($json.code);\nconst stdoutRaw = String($json.stdout || '');\nconst stderrRaw = String($json.stderr || '');\n\nif (exitCode !== 0) {\n  if (exitCode === 124) {\n    throw new Error('auto_create_tcCdn.sh \u57f7\u884c\u903e\u6642\uff08timeout\uff09\uff0cstdout=' + stdoutRaw);\n  }\n\n  throw new Error(\n    'auto_create_tcCdn.sh \u57f7\u884c\u5931\u6557\uff0ccode=' + exitCode +\n    ', stdout=' + stdoutRaw +\n    ', stderr=' + stderrRaw\n  );\n}\n\nconst stdout = stdoutRaw\n  .replace(/\\r/g, '')\n  .replace(/\\\\n/g, '\\n');\n\nconst lines = stdout\n  .split('\\n')\n  .map(line => line.trim())\n  .filter(Boolean);\n\nconst targetLine = lines.find(line => line.includes('NEW_DOMAIN='));\n\nif (!targetLine) {\n  throw new Error('\u57f7\u884c\u6210\u529f\u4f46\u627e\u4e0d\u5230 NEW_DOMAIN\uff0cstdout=' + stdoutRaw);\n}\n\nconst match = targetLine.match(/NEW_DOMAIN\\s*=\\s*([A-Za-z0-9.-]+)/);\n\nif (!match) {\n  throw new Error('NEW_DOMAIN \u683c\u5f0f\u89e3\u6790\u5931\u6557\uff0ctargetLine=' + targetLine);\n}\n\nconst newDomain = match[1].trim();\nconst oldDomain = String($('query source_domain').first().json.old_domain || '').trim();\n\nreturn [\n  {\n    json: {\n      old_domain: oldDomain,\n      new_domain: newDomain\n    }\n  }\n];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -2688,
        -1584
      ],
      "id": "49615104-f4c2-418f-b42e-6f8a29a339ae",
      "name": "extract new_domain"
    },
    {
      "parameters": {
        "operation": "update",
        "documentId": {
          "__rl": true,
          "value": "18Q41382yWFsqtJLUYnjXWOnNJMDSkErGuZ_39QEvAmI",
          "mode": "list",
          "cachedResultName": "HT-\u76f8\u95dc\u8cc7\u8a0a",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/18Q41382yWFsqtJLUYnjXWOnNJMDSkErGuZ_39QEvAmI/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": 428803027,
          "mode": "list",
          "cachedResultName": "CDN\u57df\u540d",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/18Q41382yWFsqtJLUYnjXWOnNJMDSkErGuZ_39QEvAmI/edit#gid=428803027"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "old_domain": "={{ String($json.old_domain || '').trim() }}",
            "row_number": 0,
            "new_domain": "={{ '=HYPERLINK(\"https://' + String($json.new_domain || '').trim() + '\",\"' + String($json.new_domain || '').trim() + '\")' }}"
          },
          "matchingColumns": [
            "old_domain"
          ],
          "schema": [
            {
              "id": "\u54c1\u724c",
              "displayName": "\u54c1\u724c",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "\u6a21\u677f",
              "displayName": "\u6a21\u677f",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "\u57df\u540dKEY",
              "displayName": "\u57df\u540dKEY",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "\u57df\u540d\u4f5c\u7528",
              "displayName": "\u57df\u540d\u4f5c\u7528",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "old_domain",
              "displayName": "old_domain",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "\u66f4\u63db\u65e5",
              "displayName": "\u66f4\u63db\u65e5",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "source_domain",
              "displayName": "source_domain",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "new_domain",
              "displayName": "new_domain",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "\u53ef\u7528\u5099\u6848\u57df\u540d",
              "displayName": "\u53ef\u7528\u5099\u6848\u57df\u540d",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "\u5f8c\u53f0\u66f4\u63db\u4f4d\u7f6e",
              "displayName": "\u5f8c\u53f0\u66f4\u63db\u4f4d\u7f6e",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "\u5099\u8a3b",
              "displayName": "\u5099\u8a3b",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "\u5f8c\u53f0\u66f4\u63db",
              "displayName": "\u5f8c\u53f0\u66f4\u63db",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "\u4f9b\u61c9\u5546",
              "displayName": "\u4f9b\u61c9\u5546",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "displayName": "row_number",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": true,
              "readOnly": true,
              "removed": false
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        -2480,
        -1584
      ],
      "id": "37c37b19-5160-4a9f-b002-a55c92a3b25a",
      "name": "Google Sheets update row",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "auth",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "auth": {
      "main": [
        [
          {
            "node": "get cdn list",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "get cdn list": {
      "main": [
        [
          {
            "node": "query source_domain",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "get backup domain list": {
      "main": [
        [
          {
            "node": "fliter results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "fliter results": {
      "main": [
        [
          {
            "node": "renew root_domains file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "query source_domain": {
      "main": [
        [
          {
            "node": "prepare webhook response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "renew root_domains file": {
      "main": [
        [
          {
            "node": "execute auto create cdn domain script",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "execute auto create cdn domain script": {
      "main": [
        [
          {
            "node": "extract new_domain",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "prepare webhook response": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Respond to Webhook": {
      "main": [
        [
          {
            "node": "get backup domain list",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "extract new_domain": {
      "main": [
        [
          {
            "node": "Google Sheets update row",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": true,
  "settings": {
    "executionOrder": "v1",
    "binaryMode": "separate",
    "availableInMCP": false
  },
  "versionId": "5945a072-b971-4c0f-86c9-9386b7538fa0",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "EjcfgahuUcQsy0vc",
  "tags": []
}