8
n8n 中文网amn8n.com

使用AI和WAVE生成法律网站无障碍声明

中级

这是一个AI, Marketing领域的自动化工作流,包含 13 个节点。主要使用 Set, Code, Html, Gmail, HttpRequest 等节点,结合人工智能技术实现智能自动化。 使用AI和WAVE生成法律网站无障碍声明

前置要求
  • Google 账号和 Gmail API 凭证
  • 可能需要目标 API 的认证凭证
  • Google Gemini API Key
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "meta": {
    "instanceId": "4970c3bf8a443f2d4c35b388ef96894f5ae52e32fa83fc8da098b824d939fbd9"
  },
  "nodes": [
    {
      "id": "7d80a2b6-225b-41c3-9723-b1c533176dcd",
      "name": "获取网站HTML",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1680,
        180
      ],
      "parameters": {
        "url": "={{ $json['URL to analyze'] }}",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "598f30d8-ca38-469e-978b-c521b2163e6c",
      "name": "获取WAVE报告",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1420,
        180
      ],
      "parameters": {
        "url": "=https://wave.webaim.org/api/request?key={{ $('CHANGE THESE: dependencies').item.json.wave_api_key }}&reporttype=4&url={{ $('CHANGE THESE: dependencies').item.json['URL to analyze'] }}\n",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "0e6c3a12-ad82-4b84-85b2-b0d5a3ebe055",
      "name": "多表:您可以连接多个表以实现有组织的数据结构",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -600,
        400
      ],
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"Accessibility Statement\": {\n\t\t\t\"type\": \"string\",\n            \"description\": \"output the HTML code for the accessibility statement here. The statement should use the specified language\"\n\t\t}\n\t}\n}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "3ceda0aa-662d-49c8-a009-520889c54332",
      "name": "无障碍声明生成器",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -860,
        180
      ],
      "parameters": {
        "text": "=You are an expert legal-tech assistant. Your specialty is European digital accessibility law, specifically the **European Accessibility Act (EAA)** and the **Web Content Accessibility Guidelines (WCAG)**.\n\nYour task is to generate a formal **\"Accessibility Statement\"**.\n\nThe final statement must be written **in English** and formatted as a **clean, professional HTML document**. The content must be factually based on the provided data and compliant with the EAA's requirements.\n\n\nPlease generate a compliant Accessibility Statement by following these instructions precisely.\n\n**PART 1: INPUT DATA**\n\nYou will use the following information to construct the statement:\n\n* **Company Name:** `{{ $('CHANGE THESE: dependencies').item.json['Company Name'] }}`\n* **Company Country:** `{{ $('CHANGE THESE: dependencies').item.json['Country of the Company (used to apply local law)'] }}`\n* **Website URL:** `{{ $('CHANGE THESE: dependencies').item.json['URL to analyze'] }}`\n* **Accessibility Scan Results:** A JSON list of all accessibility problems detected on the website.\n    ```json\n    {{ $('Map WAVE Report Items to Website selectors.').item.json.analysisItems.toJsonString() }}\n    ```\n\n**PART 2: YOUR TASK & INSTRUCTIONS**\n\nCreate the HTML code for the \"Accessibility Statement\" by completing the following steps:\n\n**Step 1: Determine Compliance Status**\nAnalyze the `Accessibility Scan Results`. Since the data contains multiple items with an `issue_type` of \"error\", you **must** classify the website's status as **\"partially compliant\"**.\n\n**Step 2: Summarize Non-Accessible Content**\nFrom the `Accessibility Scan Results`, identify the main **categories** of problems. In the final statement, list 2-4 of these general categories. Do **not** list every single error. Good examples are:\n* \"Missing alternative text for images and graphics\"\n* \"Insufficient color contrasts between text and background\"\n* \"Form elements without associated labels\"\n* \"Menus or interactive elements not fully operable by keyboard\"\n\n**Step 3: Construct the Final HTML Document**\nGenerate a complete HTML document in English. The document **must** include the following sections, using the provided English titles:\n\n1.  **`Accessibility Statement`**: The main title of the page.\n2.  **`Commitment to Accessibility`**: A brief, professional introduction stating the company's commitment to digital accessibility in the name of `{{ $('CHANGE THESE: dependencies').item.json['Company Name'] }}`.\n3.  **`Conformance Status`**: State that the website is \"partially conformant with the Web Content Accessibility Guidelines (WCAG) 2.1 level AA\" due to the non-compliances listed below.\n4.  **`Non-Accessible Content`**: List the general problem categories you identified in Step 2.\n5.  **`Preparation of this Accessibility Statement`**: State that the assessment method was a `self-assessment` conducted with automated tools and that the statement was created on `{{ $now.toFormat('MMMM d, yyyy') }}`.\n6.  **`Feedback and Contact Information`**: Provide a section for users to report barriers. **Crucially, use a clear placeholder text** like `[Please insert your contact email address or a link to your contact form here]` so the end-user knows this part must be manually replaced.\n7.  **`Enforcement Procedure`**: This section is country-specific. **You must insert a clear placeholder** informing the user that they need to add the details of their country's official national enforcement body. Use placeholder text like: `[The website owner must insert the name, contact details, and web link for the official national enforcement/arbitration body for their country here.]`\n\n**Step 4: Final Output Requirement**\nYour final response must ONLY be the complete, raw HTML code for the statement in the required JSON format. The Accesibility Statement MUST be in {{ $('CHANGE THESE: dependencies').item.json['Desired Output Language'] }} language!!",
        "options": {},
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 2
    },
    {
      "id": "70f20556-12de-4b43-8950-c3409be30e27",
      "name": "gemini 2.5 pro",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        -920,
        400
      ],
      "parameters": {
        "options": {},
        "modelName": "models/gemini-2.5-pro-preview-06-05"
      },
      "credentials": {
        "googlePalmApi": {
          "id": "srw1vvQUiWhObvtc",
          "name": "Google Gemini(PaLM) Api account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "f16e7f9a-357f-4493-8b2f-677e5c3b3a97",
      "name": "将输出解析为html",
      "type": "n8n-nodes-base.html",
      "position": [
        -480,
        180
      ],
      "parameters": {
        "html": "{{ $json.output['Accessibility Statement'] }}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "c71c1911-4de6-42f9-a804-477237962e47",
      "name": "创建无障碍声明html文件",
      "type": "n8n-nodes-base.moveBinaryData",
      "position": [
        -180,
        180
      ],
      "parameters": {
        "mode": "jsonToBinary",
        "options": {
          "fileName": "=accessibility_statement_{{ $('CHANGE THESE: dependencies').item.json['Company Name'].toSnakeCase() }}.html",
          "mimeType": "text/html",
          "useRawData": true
        },
        "sourceKey": "html",
        "convertAllData": false
      },
      "typeVersion": 1
    },
    {
      "id": "a7b3c3c8-f6b5-42ce-bf7e-b321cb68906c",
      "name": "将WAVE报告项映射到网站选择器",
      "type": "n8n-nodes-base.code",
      "position": [
        -1200,
        180
      ],
      "parameters": {
        "jsCode": "// --- Corrected Script ---\n\nconsole.log(\"--- 1. SCRIPT INITIALIZING ---\");\nconst cheerio = require('cheerio');\nconsole.log(\"Cheerio library loaded.\");\n\nconst fullHtml = $('Get Website HTML').first().json.data;\nconst waveCategories = $('Get WAVE Report').first().json.categories;\nconsole.log(`Input data loaded. HTML Length: ${fullHtml.length}`);\n\n// --- 3. INITIALIZING CHEERIO ---\nconst $$ = cheerio.load(fullHtml);\nconsole.log(`Cheerio loaded HTML successfully. Document title: \"${$$('title').text()}\"`);\n\nconst analysisItems = [];\n\n// --- 4. PROCESSING LOOP ---\nif (waveCategories && typeof waveCategories === 'object') {\n  for (const categoryName in waveCategories) {\n    const category = waveCategories[categoryName];\n    if (category && category.items && typeof category.items === 'object') {\n      for (const itemId in category.items) {\n        const item = category.items[itemId];\n        if (item.selectors && Array.isArray(item.selectors)) {\n          \n          // Loop through the array of selector strings\n          for (const selectorString of item.selectors) {\n            \n            // --- THIS IS THE CORRECTED LINE ---\n            // The selector is the string itself from the array.\n            const selector = selectorString;\n\n            // Ensure the selector is a valid string before using it\n            if (typeof selector === 'string' && selector) {\n              console.log(`  -> Searching for selector: \"${selector.substring(0, 80)}...\"`);\n              const elementNode = $$(selector).first();\n              \n              if (elementNode.length > 0) {\n                console.log(`    -> SUCCESS: Found element!`);\n                let contextHtml = elementNode.parent().html();\n                \n                if (contextHtml && contextHtml.length > 2000) {\n                  contextHtml = $$.html(elementNode);\n                }\n\n                analysisItems.push({\n                  issue_type: categoryName,\n                  description: item.description,\n                  selector: selector,\n                  context_html: contextHtml ? contextHtml.trim() : \"\"\n                });\n              } else {\n                console.log(`    -> WARNING: Could not find element for selector.`);\n              }\n            }\n          }\n        }\n      }\n    }\n  }\n}\n\n// --- 5. FINAL OUTPUT ---\nconsole.log(`\\n--- PROCESSING COMPLETE ---`);\nconsole.log(`Total items collected for AI: ${analysisItems.length}`);\n\nreturn {\n  json: {\n    analysisItems\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "e8750f9c-778f-41fd-aead-270d33e255e4",
      "name": "更改这些:依赖项",
      "type": "n8n-nodes-base.set",
      "position": [
        -1880,
        -100
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "678e5308-808a-46c5-89b4-c68b272e03c6",
              "name": "wave_api_key",
              "type": "string",
              "value": ""
            },
            {
              "id": "470042c1-8609-41ab-ab1e-bf817035d426",
              "name": "URL to analyze",
              "type": "string",
              "value": "="
            },
            {
              "id": "d3c198ec-2bba-45d1-8687-b918fc2f2499",
              "name": "Email for summary",
              "type": "string",
              "value": "example@gmail.com"
            },
            {
              "id": "f15f810e-ce67-463e-8b99-61de6f1bcb6c",
              "name": "Desired Output Language",
              "type": "string",
              "value": "english"
            },
            {
              "id": "219c0199-a819-4e45-bd9e-aa7197060da1",
              "name": "Company Name",
              "type": "string",
              "value": "Tiro"
            },
            {
              "id": "9423eed7-e169-4312-8293-149d305d156e",
              "name": "Country of the Company (used to apply local law)",
              "type": "string",
              "value": "Germany"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "510ed358-75a8-4842-a8aa-0b2fa95144b6",
      "name": "点击\"执行工作流\"时",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -2080,
        180
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "1ebee155-5b9a-4da3-8e63-054bf14b945a",
      "name": "通过邮件发送无障碍声明",
      "type": "n8n-nodes-base.gmail",
      "position": [
        80,
        180
      ],
      "webhookId": "69c88d00-ad22-4a8b-9f6a-f8d81f84c617",
      "parameters": {
        "sendTo": "={{ $('CHANGE THESE: dependencies').item.json['Email for summary'] }}",
        "message": "=This Email contains your Accessibility Statement. Check the attached files.",
        "options": {
          "attachmentsUi": {
            "attachmentsBinary": [
              {}
            ]
          }
        },
        "subject": "=Accessibility Statement for {{ $('CHANGE THESE: dependencies').item.json['Company Name'] }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "ExhDKVxieYxsG75E",
          "name": "Gmail account"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "cdda9066-42d8-4d9f-97a8-9a5184bd58e6",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3020,
        -280
      ],
      "parameters": {
        "color": 5,
        "width": 880,
        "height": 920,
        "content": "# 🚀 自动生成您的欧盟无障碍声明"
      },
      "typeVersion": 1
    },
    {
      "id": "f3a66efe-8bce-4f08-871d-9a9a70f8ab9e",
      "name": "便签1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1980,
        -380
      ],
      "parameters": {
        "color": 4,
        "width": 320,
        "height": 460,
        "content": "# ⚙️ 步骤1:从这里开始!"
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "gemini 2.5 pro": {
      "ai_languageModel": [
        [
          {
            "node": "Accessibility Statement Generator",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Get WAVE Report": {
      "main": [
        [
          {
            "node": "Map WAVE Report Items to Website selectors.",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Website HTML": {
      "main": [
        [
          {
            "node": "Get WAVE Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse output as html": {
      "main": [
        [
          {
            "node": "Create accesibility statement html file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Accessibility Statement Generator",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "CHANGE THESE: dependencies": {
      "main": [
        [
          {
            "node": "Get Website HTML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Accessibility Statement Generator": {
      "main": [
        [
          {
            "node": "Parse output as html",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking ‘Execute workflow’": {
      "main": [
        [
          {
            "node": "CHANGE THESE: dependencies",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create accesibility statement html file": {
      "main": [
        [
          {
            "node": "Send accessibility statement by email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Map WAVE Report Items to Website selectors.": {
      "main": [
        [
          {
            "node": "Accessibility Statement Generator",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

中级 - 人工智能, 营销

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
中级
节点数量13
分类2
节点类型11
难度说明

适合有一定经验的用户,包含 6-15 个节点的中等复杂度工作流

作者
Lukas Kunhardt

Lukas Kunhardt

@lukaskunhardt

Automation Expert with a focus on structured data extraction from messy inputs.

外部链接
在 n8n.io 查看

分享此工作流