AutomationFlowsAI & RAG › Monitor Regulatory Website Changes with Claude Sonnet and Gmail Alerts

Monitor Regulatory Website Changes with Claude Sonnet and Gmail Alerts

BySwapnil Mandloi @swapnil-mandloi on n8n.io

This workflow runs daily to monitor regulatory websites, detect page changes via hashing, analyze potential compliance impact with Anthropic Claude Sonnet, log findings to n8n Data Tables, and email the relevant compliance owner through Gmail. Runs on a daily schedule and loads…

Cron / scheduled trigger★★★★☆ complexityAI-powered22 nodesHTTP RequestCryptoData TableAgentAnthropic ChatOutput Parser StructuredGmail
AI & RAG Trigger: Cron / scheduled Nodes: 22 Complexity: ★★★★☆ AI nodes: yes Added:

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

This workflow follows the Agent → Datatable 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": "PqglJ2PF5v2oFAxY",
  "meta": {
    "builderVariant": "mcp",
    "aiBuilderAssisted": true
  },
  "name": "Automated Regulatory Audit Engine",
  "tags": [],
  "nodes": [
    {
      "id": "706c6228-533f-4692-9999-09dd11c496b3",
      "name": "Daily Watch Cycle",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        0,
        64
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "159922eb-6151-4af6-ad46-baca99df7594",
      "name": "Load Watch Sources",
      "type": "n8n-nodes-base.code",
      "position": [
        224,
        64
      ],
      "parameters": {
        "jsCode": "const sources = [\n  { sourceName: 'SEBI Circulars', url: 'https://www.sebi.gov.in/sebiweb/home/HomeAction.do?doListing=yes&sid=1&ssid=6&smid=0', sector: 'BFSI', jurisdiction: 'India', ownerEmail: 'user@example.com' },\n  { sourceName: 'RBI Notifications', url: 'https://www.rbi.org.in/Scripts/NotificationUser.aspx', sector: 'BFSI', jurisdiction: 'India', ownerEmail: 'user@example.com' },\n  { sourceName: 'US FDA Press Announcements', url: 'https://www.fda.gov/news-events/fda-newsroom/press-announcements', sector: 'Pharma', jurisdiction: 'US', ownerEmail: 'user@example.com' },\n  { sourceName: 'EMA News', url: 'https://www.ema.europa.eu/en/news', sector: 'Pharma', jurisdiction: 'EU', ownerEmail: 'user@example.com' },\n  { sourceName: 'OSHA News', url: 'https://www.osha.gov/news', sector: 'Manufacturing', jurisdiction: 'US', ownerEmail: 'user@example.com' }\n];\nreturn sources.map(s => ({ json: s }));"
      },
      "typeVersion": 2
    },
    {
      "id": "9fd9cff8-c979-4448-870d-0b459ded46e7",
      "name": "Watch Cycle Complete",
      "type": "n8n-nodes-base.set",
      "position": [
        672,
        -208
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "status",
              "name": "status",
              "type": "string",
              "value": "complete"
            },
            {
              "id": "finishedAt",
              "name": "finishedAt",
              "type": "string",
              "value": "={{ $now.toISO() }}"
            }
          ]
        }
      },
      "typeVersion": 3.5
    },
    {
      "id": "70902452-2e66-4587-b5d3-2d9badd79035",
      "name": "Fetch Source Page",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "maxTries": 3,
      "position": [
        672,
        -16
      ],
      "parameters": {
        "url": "={{ $json.url }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "text"
            }
          }
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.3,
      "waitBetweenTries": 2000
    },
    {
      "id": "2ab19dec-a010-4706-8838-d2050d075557",
      "name": "Compute Content Hash",
      "type": "n8n-nodes-base.crypto",
      "position": [
        896,
        -16
      ],
      "parameters": {
        "value": "={{ JSON.stringify($json) }}",
        "dataPropertyName": "contentHash"
      },
      "typeVersion": 2
    },
    {
      "id": "d31cda8a-4300-4edc-8076-34984d198b21",
      "name": "Get Prior Watch State",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        1120,
        -16
      ],
      "parameters": {
        "limit": 1,
        "filters": {
          "conditions": [
            {
              "keyName": "url",
              "keyValue": "={{ $('Per-Source Loop').item.json.url }}"
            }
          ]
        },
        "operation": "get",
        "dataTableId": {
          "__rl": true,
          "mode": "name",
          "value": "reg_radar_watch_state"
        }
      },
      "typeVersion": 1.1,
      "alwaysOutputData": true
    },
    {
      "id": "7c544e09-f308-443a-83c7-34ee451f950d",
      "name": "Assemble Change Record",
      "type": "n8n-nodes-base.set",
      "position": [
        1344,
        -16
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "sourceName",
              "name": "sourceName",
              "type": "string",
              "value": "={{ $('Per-Source Loop').item.json.sourceName }}"
            },
            {
              "id": "url",
              "name": "url",
              "type": "string",
              "value": "={{ $('Per-Source Loop').item.json.url }}"
            },
            {
              "id": "sector",
              "name": "sector",
              "type": "string",
              "value": "={{ $('Per-Source Loop').item.json.sector }}"
            },
            {
              "id": "jurisdiction",
              "name": "jurisdiction",
              "type": "string",
              "value": "={{ $('Per-Source Loop').item.json.jurisdiction }}"
            },
            {
              "id": "ownerEmail",
              "name": "ownerEmail",
              "type": "string",
              "value": "={{ $('Per-Source Loop').item.json.ownerEmail }}"
            },
            {
              "id": "currentHash",
              "name": "currentHash",
              "type": "string",
              "value": "={{ $('Compute Content Hash').item.json.contentHash }}"
            },
            {
              "id": "priorHash",
              "name": "priorHash",
              "type": "string",
              "value": "={{ $json.contentHash || '' }}"
            },
            {
              "id": "isBaseline",
              "name": "isBaseline",
              "type": "boolean",
              "value": "={{ !$json.contentHash }}"
            },
            {
              "id": "changed",
              "name": "changed",
              "type": "boolean",
              "value": "={{ !!$json.contentHash && $json.contentHash !== $('Compute Content Hash').item.json.contentHash }}"
            },
            {
              "id": "excerpt",
              "name": "excerpt",
              "type": "string",
              "value": "={{ ($('Fetch Source Page').item.json.data || '').toString().replace(/<[^>]+>/g, ' ').replace(/\\s+/g, ' ').slice(0, 6000) }}"
            },
            {
              "id": "checkedAt",
              "name": "checkedAt",
              "type": "string",
              "value": "={{ $now.toISO() }}"
            }
          ]
        }
      },
      "typeVersion": 3.5
    },
    {
      "id": "59c18255-38bc-4a87-b77a-f3b1744754a9",
      "name": "Upsert Watch State",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        1568,
        -16
      ],
      "parameters": {
        "columns": {
          "value": {
            "url": "={{ $('Assemble Change Record').item.json.url }}",
            "sector": "={{ $('Assemble Change Record').item.json.sector }}",
            "sourceName": "={{ $('Assemble Change Record').item.json.sourceName }}",
            "contentHash": "={{ $('Assemble Change Record').item.json.currentHash }}",
            "lastCheckedAt": "={{ $('Assemble Change Record').item.json.checkedAt }}"
          },
          "schema": [
            {
              "id": "url",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "sourceName",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "sourceName",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "sector",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "sector",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "contentHash",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "contentHash",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "lastCheckedAt",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "lastCheckedAt",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "url"
          ]
        },
        "filters": {
          "conditions": [
            {
              "keyName": "url",
              "keyValue": "={{ $('Assemble Change Record').item.json.url }}"
            }
          ]
        },
        "options": {},
        "operation": "upsert",
        "dataTableId": {
          "__rl": true,
          "mode": "name",
          "value": "reg_radar_watch_state"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "2d35ba18-5745-4380-9a27-5ec1d1c758fe",
      "name": "Change Detected?",
      "type": "n8n-nodes-base.if",
      "position": [
        1792,
        64
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "operator": {
                "type": "boolean",
                "operation": "true"
              },
              "leftValue": "={{ $('Assemble Change Record').item.json.changed }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "04f45897-5ccb-4644-b099-e43bf3b33252",
      "name": "Analyze Regulatory Impact",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        2016,
        64
      ],
      "parameters": {
        "text": "=A monitored regulatory source has changed.\n\nSource: {{ $('Assemble Change Record').item.json.sourceName }}\nJurisdiction: {{ $('Assemble Change Record').item.json.jurisdiction }}\nSector: {{ $('Assemble Change Record').item.json.sector }}\nURL: {{ $('Assemble Change Record').item.json.url }}\n\nAnalyze the extracted page content below. Identify the specific regulatory change, who it affects, its compliance impact, and concrete recommended actions. If the content is a general listing page, focus on the most recent or prominent item.\n\nEXTRACTED CONTENT:\n{{ $('Assemble Change Record').item.json.excerpt }}",
        "options": {
          "systemMessage": "You are a senior regulatory compliance analyst serving large enterprises. Be factual, concise, and conservative. Never invent obligations that are not supported by the content. Severity MUST be exactly one of: Low, Medium, High, Critical. Set confidence between 0 and 1 reflecting how clearly the content supports your analysis. If the content is ambiguous or appears to be an unchanged listing page, use Low severity and a low confidence."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3.1
    },
    {
      "id": "a5bee1ca-bf34-4963-9454-5d5f905fcf22",
      "name": "Claude Sonnet 4.6",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "position": [
        2024,
        280
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "claude-sonnet-4-6",
          "cachedResultName": "Claude Sonnet 4.6"
        },
        "options": {}
      },
      "typeVersion": 1.5
    },
    {
      "id": "2a3d4262-bc39-4090-b93a-2892196f7a83",
      "name": "Impact Schema",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        2152,
        280
      ],
      "parameters": {
        "jsonSchemaExample": "{ \"changeSummary\": \"Concise plain-language summary of what changed\", \"severity\": \"High\", \"affectedAreas\": [\"capital adequacy reporting\", \"KYC\"], \"recommendedActions\": [\"Update KYC policy doc\", \"Brief compliance committee\"], \"deadline\": \"2026-09-30 or none\", \"confidence\": 0.9 }"
      },
      "typeVersion": 1.3
    },
    {
      "id": "b09f0720-2e0f-43b3-b8e6-82f68182f011",
      "name": "Shape",
      "type": "n8n-nodes-base.set",
      "position": [
        2368,
        64
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "sourceName",
              "name": "sourceName",
              "type": "string",
              "value": "={{ $('Assemble Change Record').item.json.sourceName }}"
            },
            {
              "id": "url",
              "name": "url",
              "type": "string",
              "value": "={{ $('Assemble Change Record').item.json.url }}"
            },
            {
              "id": "sector",
              "name": "sector",
              "type": "string",
              "value": "={{ $('Assemble Change Record').item.json.sector }}"
            },
            {
              "id": "jurisdiction",
              "name": "jurisdiction",
              "type": "string",
              "value": "={{ $('Assemble Change Record').item.json.jurisdiction }}"
            },
            {
              "id": "ownerEmail",
              "name": "ownerEmail",
              "type": "string",
              "value": "={{ $('Assemble Change Record').item.json.ownerEmail }}"
            },
            {
              "id": "currentHash",
              "name": "currentHash",
              "type": "string",
              "value": "={{ $('Assemble Change Record').item.json.currentHash }}"
            },
            {
              "id": "checkedAt",
              "name": "checkedAt",
              "type": "string",
              "value": "={{ $('Assemble Change Record').item.json.checkedAt }}"
            },
            {
              "id": "severity",
              "name": "severity",
              "type": "string",
              "value": "={{ $json.output.severity }}"
            },
            {
              "id": "changeSummary",
              "name": "changeSummary",
              "type": "string",
              "value": "={{ $json.output.changeSummary }}"
            },
            {
              "id": "affectedAreas",
              "name": "affectedAreas",
              "type": "array",
              "value": "={{ $json.output.affectedAreas }}"
            },
            {
              "id": "recommendedActions",
              "name": "recommendedActions",
              "type": "array",
              "value": "={{ $json.output.recommendedActions }}"
            },
            {
              "id": "deadline",
              "name": "deadline",
              "type": "string",
              "value": "={{ $json.output.deadline }}"
            },
            {
              "id": "confidence",
              "name": "confidence",
              "type": "number",
              "value": "={{ $json.output.confidence }}"
            },
            {
              "id": "executionId",
              "name": "executionId",
              "type": "string",
              "value": "={{ $execution.id }}"
            }
          ]
        }
      },
      "typeVersion": 3.5
    },
    {
      "id": "3c08c6ae-6afe-4559-8a66-947648346591",
      "name": "Insert Audit Log",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        2592,
        64
      ],
      "parameters": {
        "columns": {
          "value": {
            "url": "={{ $('Shape').item.json.url }}",
            "sector": "={{ $('Shape').item.json.sector }}",
            "severity": "={{ $('Shape').item.json.severity }}",
            "checkedAt": "={{ $('Shape').item.json.checkedAt }}",
            "confidence": "={{ $('Shape').item.json.confidence }}",
            "sourceName": "={{ $('Shape').item.json.sourceName }}",
            "contentHash": "={{ $('Shape').item.json.currentHash }}",
            "executionId": "={{ $('Shape').item.json.executionId }}",
            "changeSummary": "={{ $('Shape').item.json.changeSummary }}",
            "recommendedActions": "={{ ($('Shape').item.json.recommendedActions || []).join('; ') }}"
          },
          "schema": [
            {
              "id": "checkedAt",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "checkedAt",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "sourceName",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "sourceName",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "url",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "url",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "sector",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "sector",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "contentHash",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "contentHash",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "severity",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "severity",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "changeSummary",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "changeSummary",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "recommendedActions",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "recommendedActions",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "confidence",
              "type": "number",
              "display": true,
              "required": false,
              "displayName": "confidence",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "executionId",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "executionId",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            }
          ],
          "mappingMode": "defineBelow"
        },
        "options": {},
        "dataTableId": {
          "__rl": true,
          "mode": "name",
          "value": "reg_radar_audit_log"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "0cc29d35-4b72-4687-b8f4-e7f206e98101",
      "name": "Alert Compliance Owner",
      "type": "n8n-nodes-base.gmail",
      "onError": "continueRegularOutput",
      "maxTries": 3,
      "position": [
        2816,
        176
      ],
      "parameters": {
        "sendTo": "={{ $('Shape').item.json.ownerEmail }}",
        "message": "=<div style=\"font-family:Inter,Arial,sans-serif;background:#0A1128;color:#E6ECFF;padding:24px;border-radius:12px;max-width:640px\"><div style=\"color:#1B98E0;font-size:13px;letter-spacing:2px;text-transform:uppercase\">Regulatory Radar OS</div><h2 style=\"margin:6px 0 2px;color:#FFFFFF\">{{ $('Shape').item.json.sourceName }}</h2><div style=\"color:#F4A259;font-weight:600\">Severity: {{ $('Shape').item.json.severity }} &nbsp;\u2022&nbsp; Confidence: {{ $('Shape').item.json.confidence }}</div><p style=\"color:#C7D2FE;line-height:1.6;margin-top:16px\">{{ $('Shape').item.json.changeSummary }}</p><div style=\"background:#111B3A;border-left:3px solid #1B98E0;padding:12px 16px;border-radius:8px;margin:16px 0\"><div style=\"color:#8FA6D9;font-size:12px;text-transform:uppercase;letter-spacing:1px\">Recommended actions</div><div style=\"color:#E6ECFF;margin-top:6px\">{{ ($('Shape').item.json.recommendedActions || []).map(a => '\u2022 ' + a).join('<br>') }}</div></div><div style=\"color:#8FA6D9;font-size:13px\">Sector: {{ $('Shape').item.json.sector }} &nbsp;\u2022&nbsp; Deadline: {{ $('Shape').item.json.deadline }}</div><div style=\"color:#8FA6D9;font-size:13px;margin-top:4px\">Source: <a href=\"{{ $('Shape').item.json.url }}\" style=\"color:#1B98E0\">{{ $('Shape').item.json.url }}</a></div><div style=\"margin-top:20px;color:#5A6B99;font-size:11px\">Automated compliance monitoring \u2022 Review and action per your internal policy \u2022 Run {{ $('Shape').item.json.executionId }}</div></div>",
        "options": {
          "appendAttribution": false
        },
        "subject": "=[Reg Radar] {{ $('Shape').item.json.severity }} \u2014 {{ $('Shape').item.json.sourceName }} ({{ $('Shape').item.json.jurisdiction }})"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 2.2,
      "waitBetweenTries": 2000
    },
    {
      "id": "0b9e2dc8-7fd8-4911-9c74-c2ef3607bf6b",
      "name": "Per-Source Loop",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        448,
        64
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "f67f18b9-7220-45a8-b16b-fa079a9e4184",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -208,
        -656
      ],
      "parameters": {
        "width": 560,
        "height": 352,
        "content": "Workflow Architecture Documentation\nAutomated Regulatory Audit Engine\n\nSystem Overview\nThis workflow serves as an automated, agentic AI compliance engine. It systematically monitors designated regulatory sources, utilizes cryptographic hashing to detect unannounced page alterations, and deploys Claude 3.5 Sonnet to evaluate the impact of any detected changes before routing actionable alerts to stakeholders."
      },
      "typeVersion": 1
    },
    {
      "id": "51ff18bb-073f-4dc2-be44-ad4e584f914e",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -144,
        416
      ],
      "parameters": {
        "width": 480,
        "height": 272,
        "content": "1. Initiation & Sourcing\n\nSchedule Trigger (Daily Watch Cycle): Initiates the execution on a strict daily cron schedule.\n\nSet/Code Node (Load Watch Sources): Ingests the predefined array of regulatory URLs and compliance targets requiring monitoring."
      },
      "typeVersion": 1
    },
    {
      "id": "15536dc6-c4f4-4ce1-83f0-65ec4b832d31",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        432,
        400
      ],
      "parameters": {
        "width": 880,
        "height": 544,
        "content": "2. Core Processing (The Iteration Engine)\n\nLoop Node (Per-Source Loop): Iterates the execution payload through each identified regulatory source.\n\nHTTP Request (Fetch Source Page): Retrieves the current live HTML/text content of the target regulatory page.\n\nCrypto Node (Compute Content Hash): Generates a secure hash (e.g., SHA-256) of the fetched content to establish an immutable footprint of the current page state.\n\nDatabase Read (Get Prior Watch State): Queries the database to retrieve the historical hash from the previous successful cycle.\n\nSet Node (Assemble Change Record): Structures the payload, aligning the new hash alongside the historical hash for direct comparison.\n\nDatabase Write (Upsert Watch State): Updates the system database with the newly generated hash to serve as the baseline for the next cycle."
      },
      "typeVersion": 1
    },
    {
      "id": "56f2967b-9518-45eb-9d80-ae495f8c1e69",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1392,
        416
      ],
      "parameters": {
        "width": 592,
        "height": 256,
        "content": "3. Conditional Routing\n\nIF/Switch Node (Change Detected?): Evaluates the payload.\n\nFalse (No match): Loops back to the next source or terminates if the queue is empty.\n\nTrue (Hash mismatch): Routes the payload to the AI analysis branch"
      },
      "typeVersion": 1
    },
    {
      "id": "546f7653-07db-408f-92cc-294cbb3e78dc",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2016,
        432
      ],
      "parameters": {
        "width": 624,
        "height": 544,
        "content": "4. Agentic AI Analysis (True Branch)\n\nAI Agent (Analyze Regulatory Impact): Powered by the Claude Sonnet 4.6 model. This node ingests the detected page changes and processes them to determine the legal or compliance impact.\n\nOutput Parser (Impact Schema): Forces the LLM output into a strict, structured JSON schema to ensure downstream data consistency.\n\nData Transformation (Shape): Cleans and formats the parsed AI output into a standardized alert template.\n\nDatabase Write (Insert Audit Log): Writes the specific change event, the AI\u2019s impact assessment, and the timestamp into an immutable audit ledger.\n\nCommunication Node (Alert Compliance Owner): Dispatches a high-priority, formatted message (via Slack, Email, or internal comms) to the designated stakeholder outlining the regulatory shift."
      },
      "typeVersion": 1
    },
    {
      "id": "3e605314-c2f9-4cb6-97c4-0caf5fb97893",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2720,
        432
      ],
      "parameters": {
        "width": 400,
        "height": 208,
        "content": "5. Termination\n\nNo-Op/End Node (Watch Cycle Complete): Successfully terminates the workflow once all items in the Loop have been processed."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": true,
    "executionOrder": "v1"
  },
  "versionId": "7236807a-2462-4947-97fa-a256d7ded49e",
  "nodeGroups": [],
  "connections": {
    "Shape": {
      "main": [
        [
          {
            "node": "Insert Audit Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Impact Schema": {
      "ai_outputParser": [
        [
          {
            "node": "Analyze Regulatory Impact",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Per-Source Loop": {
      "main": [
        [
          {
            "node": "Watch Cycle Complete",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Fetch Source Page",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Change Detected?": {
      "main": [
        [
          {
            "node": "Analyze Regulatory Impact",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Per-Source Loop",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Insert Audit Log": {
      "main": [
        [
          {
            "node": "Alert Compliance Owner",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claude Sonnet 4.6": {
      "ai_languageModel": [
        [
          {
            "node": "Analyze Regulatory Impact",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Daily Watch Cycle": {
      "main": [
        [
          {
            "node": "Load Watch Sources",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Source Page": {
      "main": [
        [
          {
            "node": "Compute Content Hash",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Load Watch Sources": {
      "main": [
        [
          {
            "node": "Per-Source Loop",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upsert Watch State": {
      "main": [
        [
          {
            "node": "Change Detected?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Compute Content Hash": {
      "main": [
        [
          {
            "node": "Get Prior Watch State",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Prior Watch State": {
      "main": [
        [
          {
            "node": "Assemble Change Record",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Alert Compliance Owner": {
      "main": [
        [
          {
            "node": "Per-Source Loop",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Assemble Change Record": {
      "main": [
        [
          {
            "node": "Upsert Watch State",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Analyze Regulatory Impact": {
      "main": [
        [
          {
            "node": "Shape",
            "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 runs daily to monitor regulatory websites, detect page changes via hashing, analyze potential compliance impact with Anthropic Claude Sonnet, log findings to n8n Data Tables, and email the relevant compliance owner through Gmail. Runs on a daily schedule and loads…

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

More AI & RAG workflows → · Browse all categories →

Related workflows

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

AI & RAG

This workflow automates end-to-end sustainability lifecycle management for corporate sustainability teams, ESG governance officers, and circular economy programme leads. It addresses the challenge of

Form Trigger, Agent, OpenAI Chat +11
AI & RAG

This workflow automates end-to-end ESG (Environmental, Social, and Governance) sustainability reporting for enterprise sustainability teams, compliance officers, and green governance leads. It solves

Agent, OpenAI Chat, Output Parser Structured +12
AI & RAG

If you teach on Udemy at any meaningful scale, you already know the problem: 80% of student messages are variations of the same handful of questions, but every one of them needs a thoughtful reply to

N8N Nodes Globals, HTTP Request, Google Sheets +8
AI & RAG

Aggregates communication data from Slack, Microsoft Teams, Gmail, GitHub, and Confluence into a single, unified AI-powered analysis workflow designed for quality review and automated documentation upd

Slack, Microsoft Teams, Gmail +6
AI & RAG

This workflow automates legal case tracking, deadline management, and exception handling for law firms, corporate legal departments, and court systems managing complex litigation portfolios. Designed

HTTP Request, Agent, Agent Tool +5