AutomationFlowsAI & RAG › Opta | Agente De Ia (principal)

Opta | Agente De Ia (principal)

OPTA | AGENTE DE IA (PRINCIPAL). Uses httpRequest, redis, openAi, agent. Scheduled trigger; 54 nodes.

Cron / scheduled trigger★★★★★ complexityAI-powered54 nodesHTTP RequestRedisOpenAIAgentOpenAI ChatMemory Redis ChatMcp Client Tool
AI & RAG Trigger: Cron / scheduled Nodes: 54 Complexity: ★★★★★ AI nodes: yes Added:

This workflow follows the Agent → 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": "OPTA | AGENTE DE IA (PRINCIPAL)",
  "nodes": [
    {
      "id": "a001",
      "name": "Trigger 30s",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        0,
        300
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "seconds",
              "secondsInterval": 30
            }
          ]
        }
      }
    },
    {
      "id": "a002",
      "name": "Busca Grupos",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        220,
        300
      ],
      "parameters": {
        "url": "https://vgawovbxbvtbyrcwdrto.supabase.co/rest/v1/grupos_monitorados",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "select",
              "value": "*"
            },
            {
              "name": "ativo",
              "value": "eq.true"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "<redacted-credential>"
            },
            {
              "name": "Authorization",
              "value": "<redacted-credential>"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "a003",
      "name": "Extrai Grupos",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        440,
        300
      ],
      "parameters": {
        "jsCode": "const all = $input.all();\nif (all.length === 0) return [];\n// HTTP Request ja divide array em itens \u2014 passa direto\nif (all.length === 1 && Array.isArray(all[0].json)) {\n  return all[0].json.map(g => ({ json: g }));\n}\nreturn all.map(i => ({ json: i.json }));"
      }
    },
    {
      "id": "a005",
      "name": "Busca Msgs WTS",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        880,
        300
      ],
      "parameters": {
        "url": "=https://api.wts.chat/chat/v1/session/{{ $json.session_id }}/message",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "PageSize",
              "value": "30"
            },
            {
              "name": "OrderDirection",
              "value": "DESCENDING"
            },
            {
              "name": "CreatedAt.After",
              "value": "={{ $json.last_processed_at || '2024-01-01T00:00:00Z' }}"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "accept",
              "value": "application/json"
            }
          ]
        },
        "options": {}
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "a006",
      "name": "IF Tem Msgs",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        1100,
        300
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "cond1",
              "leftValue": "={{ $json.totalItems }}",
              "rightValue": 0,
              "operator": {
                "type": "number",
                "operation": "gt"
              }
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "a007",
      "name": "Code: Debounce Check",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1320,
        180
      ],
      "parameters": {
        "jsCode": "const msgsData = $input.first().json;\nconst grupo   = $('Extrai Grupos').item.json;\nconst allMsgs = msgsData.items || [];\nif (allMsgs.length === 0) return [];\n\n// CR\u00cdTICO: WTS API CreatedAt.After faz >= (inclusivo) em vez de >\n// Filtra client-side msgs que j\u00e1 foram processadas (createdAt <= last_processed_at)\nconst lastMs = new Date(grupo.last_processed_at || '2024-01-01').getTime();\nconst msgs = allMsgs.filter(m => new Date(m.createdAt || m.timestamp).getTime() > lastMs);\nif (msgs.length === 0) return []; // nada realmente novo\n\n// items[0] = mais recente (DESCENDING)\nconst newest     = msgs[0];\nconst newestMs   = new Date(newest.createdAt || newest.timestamp).getTime();\nconst diffSec    = (Date.now() - newestMs) / 1000;\n\n// +1ms no last_processed_at futuro pra evitar re-pegar a mesma msg quando WTS faz >=\nconst newestPlus1 = new Date(newestMs + 1).toISOString();\n\nreturn [{\n  json: {\n    session_id:        grupo.session_id,\n    zapi_group_id:     grupo.zapi_group_id,\n    nome:              grupo.nome,\n    ai_ativo:          grupo.ai_ativo,\n    last_processed_at: grupo.last_processed_at,\n    mensagens:         msgs,\n    newest_msg_at:     newestPlus1,\n    debounce_ok:       diffSec > 15,\n    diff_seconds:      Math.round(diffSec)\n  }\n}];"
      }
    },
    {
      "id": "a008",
      "name": "IF Debounce OK",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        1540,
        180
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "cond1",
              "leftValue": "={{ $json.debounce_ok }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true"
              }
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "a009",
      "name": "Atualiza Processado",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1760,
        60
      ],
      "parameters": {
        "method": "PATCH",
        "url": "=https://vgawovbxbvtbyrcwdrto.supabase.co/rest/v1/grupos_monitorados?session_id=eq.{{ $('Extrai Grupos').item.json.session_id }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "<redacted-credential>"
            },
            {
              "name": "Authorization",
              "value": "<redacted-credential>"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Prefer",
              "value": "return=minimal"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={ \"last_processed_at\": \"{{ $('Code: Debounce Check').item.json.newest_msg_at }}\" }",
        "options": {}
      }
    },
    {
      "id": "a010",
      "name": "Code: Detecta Keywords",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3960,
        480
      ],
      "parameters": {
        "jsCode": "const prev = $('Code: Debounce Check').item.json;\nconst msgs = prev.mensagens || [];\n\nconst IS_INBOUND  = d => d === 'FROM_HUB' || d === 'INBOUND';\nconst IS_OUTBOUND = d => d === 'TO_HUB'   || d === 'OUTBOUND';\n\nconst normalize = t => t.toLowerCase().normalize('NFD').replace(/[\\u0300-\\u036f]/g, '');\n\n// Keywords pra ATENDENTE (msgs TO_HUB do painel WTS) \u2014 frases naturais\nconst KW_INICIO = ['sobre esse caso', 'sobre essa questao', 'sobre isso', 'vou verificar', 'vou olhar', 'vou checar', 'estou olhando', 'estou verificando', 'deixa eu verificar', 'vou atender', 'vou ajudar'];\nconst KW_FIM    = ['fico a sua disposicao', 'fico a disposicao', 'estou a sua disposicao', 'estou a disposicao', 'qualquer coisa so chamar', 'qualquer coisa, chamar', 'qualquer outra duvida', 'foi um prazer ajudar', 'obrigado pelo contato', 'resolvido'];\n\n// Keywords FORCE \u2014 funcionam em QUALQUER direction (atendente direto pelo WhatsApp ou cliente)\n// Pra abrir/fechar direto no grupo sem precisar do painel WTS\nconst KW_FORCE_INICIO = ['#abrir', '#atender', '#iniciar', '/abrir'];\nconst KW_FORCE_FIM    = ['#encerrar', '#finalizar', '/fechar'];\n\nlet hasInicio = false, hasFim = false;\nlet msgInicio = null, msgFim = null;\n\nfor (const m of msgs) {\n  const t = normalize(m.text || '');\n\n  // FORCE keywords \u2014 funcionam em qualquer direction (cliente ou atendente)\n  if (!hasInicio && KW_FORCE_INICIO.some(k => t.includes(k))) { hasInicio = true; msgInicio = m; }\n  if (!hasFim    && KW_FORCE_FIM.some(k => t.includes(k)))    { hasFim    = true; msgFim    = m; }\n\n  // Frases naturais \u2014 s\u00f3 TO_HUB (atendente via painel WTS)\n  if (!IS_OUTBOUND(m.direction)) continue;\n  if (!hasInicio && KW_INICIO.some(k => t.includes(k))) { hasInicio = true; msgInicio = m; }\n  if (!hasFim    && KW_FIM.some(k => t.includes(k)))    { hasFim    = true; msgFim    = m; }\n}\n\nconst contextMsgs = [...msgs].reverse()\n  .filter(m => m.text && m.type !== 'NOTE')\n  .map(m => ({\n    role:      IS_INBOUND(m.direction) ? 'user' : 'assistant',\n    content:   m.text,\n    timestamp: m.timestamp || m.createdAt\n  }));\n\nreturn [{ json: { ...prev, hasInicio, hasFim, msgInicio, msgFim, contextMsgs } }];"
      }
    },
    {
      "id": "a011",
      "name": "IF hasInicio",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        4180,
        380
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "cond1",
              "leftValue": "={{ $json.hasInicio }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true"
              }
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "a012",
      "name": "Posta Nota #inicio",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        4400,
        280
      ],
      "parameters": {
        "method": "POST",
        "url": "=https://api.wts.chat/chat/v1/session/{{ $json.session_id }}/note",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "accept",
              "value": "application/json"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "{\"text\": \"#humano (atendente assumiu via keyword)\"}",
        "options": {}
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "a013",
      "name": "Cria Chamado",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        4620,
        280
      ],
      "parameters": {
        "method": "POST",
        "url": "https://vgawovbxbvtbyrcwdrto.supabase.co/rest/v1/rpc/abrir_chamado",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "<redacted-credential>"
            },
            {
              "name": "Authorization",
              "value": "<redacted-credential>"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Prefer",
              "value": "return=minimal"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={ \"p_session_id\": \"{{ $('Code: Detecta Keywords').item.json.session_id }}\", \"p_grupo_nome\": \"{{ $('Code: Detecta Keywords').item.json.nome }}\", \"p_motivo_abertura\": \"keyword_atendente\" }",
        "options": {}
      }
    },
    {
      "id": "a014",
      "name": "IF hasFim",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        4180,
        480
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "cond1",
              "leftValue": "={{ $json.hasFim }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true"
              }
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "a015",
      "name": "Posta Nota #fim",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        4400,
        420
      ],
      "parameters": {
        "method": "POST",
        "url": "=https://api.wts.chat/chat/v1/session/{{ $json.session_id }}/note",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "accept",
              "value": "application/json"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "{\"text\": \"#fim\"}",
        "options": {}
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "a016",
      "name": "Fecha Chamado",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        4620,
        420
      ],
      "parameters": {
        "method": "PATCH",
        "url": "https://vgawovbxbvtbyrcwdrto.supabase.co/rest/v1/rpc/fechar_chamado",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "<redacted-credential>"
            },
            {
              "name": "Authorization",
              "value": "<redacted-credential>"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Prefer",
              "value": "return=minimal"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={ \"p_session_id\": \"{{ $json.session_id }}\", \"p_motivo\": \"keyword_atendente\" }",
        "options": {}
      }
    },
    {
      "id": "a017",
      "name": "Busca \u00daltima Nota",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        4180,
        660
      ],
      "parameters": {
        "url": "=https://api.wts.chat/chat/v1/session/{{ $json.session_id }}/note",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "PageSize",
              "value": "1"
            },
            {
              "name": "OrderDirection",
              "value": "DESCENDING"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "accept",
              "value": "application/json"
            }
          ]
        },
        "options": {}
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "a018",
      "name": "Code: Extrai Estado",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        4400,
        660
      ],
      "parameters": {
        "jsCode": "const notesData = $input.first().json;\nconst lastNote  = (notesData.items || [])[0];\nconst estado    = (lastNote?.text || '').trim();\nconst kw        = $('Code: Detecta Keywords').item.json;\n\nreturn [{\n  json: {\n    ...kw,\n    estado,\n    lastNoteId: lastNote?.id,\n    lastNoteAt: lastNote?.timestamp || lastNote?.createdAt\n  }\n}];"
      }
    },
    {
      "id": "a019",
      "name": "IF Em Atendimento",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        4620,
        660
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": false,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "cond1",
              "leftValue": "={{ $json.estado }}",
              "rightValue": "#humano",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              }
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "a028",
      "name": "IF Novo Atendimento",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        4840,
        780
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": false,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "cond1",
              "leftValue": "={{ $json.estado }}",
              "rightValue": "#inicio",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              }
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "a029",
      "name": "Posta #inicio Novo Atend",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        5060,
        780
      ],
      "parameters": {
        "method": "POST",
        "url": "=https://api.wts.chat/chat/v1/session/{{ $json.session_id }}/note",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "accept",
              "value": "application/json"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "{\"text\": \"#inicio\"}",
        "options": {}
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "a020",
      "name": "IF AI Ativa",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        4840,
        540
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "cond1",
              "leftValue": "={{ $json.ai_ativo }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true"
              }
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "b001",
      "name": "SplitOut Dividir Mensagens",
      "type": "n8n-nodes-base.splitOut",
      "typeVersion": 1,
      "position": [
        1980,
        60
      ],
      "parameters": {
        "fieldToSplitOut": "mensagens",
        "options": {}
      }
    },
    {
      "id": "b002",
      "name": "IF Filtra Inbound",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        2200,
        60
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "d1",
              "leftValue": "={{ $json.direction }}",
              "rightValue": "FROM_HUB",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            },
            {
              "id": "b1",
              "leftValue": "={{ $json.text || \"\" }}",
              "rightValue": "*BIA*",
              "operator": {
                "type": "string",
                "operation": "notStartsWith"
              }
            },
            {
              "id": "b2",
              "leftValue": "={{ $json.text || \"\" }}",
              "rightValue": "\u2063",
              "operator": {
                "type": "string",
                "operation": "notContains"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      }
    },
    {
      "id": "b003a",
      "name": "Verifica Rate Limit",
      "type": "n8n-nodes-base.redis",
      "typeVersion": 1,
      "position": [
        2410,
        60
      ],
      "parameters": {
        "operation": "incr",
        "key": "=bia_turn_{{ $('Set Campos B\u00e1sicos').item.json.sessionId }}_{{ $now.toFormat('yyyyMMddHHmm') }}",
        "expire": true,
        "ttl": 60
      },
      "credentials": {
        "redis": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "b003b",
      "name": "IF Rate OK?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        2620,
        60
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "r1",
              "leftValue": "={{ parseInt($json.value ?? $json.result ?? $json.propertyName ?? Object.values($json)[0] ?? '0') }}",
              "rightValue": 3,
              "operator": {
                "type": "number",
                "operation": "lte"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      }
    },
    {
      "id": "b003",
      "name": "Filtra TEXT",
      "type": "n8n-nodes-base.filter",
      "typeVersion": 2.2,
      "position": [
        2420,
        -60
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "tx",
              "leftValue": "={{ $json.type }}",
              "rightValue": "TEXT",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            },
            {
              "id": "tn",
              "leftValue": "={{ $json.text }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      }
    },
    {
      "id": "b004",
      "name": "Grava TEXT",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        2640,
        -60
      ],
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "1",
              "name": "text",
              "value": "={{ $json.text }}",
              "type": "string"
            },
            {
              "id": "2",
              "name": "createdAt",
              "value": "={{ $json.createdAt }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "b005",
      "name": "Filtra FILE",
      "type": "n8n-nodes-base.filter",
      "typeVersion": 2.2,
      "position": [
        2420,
        180
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "f1",
              "leftValue": "={{ $json.type }}",
              "rightValue": "TEXT",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      }
    },
    {
      "id": "b006",
      "name": "Switch M\u00eddia",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        2640,
        180
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "a",
                    "leftValue": "={{ $json.details?.file?.mimeType }}",
                    "rightValue": "audio/",
                    "operator": {
                      "type": "string",
                      "operation": "startsWith"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "AUDIO"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "i",
                    "leftValue": "={{ $json.details?.file?.mimeType }}",
                    "rightValue": "image/",
                    "operator": {
                      "type": "string",
                      "operation": "startsWith"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "IMAGEM"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "b007",
      "name": "Baixa \u00c1udio",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        2860,
        60
      ],
      "parameters": {
        "url": "={{ $json.details.file.publicUrl }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      }
    },
    {
      "id": "b008",
      "name": "Transcreve \u00c1udio",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 1.5,
      "position": [
        3080,
        60
      ],
      "parameters": {
        "resource": "audio",
        "operation": "transcribe",
        "options": {
          "language": "pt"
        }
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "b009",
      "name": "Grava \u00c1udio",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        3300,
        60
      ],
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "1",
              "name": "text",
              "value": "=[\u00c1udio do cliente]: {{ $json.text }}",
              "type": "string"
            },
            {
              "id": "2",
              "name": "createdAt",
              "value": "={{ $now.toISO() }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "b010",
      "name": "Transcreve Imagem",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 1.5,
      "position": [
        2860,
        300
      ],
      "parameters": {
        "resource": "image",
        "operation": "analyze",
        "modelId": {
          "__rl": true,
          "value": "gpt-4o-mini",
          "mode": "list",
          "cachedResultName": "GPT-4O-MINI"
        },
        "text": "O cliente enviou esta imagem em um grupo de suporte de TI. Descreva o que est\u00e1 nela em detalhes \u2014 pode ser print de erro, foto de tela do sistema, mensagem de erro, captura de configura\u00e7\u00e3o, foto de equipamento. Seja espec\u00edfico sobre textos, c\u00f3digos de erro e elementos visuais.",
        "imageUrls": "={{ $json.details.file.publicUrl }}",
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "b011",
      "name": "Grava Imagem",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        3080,
        300
      ],
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "1",
              "name": "text",
              "value": "=[Imagem enviada pelo cliente]: {{ $json.content }}",
              "type": "string"
            },
            {
              "id": "2",
              "name": "createdAt",
              "value": "={{ $now.toISO() }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "b012",
      "name": "Merge M\u00eddia",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.2,
      "position": [
        3520,
        60
      ],
      "parameters": {
        "numberInputs": 3
      }
    },
    {
      "id": "b013",
      "name": "Concatena Mensagens",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3740,
        60
      ],
      "parameters": {
        "jsCode": "const dbc = $('Code: Debounce Check').item.json;\nconst items = $input.all();\nconst sorted = [...items].sort((a,b)=>{\n  const ta = new Date(a.json.createdAt||0).getTime();\n  const tb = new Date(b.json.createdAt||0).getTime();\n  return ta - tb;\n});\nconst text = sorted.map(i => i.json.text).filter(Boolean).join('\\n').trim();\n\n// Mant\u00e9m mensagens originais para Detecta Keywords (busca por texto literal)\nreturn [{\n  json: {\n    session_id:        dbc.session_id,\n    zapi_group_id:     dbc.zapi_group_id,\n    nome:              dbc.nome,\n    ai_ativo:          dbc.ai_ativo,\n    last_processed_at: dbc.last_processed_at,\n    mensagens:         dbc.mensagens,\n    text_concatenado:  text,\n    msgs_count:        sorted.length\n  }\n}];"
      }
    },
    {
      "id": "b020",
      "name": "Set Campos B\u00e1sicos",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        5060,
        540
      ],
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "1",
              "name": "sessionId",
              "value": "={{ $json.session_id }}",
              "type": "string"
            },
            {
              "id": "2",
              "name": "zapi_group_id",
              "value": "={{ $json.zapi_group_id }}",
              "type": "string"
            },
            {
              "id": "3",
              "name": "nome",
              "value": "={{ $json.nome }}",
              "type": "string"
            },
            {
              "id": "4",
              "name": "chatInput",
              "value": "={{ $(\"Concatena Mensagens\").first().json.text_concatenado }}",
              "type": "string"
            },
            {
              "id": "5",
              "name": "dataHoraAtual",
              "value": "={{ $now.setZone('America/Sao_Paulo').setLocale('pt-BR').toFormat(\"cccc, dd'/'MM'/'yyyy HH:mm\") }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "b021",
      "name": "AI Agent Bia",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 1.7,
      "position": [
        5280,
        540
      ],
      "parameters": {
        "promptType": "define",
        "text": "={{ $(\"Set Campos B\u00e1sicos\").item.json.chatInput }}",
        "options": {
          "systemMessage": "Voc\u00ea \u00e9 Bia, assistente virtual de suporte t\u00e9cnico da ag\u00eancia CRC Automa\u00e7\u00e3o (Grupo OPTA).\nAtende clientes em grupos do WhatsApp tirando d\u00favidas sobre sistemas, automa\u00e7\u00f5es e ferramentas.\n\nAgora: {{ $('Set Campos B\u00e1sicos').item.json.dataHoraAtual }}\nGrupo: {{ $('Set Campos B\u00e1sicos').item.json.nome }}\n\n========================================\nPERSONALIDADE\n========================================\n- Atendente simp\u00e1tica e t\u00e9cnica, fala como gente\n- Adapte o tamanho da resposta ao tipo de pergunta:\n  * Sauda\u00e7\u00f5es, confirma\u00e7\u00f5es simples, \"ok\": 1-2 frases\n  * Esclarecimentos r\u00e1pidos: 2-3 frases\n  * **Procedimentos / passo-a-passo (como criar X, configurar Y, ativar Z): SEJA DETALHADO**\n    \u2014 descreva o sub-menu exato, o campo exato e o bot\u00e3o exato em cada passo\n    \u2014 n\u00e3o resuma, n\u00e3o pule etapas, mencione abas/se\u00e7\u00f5es espec\u00edficas se houver\n    \u2014 exemplo bom: \"1. Menu lateral \u2192 Automa\u00e7\u00e3o \u2192 submenu 'Agentes IA'\"\n    \u2014 exemplo ruim: \"1. Acesse o menu de Automa\u00e7\u00e3o\"\n- Se a resposta ficar longa, QUEBRE em mensagens separadas usando \"---\"\n- NUNCA fa\u00e7a 2 perguntas na mesma mensagem\n- Emojis com modera\u00e7\u00e3o (m\u00e1ximo 1-2 por mensagem)\n- Nunca repita informa\u00e7\u00e3o que o cliente j\u00e1 deu\n\n========================================\nSUA FUN\u00c7\u00c3O\n========================================\n- Receber d\u00favidas t\u00e9cnicas em grupos de suporte de TI\n- Coletar informa\u00e7\u00f5es suficientes pra preencher o chamado: o que aconteceu, em qual sistema, h\u00e1 quanto tempo, mensagem de erro\n- Tentar resolver d\u00favidas simples (procedimentos, configura\u00e7\u00f5es b\u00e1sicas, FAQs)\n- Quando N\u00c3O souber resolver: avisar que vai transferir para o time humano e adicionar [ESCALAR] no FINAL da resposta\n\n========================================\nQUANDO O CLIENTE FINALIZA (adicionar [CONCLUIR] no final)\n========================================\nAp\u00f3s resolver uma d\u00favida, SEMPRE pergunte se precisa de mais alguma coisa.\nSe o cliente despedir, agradecer ou dizer que era s\u00f3 isso (ex: \"obrigado\", \"valeu\",\n\"era s\u00f3 isso\", \"tudo certo\", \"n\u00e3o preciso de mais nada\", \"fechou\", \"blz\"),\nagrade\u00e7a e adicione [CONCLUIR] no FINAL da sua \u00faltima resposta.\n\nExemplo: \"Foi um prazer ajudar! Estamos por aqui sempre que precisar. \ud83d\ude0a\" [CONCLUIR]\n\nAp\u00f3s [CONCLUIR], o sistema fecha o chamado automaticamente.\nN\u00e3o use [CONCLUIR] se o cliente ainda tiver d\u00favidas em aberto.\n\n========================================\nQUANDO ESCALAR (adicionar [ESCALAR] no final)\n========================================\n- Cliente pede pra falar com humano/atendente/t\u00e9cnico\n- Problema requer acesso a sistemas internos que voc\u00ea n\u00e3o tem\n- Bug complexo que precisa investiga\u00e7\u00e3o\n- Cliente irritado ou insatisfeito\n- Ap\u00f3s coletar informa\u00e7\u00f5es suficientes pra abrir chamado\n- Qualquer assunto que voc\u00ea n\u00e3o consegue resolver com confian\u00e7a\n\nMensagem ao escalar: \"Vou te transferir pra um t\u00e9cnico que pode te ajudar com isso. J\u00e1 anotei tudo aqui.\" [ESCALAR]\n\n========================================\nREGRA DE OURO\n========================================\nNUNCA invente procedimentos, comandos, IDs, URLs ou configura\u00e7\u00f5es espec\u00edficas dos sistemas do cliente. Se n\u00e3o tiver certeza, escale.\n\n========================================\n\ud83d\udea8 REGRA OBRIGAT\u00d3RIA \u2014 SEMPRE USE A TOOL \"MCP Doc WTS\"\n========================================\nANTES de responder QUALQUER pergunta sobre como usar a plataforma, voc\u00ea DEVE OBRIGATORIAMENTE:\n\n1. CHAMAR a tool \"MCP Doc WTS\" passando a pergunta do cliente\n2. LER o resultado retornado\n3. S\u00f3 ent\u00e3o gerar a resposta com base NO QUE A TOOL RETORNOU\n\nUse a tool em TODAS estas situa\u00e7\u00f5es (n\u00e3o exaustivo):\n- \"como criar/configurar/excluir/editar X\" (qualquer recurso da plataforma)\n- \"como funciona X\"\n- \"onde encontro X\"\n- \"qual menu pra X\"\n- \"como integro X\"\n- Qualquer coisa que envolva: chatbot, agente, etiqueta, card, sess\u00e3o, contato, painel, equipe, departamento, canal, automa\u00e7\u00e3o, webhook, integra\u00e7\u00e3o, custom field, fluxo, mensagem, configura\u00e7\u00e3o\n\n\u274c PROIBIDO: responder sobre a plataforma SEM antes consultar a tool. Sua mem\u00f3ria de treinamento sobre a plataforma \u00e9 INSUFICIENTE \u2014 voc\u00ea inventa nomes de menus que n\u00e3o existem.\n\n\u2705 CORRETO: chamar tool \u2192 ler resposta \u2192 responder com info real.\n\nSe voc\u00ea responder sem consultar a tool, sua resposta vai estar ERRADA porque a doc da plataforma evolui constantemente.\n\nQuando se referir \u00e0 plataforma na conversa, fale \"nossa plataforma\" / \"o sistema\" \u2014 universalize, sem citar marca (WTS, flw.chat).\n\n========================================\nFORMATA\u00c7\u00c3O WHATSAPP (CR\u00cdTICO)\n========================================\nNUNCA use ** (asterisco duplo) \u2014 isso \u00e9 markdown e n\u00e3o funciona no WhatsApp.\nUse *asterisco simples* para negrito.\nERRADO: **importante**, **passo 1**\nCERTO: *importante*, *passo 1*\n\n========================================\nPREFIX *BIA* \u2014 N\u00c3O INCLUA NA RESPOSTA\n========================================\nNUNCA comece sua resposta com \"*BIA*\", asterisco ou qualquer marca de identifica\u00e7\u00e3o.\nO sistema adiciona automaticamente \"*BIA* \" no in\u00edcio de cada mensagem antes de enviar.\nVoc\u00ea s\u00f3 escreve o conte\u00fado natural \u2014 sem prefixos.\n\n========================================\nPROIBIDO: LINKS / URLS\n========================================\nNUNCA envie links, URLs, \"clique aqui\", \"veja em [link]\", \"acesse https://...\", nem markdown de link tipo [texto](url).\nMesmo quando consultar a doc via tool, N\u00c3O mande o link da doc \u2014 apenas explique com palavras o passo-a-passo.\nSe precisar referenciar uma p\u00e1gina, diga apenas o caminho dentro da plataforma (ex: \"Menu CRM \u2192 Contatos\"), sem URL.\n\n========================================\nIMAGENS E \u00c1UDIOS\n========================================\n- Voc\u00ea consegue ver imagens (prints de erro) e ouvir \u00e1udios\n- \u00c1udios s\u00e3o transcritos automaticamente \u2014 responda ao conte\u00fado normalmente\n- Se cliente mandar print de erro, identifique o erro e oriente"
        }
      }
    },
    {
      "id": "b022",
      "name": "GPT-4o-mini Bia",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1,
      "position": [
        5170,
        760
      ],
      "parameters": {
        "model": "gpt-4o-mini",
        "options": {
          "temperature": 0.3
        }
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "b023",
      "name": "Mem\u00f3ria Redis",
      "type": "@n8n/n8n-nodes-langchain.memoryRedisChat",
      "typeVersion": 1.3,
      "position": [
        5390,
        760
      ],
      "parameters": {
        "sessionIdType": "customKey",
        "sessionKey": "=bia_{{ $(\"Set Campos B\u00e1sicos\").item.json.sessionId }}",
        "contextWindowLength": 6,
        "sessionTTL": 86400
      },
      "credentials": {
        "redis": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "b024",
      "name": "MCP Doc WTS",
      "type": "@n8n/n8n-nodes-langchain.mcpClientTool",
      "typeVersion": 1.2,
      "position": [
        4290,
        280
      ],
      "parameters": {
        "endpointUrl": "https://docs.flw.chat/guide/~gitbook/mcp",
        "options": {}
      }
    },
    {
      "id": "b030",
      "name": "Code Parser",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        5500,
        540
      ],
      "parameters": {
        "jsCode": "let raw = ($input.first().json.output || '').trim();\nlet escalar = false;\nlet concluir = false;\nif (raw.includes('[ESCALAR]')) {\n  escalar = true;\n  raw = raw.replace(/\\[ESCALAR\\]/g, '').trim();\n}\nif (raw.includes('[CONCLUIR]')) {\n  concluir = true;\n  raw = raw.replace(/\\[CONCLUIR\\]/g, '').trim();\n}\n// Markdown WhatsApp: ** -> *\nraw = raw.replace(/\\*\\*([^*]+?)\\*\\*/g, '*$1*');\n// PROIBIDO: links/URLs \u2014 strip de markdown link [texto](url) \u2192 texto, remove URLs cruas\nraw = raw.replace(/\\[([^\\]]+)\\]\\(https?:\\/\\/[^)]+\\)/g, '$1');\nraw = raw.replace(/https?:\\/\\/[^\\s)]+/g, '');\n// Limpa pontua\u00e7\u00e3o solta deixada pela remo\u00e7\u00e3o (\"texto . \", \" : \")\nraw = raw.replace(/\\s+([.,:;!?])/g, '$1').replace(/\\n{3,}/g, '\\n\\n').trim();\n\nconst MAX_CHARS = 600;\nconst MAX_MSGS = 15;\nconst blocks = raw.split(/\\n?---\\n?/).map(b => b.trim()).filter(Boolean);\nconst out = [];\nfor (const block of blocks) {\n  const lines = block.split('\\n');\n  let current = '';\n  for (const line of lines) {\n    const l = line.trim();\n    if (l === '') { if (current) { out.push(current); current = ''; } continue; }\n    const cand = current ? current + '\\n' + l : l;\n    if (cand.length <= MAX_CHARS) current = cand;\n    else { if (current) out.push(current); current = l.substring(0, MAX_CHARS); }\n  }\n  if (current) out.push(current);\n}\n\n// Prefix vis\u00edvel *BIA* em linha pr\u00f3pria (cliente v\u00ea negrito + quebra) + suffix invis\u00edvel \u2063 (zero-width, defense in depth)\nconst messages = out.slice(0, MAX_MSGS).map(t => ({ texto: '*BIA*\\n\\n' + t + '\\u2063' }));\nreturn [{ json: { messages, escalar, concluir, total: messages.length } }];"
      }
    },
    {
      "id": "b031",
      "name": "SplitOut Segmentos",
      "type": "n8n-nodes-base.splitOut",
      "typeVersion": 1,
      "position": [
        5720,
        540
      ],
      "parameters": {
        "fieldToSplitOut": "messages",
        "options": {}
      }
    },
    {
      "id": "b032",
      "name": "Loop Mensagens",
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        5940,
        540
      ],
      "parameters": {
        "options": {}
      }
    },
    {
      "id": "b033",
      "name": "Wait Din\u00e2mico",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        6160,
        460
      ],
      "parameters": {
        "amount": 1.5
      }
    },
    {
      "id": "b034",
      "name": "Enviar Z-API",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        6380,
        460
      ],
      "parameters": {
        "method": "POST",
        "url": "https://api.z-api.io/instances/3F1CC7F5E61EA11E0EE16E59E5E6857E/token/55E9104D87E0587F9C1B70BD/send-text",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Client-Token",
              "value": "F6a21ad5808724e14822ed80677a5f39eS"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={ \"phone\": \"{{ $(\"Set Campos B\u00e1sicos\").item.json.zapi_group_id }}\", \"message\": {{ JSON.stringify($json.texto) }} }",
        "options": {}
      }
    },
    {
      "id": "b048",
      "name": "Lock Escala\u00e7\u00e3o",
      "type": "n8n-nodes-base.redis",
      "typeVersion": 1,
      "position": [
        4400,
        580
      ],
      "parameters": {
        "operation": "incr",
        "key": "=bia_escalated_{{ $('Set Campos B\u00e1sicos').item.json.sessionId }}",
        "expire": true,
        "ttl": 3600
      },
      "credentials": {
        "redis": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "b049",
      "name": "IF Primeira Escala\u00e7\u00e3o?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        4620,
        580
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "e1",
              "leftValue": "={{ parseInt($json.value ?? $json.result ?? $json.propertyName ?? Object.values($json)[0] ?? '0') }}",
              "rightValue": 1,
              "operator": {
                "type": "number",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      }
    },
    {
      "id": "b045",
      "name": "IF Concluir?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        4620,
        720
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "c1",
              "leftValue": "={{ $(\"Code Parser\").first().json.concluir }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      }
    },
    {
      "id": "b046",
      "name": "Posta #fim (concluir)",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        4840,
        800
      ],
      "parameters": {
        "method": "POST",
        "url": "=https://api.wts.chat/chat/v1/session/{{ $(\"Set Campos B\u00e1sicos\").item.json.sessionId }}/note",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "accept",
              "value": "application/json"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "{\"text\": \"#fim\"}",
        "options": {}
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "b047",
      "name": "Fecha Chamado (AI)",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        5060,
        800
      ],
      "parameters": {
        "method": "POST",
        "url": "https://vgawovbxbvtbyrcwdrto.supabase.co/rest/v1/rpc/fechar_chamado",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "<redacted-credential>"
            },
            {
              "name": "Authorization",
              "value": "<redacted-credential>"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={ \"p_session_id\": \"{{ $(\"Set Campos B\u00e1sicos\").item.json.sessionId }}\", \"p_motivo\": \"ai_concluir\" }",
        "options": {}
      }
    },
    {
      "id": "b040",
      "name": "IF Escalar",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        6160,
        720
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "e",
              "leftValue": "={{ $(\"Code Parser\").first().json.escalar }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      }
    },
    {
      "id": "b041",
      "name": "Escalona Z-API (Chamados I.A)",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        6380,
        660
      ],
      "parameters": {
        "method": "POST",
        "url": "https://api.z-api.io/instances/3F1CC7F5E61EA11E0EE16E59E5E6857E/token/55E9104D87E0587F9C1B70BD/send-text",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Client-Token",
              "value": "F6a21ad5808724e14822ed80677a5f39eS"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={ \"phone\": \"120363425640655013-group\", \"message\": {{ JSON.stringify('\ud83d\udd14 *Chamado escalado*\\n\\nGrupo: ' + $('Set Campos B\u00e1sicos').item.json.nome + '\\n\\n\u00daltima mensagem do cliente:\\n' + $('Concatena Mensagens').first().json.text_concatenado) }} }",
        "options": {}
      }
    },
    {
      "id": "b042",
      "name": "Posta Nota #humano",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        6380,
        780
      ],
      "parameters": {
        "method": "POST",
        "url": "=https://api.wts.chat/chat/v1/session/{{ $(\"Set Campos B\u00e1sicos\").item.json.sessionId }}/note",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "accept",
              "value": "application/json"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "{\"text\": \"#humano\"}",
        "options": {}
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Trigger 30s": {
      "main": [
        [
          {
            "node": "Busca Grupos",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Busca Grupos": {
      "main": [
        [
          {
            "node": "Extrai Grupos",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extrai Grupos": {
      "main": [
        [
          {
            "node": "Busca Msgs WTS",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Busca Msgs WTS": {
      "main": [
        [
          {
            "node": "IF Tem Msgs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF Tem Msgs": {
      "main": [
        [
          {
            "node": "Code: Debounce Check",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Code: Debounce Check": {
      "main": [
        [
          {
            "node": "IF Debounce OK",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF Debounce OK": {
      "main": [
        [
          {
            "node": "Atualiza Processado",
            "type": "main",
            "index": 0
          },
          {
            "node": "SplitOut Dividir Mensagens",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Atualiza Processado": {
      "main": [
        []
      ]
    },
    "Code: Detecta Keywords": {
      "main": [
        [
          {
            "node": "IF hasInicio",
            "type": "main",
            "index": 0
          },
          {
            "node": "IF hasFim",
            "type": "main",
            "index": 0
          },
          {
            "node": "Busca \u00daltima Nota",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF hasInicio": {
      "main": [
        [
          {
            "node": "Posta Nota #inicio",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Posta Nota #inicio": {
      "main": [
        [
          {
            "node": "Cria Chamado",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF hasFim": {
      "main": [
        [
          {
            "node": "Posta Nota #fim",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Posta Nota #fim": {
      "main": [
        [
          {
            "node": "Fecha Chamado",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Busca \u00daltima Nota": {
      "main": [
        [
          {
            "node": "Code: Extrai Estado",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code: Extrai Estado": {
      "main": [
        [
          {
            "node": "IF Em Atendimento",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF Em Atendimento": {
      "main": [
        [
          {
            "node": "IF AI Ativa",
            "type": "main",
            "index": 0
          },
          {
            "node": "IF Novo Atendimento",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "IF Novo Atendimento": {
      "main": [
        [
          {
            "node": "Posta #inicio Novo Atend",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Posta #inicio Novo Atend": {
      "main": [
        []
      ]
    },
    "IF AI Ativa": {
      "main": [
        [
          {
            "node": "Set Campos B\u00e1sicos",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "SplitOut Dividir Mensagens": {
      "main": [
        [
          {
            "node": "IF Filtra Inbound",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF Filtra Inbound": {
      "main": [
        [
          {
            "node": "Filtra TEXT",
            "type": "main",
            "index": 0
          },
          {
            "node": "Filtra FILE",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Set Campos B\u00e1sicos": {
      "main": [
        [
          {
            "node": "Verifica Rate Limit",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Verifica Rate Limit": {
      "main": [
        [
          {
            "node": "IF Rate OK?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF Rate OK?": {
      "main": [
        [
          {
            "node": "AI Agent Bia",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Filtra TEXT": {
      "main": [
        [
          {
            "node": "Grava TEXT",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Grava TEXT": {
      "main": [
        [
          {
            "node": "Merge M\u00eddia",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filtra FILE": {
      "main": [
        [
          {
            "node": "Switch M\u00eddia",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch M\u00eddia": {
      "main": [
        [
          {
            "node": "Baixa \u00c1udio",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Transcreve Imagem",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Baixa \u00c1udio": {
      "main": [
        [
          {
            "node": "Transcreve \u00c1udio",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Transcreve \u00c1udio": {
      "main": [
        [
          {
            "node": "Grava \u00c1udio",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Grava \u00c1udio": {
      "main": [
        [
          {
            "node": "Merge M\u00eddia",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Transcreve Imagem": {
      "main": [
        [
          {
            "node": "Grava Imagem",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Grava Imagem": {
      "main": [
        [
          {
            "node": "Merge M\u00eddia",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Merge M\u00eddia": {
      "main": [
        [
          {
            "node": "Concatena Mensagens",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Concatena Mensagens": {
      "main": [
        [
          {
            "node": "Code: Detecta Keywords",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent Bia": {
      "main": [
        [
          {
            "node": "Code Parser",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GPT-4o-mini Bia": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent Bia",
            "type": "ai_languageModel",
            

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

OPTA | AGENTE DE IA (PRINCIPAL). Uses httpRequest, redis, openAi, agent. Scheduled trigger; 54 nodes.

Source: https://github.com/PEDROMORRAESS/genionos-genions-sofia/blob/6e619f9488fb26cf20f983b1bb04502e8cf50f62/vbot-invio/crc-automacao/opta-agente-de-ia-principal.json — 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

My workflow 7. Uses openAi, redis, httpRequest, agent. Webhook trigger; 77 nodes.

OpenAI, Redis, HTTP Request +8
AI & RAG

My workflow 7. Uses openAi, redis, httpRequest, agent. Webhook trigger; 77 nodes.

OpenAI, Redis, HTTP Request +8
AI & RAG

Transform your salon/service business with this streamlined WhatsApp automation system featuring Claude integration, zero-setup database management, and intelligent conversation handling. Claude MCP I

WhatsApp Trigger, WhatsApp, Redis +11
AI & RAG

Transform your salon/service business with this streamlined Telegram automation system featuring Claude integration, zero-setup database management, and intelligent conversation handling. Claude MCP I

Redis, Agent Tool, Google Calendar +10
AI & RAG

Agent: IPTV (instance_e2165d22_1762376395079). Uses openAi, redis, supabase, httpRequest. Webhook trigger; 56 nodes.

OpenAI, Redis, Supabase +7