AutomationFlowsWeb Scraping › Wf5 - Inteligência Normativa | Jurisai

Wf5 - Inteligência Normativa | Jurisai

WF5 - Inteligência Normativa | JurisAI. Uses httpRequest, emailSend. Scheduled trigger; 14 nodes.

Cron / scheduled trigger★★★★☆ complexity14 nodesHTTP RequestEmail Send
Web Scraping Trigger: Cron / scheduled Nodes: 14 Complexity: ★★★★☆ Added:

This workflow follows the Emailsend → HTTP Request 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
{
  "name": "WF5 - Intelig\u00eancia Normativa | JurisAI",
  "nodes": [
    {
      "id": "sticky_wf5",
      "name": "\ud83d\udccb WF5 - Intelig\u00eancia Normativa",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -220,
        -100
      ],
      "parameters": {
        "content": "## WF5 \u2014 Intelig\u00eancia Normativa\n\n**Trigger:** Schedule (toda segunda-feira \u00e0s 06:00 UTC)  \n**Objetivo:** Detectar conflitos normativos entre documentos recentes e o corpus existente\n\n**Fluxo:**\n1. Busca documentos ingeridos na \u00faltima semana\n2. Para cada novo documento:\n   - Busca documentos relacionados no Qdrant (por \u00e1rea/territory)\n   - Envia ao Claude Haiku para an\u00e1lise de conflitos\n   - Se conflito detectado \u2192 insere em normative_conflicts\n3. Notifica curadores por e-mail\n\n\u2699\ufe0f **Ap\u00f3s importar:**\n- Configure credenciais Anthropic e Supabase\n- Configure n\u00f3 de e-mail com seus dados SMTP",
        "height": 300,
        "width": 400,
        "color": 3
      }
    },
    {
      "id": "schedule_wf5",
      "name": "Trigger Semanal",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        250,
        300
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                1
              ],
              "triggerAtHour": 6,
              "triggerAtMinute": 0
            }
          ]
        }
      }
    },
    {
      "id": "get_recent_docs",
      "name": "Buscar Documentos Recentes",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        500,
        300
      ],
      "parameters": {
        "method": "GET",
        "url": "={{ $env.SUPABASE_URL }}/rest/v1/documents",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "={{ $env.SUPABASE_SERVICE_KEY }}"
            },
            {
              "name": "Authorization",
              "value": "=Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
            }
          ]
        },
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "status",
              "value": "eq.em_vigor"
            },
            {
              "name": "ingested_at",
              "value": "gte.{{ new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString() }}"
            },
            {
              "name": "select",
              "value": "id,title,doc_type,legal_area,territory,uf,issuer,published_at,source_url"
            },
            {
              "name": "order",
              "value": "ingested_at.desc"
            },
            {
              "name": "limit",
              "value": "50"
            }
          ]
        }
      }
    },
    {
      "id": "check_has_docs",
      "name": "H\u00e1 Documentos Novos?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        750,
        300
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "cond_has",
              "leftValue": "={{ $input.all().length }}",
              "rightValue": 0,
              "operator": {
                "type": "number",
                "operation": "gt"
              }
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "split_docs",
      "name": "Processar um por vez",
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        1000,
        200
      ],
      "parameters": {
        "batchSize": 1,
        "options": {}
      }
    },
    {
      "id": "search_related",
      "name": "Buscar Docs Relacionados (Qdrant)",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1250,
        200
      ],
      "parameters": {
        "method": "POST",
        "url": "={{ $env.QDRANT_URL }}/collections/{{ $env.QDRANT_COLLECTION }}/points/scroll",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "api-key",
              "value": "={{ $env.QDRANT_API_KEY }}"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "contentType": "json",
        "body": "={{ JSON.stringify({ filter: { must: [{ key: 'status', match: { value: 'em_vigor' } }, { key: 'legal_area', match: { any: $json.legal_area || [] } }] }, limit: 10, with_payload: true, with_vector: false }) }}"
      },
      "continueOnFail": true
    },
    {
      "id": "analyze_conflicts",
      "name": "Analisar Conflitos (Claude Haiku)",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1500,
        200
      ],
      "parameters": {
        "method": "POST",
        "url": "https://api.anthropic.com/v1/messages",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "x-api-key",
              "value": "={{ $env.ANTHROPIC_API_KEY }}"
            },
            {
              "name": "anthropic-version",
              "value": "2023-06-01"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "contentType": "json",
        "body": "={{ JSON.stringify({ model: $env.LLM_TRIAGE, max_tokens: 1024, temperature: 0, system: 'Voc\u00ea \u00e9 um analisador jur\u00eddico especializado em detectar conflitos normativos no direito brasileiro. Analise os documentos fornecidos e identifique poss\u00edveis conflitos. Responda APENAS em JSON v\u00e1lido no formato: { \"has_conflict\": boolean, \"conflict_type\": \"contradicao\"|\"lacuna\"|\"obsolescencia\"|\"divergencia_jurisprudencial\"|\"oportunidade\"|null, \"severity\": \"baixa\"|\"media\"|\"alta\"|\"critica\"|null, \"description\": \"string\"|null }', messages: [{ role: 'user', content: `Documento novo: ${JSON.stringify($('Processar um por vez').first().json)}\n\nDocumentos relacionados no corpus: ${JSON.stringify(($('Buscar Docs Relacionados (Qdrant)').first().json?.result || []).map(r => r.payload).slice(0, 5))}\n\nH\u00e1 conflito normativo entre o documento novo e os existentes?` }] }) }}"
      },
      "continueOnFail": true
    },
    {
      "id": "parse_conflict",
      "name": "Parsear Resposta",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1750,
        200
      ],
      "parameters": {
        "jsCode": "const currentDoc = $('Processar um por vez').first().json;\nconst anthropicResponse = $('Analisar Conflitos (Claude Haiku)').first().json;\n\nlet analysis = { has_conflict: false, conflict_type: null, severity: null, description: null };\ntry {\n  const text = anthropicResponse.content?.[0]?.text || '{}';\n  // Extrair JSON da resposta\n  const jsonMatch = text.match(/\\{[\\s\\S]*\\}/);\n  if (jsonMatch) {\n    analysis = JSON.parse(jsonMatch[0]);\n  }\n} catch (e) {\n  console.log('Erro ao parsear resposta do Claude:', e.message);\n}\n\n// Buscar documentos relacionados para montar o conflito\nconst relatedDocs = ($('Buscar Docs Relacionados (Qdrant)').first().json?.result || []).map(r => r.payload);\nconst relatedDocId = relatedDocs[0]?.document_id || null;\n\nreturn [{\n  json: {\n    doc_a_id: currentDoc.id,\n    doc_a_title: currentDoc.title,\n    doc_b_id: relatedDocId,\n    has_conflict: analysis.has_conflict === true,\n    conflict_type: analysis.conflict_type || null,\n    severity: analysis.severity || 'baixa',\n    description: analysis.description || 'An\u00e1lise autom\u00e1tica WF5'\n  }\n}];"
      }
    },
    {
      "id": "if_conflict",
      "name": "Conflito Detectado?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        2000,
        200
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "cond_conflict",
              "leftValue": "={{ $json.has_conflict }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "equals"
              }
            },
            {
              "id": "cond_has_b",
              "leftValue": "={{ $json.doc_b_id }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "isNotEmpty"
              }
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "insert_conflict",
      "name": "Registrar Conflito",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        2250,
        100
      ],
      "parameters": {
        "method": "POST",
        "url": "={{ $env.SUPABASE_URL }}/rest/v1/normative_conflicts",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "={{ $env.SUPABASE_SERVICE_KEY }}"
            },
            {
              "name": "Authorization",
              "value": "=Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Prefer",
              "value": "return=representation"
            }
          ]
        },
        "sendBody": true,
        "contentType": "json",
        "body": "={{ JSON.stringify({ document_a: $json.doc_a_id, document_b: $json.doc_b_id, conflict_type: $json.conflict_type, description: $json.description, severity: $json.severity, status: 'pendente', detected_by: 'wf5_auto' }) }}"
      },
      "continueOnFail": true
    },
    {
      "id": "no_conflict",
      "name": "Sem Conflito",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        2250,
        300
      ],
      "parameters": {}
    },
    {
      "id": "no_new_docs",
      "name": "Sem Documentos Novos",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        1000,
        400
      ],
      "parameters": {}
    },
    {
      "id": "get_conflicts_count",
      "name": "Contar Conflitos Detectados",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        2500,
        200
      ],
      "parameters": {
        "method": "GET",
        "url": "={{ $env.SUPABASE_URL }}/rest/v1/normative_conflicts?status=eq.pendente&select=id",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "={{ $env.SUPABASE_SERVICE_KEY }}"
            },
            {
              "name": "Authorization",
              "value": "=Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
            },
            {
              "name": "Prefer",
              "value": "count=exact"
            }
          ]
        }
      },
      "continueOnFail": true
    },
    {
      "id": "notify_curator",
      "name": "Notificar Curador",
      "type": "n8n-nodes-base.emailSend",
      "typeVersion": 2.1,
      "position": [
        2750,
        200
      ],
      "parameters": {
        "fromEmail": "jurisai@{{$env.ORG_NAME || 'jurisai.app'}}",
        "toEmail": "={{ $env.CURATOR_EMAIL || 'curador@suaorganizacao.com' }}",
        "subject": "[JurisAI] Relat\u00f3rio semanal: conflitos normativos detectados",
        "emailType": "text",
        "message": "=Relat\u00f3rio Semanal - JurisAI\n\nData: {{ new Date().toLocaleDateString('pt-BR') }}\n\nConflitos normativos pendentes de revis\u00e3o: verifique o painel do JurisAI.\n\nAcesse: {{ $env.WEBHOOK_URL }}\n\n---\nJurisAI - {{ $env.ORG_NAME }}"
      },
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      },
      "continueOnFail": true
    }
  ],
  "connections": {
    "Trigger Semanal": {
      "main": [
        [
          {
            "node": "Buscar Documentos Recentes",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Buscar Documentos Recentes": {
      "main": [
        [
          {
            "node": "H\u00e1 Documentos Novos?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "H\u00e1 Documentos Novos?": {
      "main": [
        [
          {
            "node": "Processar um por vez",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Sem Documentos Novos",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Processar um por vez": {
      "main": [
        [
          {
            "node": "Buscar Docs Relacionados (Qdrant)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Buscar Docs Relacionados (Qdrant)": {
      "main": [
        [
          {
            "node": "Analisar Conflitos (Claude Haiku)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Analisar Conflitos (Claude Haiku)": {
      "main": [
        [
          {
            "node": "Parsear Resposta",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parsear Resposta": {
      "main": [
        [
          {
            "node": "Conflito Detectado?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Conflito Detectado?": {
      "main": [
        [
          {
            "node": "Registrar Conflito",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Sem Conflito",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Registrar Conflito": {
      "main": [
        [
          {
            "node": "Contar Conflitos Detectados",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Contar Conflitos Detectados": {
      "main": [
        [
          {
            "node": "Notificar Curador",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "saveManualExecutions": false,
    "errorWorkflow": ""
  },
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "tags": [
    {
      "id": "jurisai",
      "name": "JurisAI"
    },
    {
      "id": "normativa",
      "name": "inteligencia-normativa"
    }
  ]
}

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

WF5 - Inteligência Normativa | JurisAI. Uses httpRequest, emailSend. Scheduled trigger; 14 nodes.

Source: https://github.com/JeffersonMFti/JurisAI/blob/f883fa2f162a02b1a2aa83da7d6d5f8fed2964b3/workflows/WF5_normative_intel.json — original creator credit. Request a take-down →

More Web Scraping workflows → · Browse all categories →

Related workflows

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

Web Scraping

Birthday Automation - Production (Fixed). Uses stopAndError, httpRequest, emailSend, bannerbear. Scheduled trigger; 86 nodes.

Stop And Error, HTTP Request, Email Send +1
Web Scraping

This workflow is an improvement of this workflow by Greg Brzezinka.

HTTP Request, Email Send, XML +1
Web Scraping

N8N-Self-Updater. Uses ssh, emailSend, httpRequest. Scheduled trigger; 27 nodes.

Ssh, Email Send, HTTP Request
Web Scraping

&gt; An automated n8n workflow originally built for DigitalOcean-based n8n deployments, but fully compatible with any VPS or cloud hosting (e.g., AWS, Google Cloud, Hetzner, Linode, etc.) where n8n ru

Ssh, Email Send, HTTP Request
Web Scraping

What if you could spot a major sales problem—or a winning campaign—the very next morning, instead of weeks later? Imagine receiving a beautiful, data-rich alert directly in your inbox the moment your

QuickBooks, HTTP Request, Email Send