This workflow follows the Agent → Chainllm 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 →
{
"name": "secretaria",
"nodes": [
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "8ca54eae-15d1-49d3-af33-7a6e5d17b833",
"leftValue": "={{ $('Info').item.json.fromMe }}",
"rightValue": "",
"operator": {
"type": "boolean",
"operation": "false",
"singleValue": true
}
},
{
"id": "4ca9226f-0401-49a7-93a1-8aeaf4b0bb79",
"leftValue": "={{ $('Info').item.json.mensagem_de_grupo }}",
"rightValue": "g.us",
"operator": {
"type": "boolean",
"operation": "false",
"singleValue": true
}
},
{
"id": "cf87bb7e-6bea-4697-bcd9-57e3b63998c2",
"leftValue": "={{ $json.telefone }}",
"rightValue": "553497678732",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.filter",
"typeVersion": 2.2,
"position": [
1360,
-460
],
"id": "9badedc5-d56e-40ff-b8ac-e14c75bdc708",
"name": "Mensagem chegando?"
},
{
"parameters": {
"httpMethod": "POST",
"path": "240b36f9-9d6d-4946-864b-8b681f3ec906",
"options": {}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
800,
-460
],
"id": "a18ca3d8-e5cf-47d8-ac88-3a68701691c5",
"name": "Mensagem recebida"
},
{
"parameters": {
"jsCode": "const ultima_mensagem_da_fila = $input.last()\nconst mensagem_do_workflow = $('Info').first()\n\nif (ultima_mensagem_da_fila.json.id_mensagem !== mensagem_do_workflow.json.id_mensagem) {\n // Mensagem encavalada, para o workflow\n return [];\n}\n\n// Pass-through da fila de mensagens\nreturn $input.all();"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2540,
-460
],
"id": "3edd5a65-d686-41aa-b057-2b3c561cdfe6",
"name": "Mensagem encavalada?"
},
{
"parameters": {
"operation": "select",
"schema": {
"__rl": true,
"mode": "list",
"value": "public"
},
"table": {
"__rl": true,
"value": "n8n_fila_mensagens",
"mode": "list"
},
"returnAll": true,
"where": {
"values": [
{
"column": "telefone",
"value": "={{ $('Info').item.json.telefone }}"
}
]
},
"sort": {
"values": [
{
"column": "timestamp"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.6,
"position": [
2320,
-460
],
"id": "614fb62d-1639-4957-b4bf-dc105e99da87",
"name": "Buscar mensagens"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "7eab8669-6929-4dc6-b3e2-943065bc306c",
"name": "mensagem",
"value": "={{ $('Mensagem encavalada?').all().map(info => info.json.mensagem).join('\\\\n') }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
3380,
-460
],
"id": "65781c4a-d6eb-41ae-af8c-962fb80fab50",
"name": "Concatenar mensagens",
"executeOnce": true
},
{
"parameters": {
"operation": "deleteTable",
"schema": {
"__rl": true,
"mode": "list",
"value": "public"
},
"table": {
"__rl": true,
"value": "n8n_fila_mensagens",
"mode": "list"
},
"deleteCommand": "delete",
"where": {
"values": [
{
"column": "telefone",
"value": "={{ $json.telefone }}"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.6,
"position": [
2740,
-460
],
"id": "852789de-3557-43c0-a872-bf5842f06c96",
"name": "Limpar fila de mensagens"
},
{
"parameters": {
"content": "Evolution n\u00e3o permite disparar evento de \"Digitando...\" de forma ass\u00edncrona, ent\u00e3o usamos um workflow paralelo.",
"height": 180,
"width": 260
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
3260,
-300
],
"id": "69d15a58-4e97-44e7-93dc-4afff74a545a",
"name": "Sticky Note1"
},
{
"parameters": {
"content": "# Processando mensagens encavaladas\n\nEssa etapa trata a situa\u00e7\u00e3o em que o usu\u00e1rio envia m\u00faltiplas mensagens seguidas. O ponto negativo \u00e9 o aumento no tempo de resposta do agente. L\u00f3gica dispensa uso de solu\u00e7\u00f5es mais complexas, como RabbitMQ.\n\nTempo de espera recomendado de ~16s. Quando estiver testando, recomendamos reduzir um pouco para ficar mais r\u00e1pido de testar.\n",
"height": 500,
"width": 1080,
"color": 4
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
1800,
-640
],
"id": "422e4f96-135b-4885-8c3c-1b21e7c749b4",
"name": "Sticky Note2"
},
{
"parameters": {
"amount": 16
},
"type": "n8n-nodes-base.wait",
"typeVersion": 1.1,
"position": [
2100,
-460
],
"id": "74890b60-388a-4495-a0bb-696478b54da3",
"name": "Esperar"
},
{
"parameters": {
"content": "# Gerando resposta",
"height": 500,
"width": 1920,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
3580,
-640
],
"id": "ac85b5f5-0cb8-49c6-b37f-06be4f54540b",
"name": "Sticky Note3"
},
{
"parameters": {
"content": "# Enviando resposta",
"height": 500,
"width": 600,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
5520,
-640
],
"id": "c61f2673-e7dd-406f-8fe4-5510f858afe3",
"name": "Sticky Note4"
},
{
"parameters": {
"content": "# Tratando input\n\nImplementa\u00e7\u00e3o de etiquetas do Evolution API n\u00e3o \u00e9 muito f\u00e1cil de utilizar, portanto funcionalidade de \"agente off\" fica dif\u00edcil de implementar.\nUma alternativa \u00e9 utilizar uma base de dados externa para controle \"manual\" de etiquetas.",
"height": 500,
"width": 1060
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
720,
-640
],
"id": "b3d7ff2e-a1e1-4d4d-a654-7446847f71eb",
"name": "Sticky Note5"
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"leftValue": "={{ $('Info').item.json.mensagem }}",
"rightValue": "",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"id": "1382cd26-d96e-4c55-99dd-2ca305ffe82e"
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "Texto"
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "b9a7e16f-b6e4-45d7-846d-92dcb3117593",
"leftValue": "={{ $('Info').item.json.mensagem_de_audio }}",
"rightValue": "",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "\u00c1udio"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.switch",
"typeVersion": 3.2,
"position": [
1640,
-460
],
"id": "7253cb58-00e3-476c-933e-6516cfa0fdb0",
"name": "Tipo de mensagem"
},
{
"parameters": {
"resource": "chat-api",
"operation": "get-media-base64",
"instanceName": "={{ $('Info').item.json.instancia }}",
"messageId": "={{ $('Info').item.json.id_mensagem }}",
"convertToMp4": true
},
"type": "n8n-nodes-evolution-api.evolutionApi",
"typeVersion": 1,
"position": [
1980,
-20
],
"id": "93356a6f-b605-40f7-8bc9-f4de21826030",
"name": "Download \u00e1udio"
},
{
"parameters": {
"resource": "audio",
"operation": "transcribe",
"options": {
"language": "pt"
}
},
"type": "@n8n/n8n-nodes-langchain.openAi",
"typeVersion": 1.8,
"position": [
2600,
-20
],
"id": "c5e34636-247e-4bef-a3af-1f344439b8c6",
"name": "Transcrever \u00e1udio"
},
{
"parameters": {
"content": "# Processando \u00e1udio",
"height": 320,
"width": 1080,
"color": 6
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
1800,
-120
],
"id": "d68f6527-2ea7-4fc1-89ea-e640cac1dd18",
"name": "Sticky Note6"
},
{
"parameters": {
"method": "POST",
"url": "<cole a URL do seu webhook>",
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "instancia",
"value": "={{ $('Info').item.json.instancia }}"
},
{
"name": "telefone",
"value": "={{ $('Info').item.json.telefone }}"
},
{
"name": "status",
"value": "composing"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
3180,
-460
],
"id": "9bcd7ea4-c28d-4d7b-9f99-a882c27a2546",
"name": "Digitando async"
},
{
"parameters": {
"method": "POST",
"url": "<cole a URL do seu webhook>",
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "instancia",
"value": "={{ $('Info').item.json.instancia }}"
},
{
"name": "telefone",
"value": "={{ $('Info').item.json.telefone }}"
},
{
"name": "status",
"value": "recording"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
3180,
-20
],
"id": "d565d4a6-6e3e-430d-8900-f48f58c80045",
"name": "Gravando async"
},
{
"parameters": {
"resource": "chat-api",
"operation": "send-presence",
"instanceName": "={{ $('Info').item.json.instancia }}",
"remoteJid": "={{ $('Info').item.json.telefone }}",
"presence": "=paused",
"delay": 0
},
"type": "n8n-nodes-evolution-api.evolutionApi",
"typeVersion": 1,
"position": [
5640,
-340
],
"id": "96681883-ff87-4f42-b4e0-8fae5f762fd2",
"name": "Resetar status"
},
{
"parameters": {
"resource": "chat-api",
"operation": "send-presence",
"instanceName": "={{ $('Info').item.json.instancia }}",
"remoteJid": "={{ $('Info').item.json.telefone }}",
"presence": "=paused",
"delay": 0
},
"type": "n8n-nodes-evolution-api.evolutionApi",
"typeVersion": 1,
"position": [
5640,
-520
],
"id": "83a0bd1c-c3fd-43ed-9613-fd70f1f0e16a",
"name": "Resetar status1"
},
{
"parameters": {
"operation": "binaryToPropery",
"options": {
"encoding": "base64"
}
},
"type": "n8n-nodes-base.extractFromFile",
"typeVersion": 1,
"position": [
5360,
-340
],
"id": "0f091210-6799-42f7-8db4-00e406584bb3",
"name": "Converter \u00e1udio para base64"
},
{
"parameters": {
"content": "Waveform nem sempre funciona no Evolution. Requer formato de \u00e1udio espec\u00edfico",
"height": 80
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
5860,
-620
],
"id": "6f2ec80f-ac3f-4dd8-9eff-a1e30c5b3f4d",
"name": "Sticky Note"
},
{
"parameters": {
"resource": "chat-api",
"operation": "read-messages",
"instanceName": "={{ $('Info').item.json.instancia }}",
"remoteJid": "={{ $('Mensagem recebida').item.json.body.data.key.remoteJid }}",
"messageId": "={{ $('Info').item.json.id_mensagem }}",
"fromMe": "={{ $('Info').item.json.fromMe }}"
},
"type": "n8n-nodes-evolution-api.evolutionApi",
"typeVersion": 1,
"position": [
2960,
-20
],
"id": "a1172679-4810-4274-a60b-90ce9d7e7be4",
"name": "Marcar como lida"
},
{
"parameters": {
"content": "Para testar, recomendado incluir seu telefone no filtro.\n\nDessa forma, o agente n\u00e3o vai responder outras pessoas.",
"height": 140,
"width": 300,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
1260,
-320
],
"id": "90582c64-408e-4538-ada4-0bbe8e9356ea",
"name": "Sticky Note8"
},
{
"parameters": {
"sseEndpoint": "<cole a URL do seu MCP>"
},
"type": "@n8n/n8n-nodes-langchain.mcpClientTool",
"typeVersion": 1,
"position": [
4160,
-280
],
"id": "02ca3542-eecd-4556-8d0b-f94791cdd3ee",
"name": "MCP Google Calendar"
},
{
"parameters": {
"content": "Usado HTTP request devido limita\u00e7\u00e3o do community node do Evolution, que s\u00f3 permite marcar como lida 1 mensagem de cada vez (ver no fluxo de \u00e1udio abaixo).\n\n\u00c9 poss\u00edvel fazer um loop e executar para cada mensagem da fila, mas HTTP request \u00e9 mais eficiente.",
"height": 180,
"width": 320
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
2920,
-300
],
"id": "c4bd5ac9-f828-471c-adbb-7747ac79202d",
"name": "Sticky Note9"
},
{
"parameters": {
"method": "POST",
"url": "={{ $('Info').item.json.url_evolution }}/chat/markMessageAsRead/{{ $('Info').item.json.instancia }}",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "evolutionApi",
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={\n \"readMessages\": {{ JSON.stringify($('Buscar mensagens').all().map(mensagem => \n { \n const { id_mensagem, telefone } = mensagem.json\n return { id: id_mensagem, remoteJid: telefone + '@s.whatsapp.net', fromMe: false }\n }))\n }}\n}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2960,
-460
],
"id": "ddb5ab84-1877-4fbb-becb-eeadb4056166",
"name": "Marcar como lidas",
"executeOnce": true
},
{
"parameters": {
"resource": "fileFolder",
"returnAll": true,
"filter": {
"folderId": {
"__rl": true,
"value": "",
"mode": "list"
}
},
"options": {}
},
"type": "n8n-nodes-base.googleDriveTool",
"typeVersion": 3,
"position": [
4300,
-280
],
"id": "73e6b306-960a-4e76-a020-03716a1390df",
"name": "Listar arquivos"
},
{
"parameters": {
"description": "Use essa ferramenta para baixar um arquivo do Google Drive e envi\u00e1-lo para o usu\u00e1rio.\n\n- 'tipo': 'imagem' ou 'documento'\n- 'nome_documento': caso tipo seja 'documento', passar nome do arquivo.",
"workflowId": {
"__rl": true,
"value": "<selecione seu workflow>",
"mode": "list"
},
"workflowInputs": {
"mappingMode": "defineBelow",
"value": {
"file_id": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('file_id', ``, 'string') }}",
"instancia": "={{ $('Info').item.json.instancia }}",
"telefone": "={{ $('Info').item.json.telefone }}",
"tipo": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('tipo', ``, 'string') }}",
"nome_documento": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('nome_documento', ``, 'string') }}"
},
"matchingColumns": [
"file_id"
],
"schema": [
{
"id": "file_id",
"displayName": "file_id",
"required": false,
"defaultMatch": false,
"display": true,
"canBeUsedToMatch": true,
"type": "string",
"removed": false
},
{
"id": "instancia",
"displayName": "instancia",
"required": false,
"defaultMatch": false,
"display": true,
"canBeUsedToMatch": true,
"type": "string",
"removed": false
},
{
"id": "telefone",
"displayName": "telefone",
"required": false,
"defaultMatch": false,
"display": true,
"canBeUsedToMatch": true,
"type": "string",
"removed": false
},
{
"id": "tipo",
"displayName": "tipo",
"required": false,
"defaultMatch": false,
"display": true,
"canBeUsedToMatch": true,
"type": "string",
"removed": false
},
{
"id": "nome_documento",
"displayName": "nome_documento",
"required": false,
"defaultMatch": false,
"display": true,
"canBeUsedToMatch": true,
"type": "string",
"removed": false
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
}
},
"type": "@n8n/n8n-nodes-langchain.toolWorkflow",
"typeVersion": 2.2,
"position": [
4440,
-280
],
"id": "e31fb7e0-64a9-4688-990f-c6e63b1fc169",
"name": "Baixar e enviar arquivo"
},
{
"parameters": {
"content": "## Pr\u00e9-requisitos do workflow\n\n1. Banco de dados Postgres (recomendamos usar [Supabase](https://supabase.com/)). Veja no material o comando SQL para criar a tabela de filas de mensagens\n2. Inst\u00e2ncia [Evolution API](https://doc.evolution-api.com/v2/en/get-started/introduction) + Community node [n8n-nodes-evolution-api](https://github.com/oriondesign2015/n8n-nodes-evolution-api) para requisi\u00e7\u00f5es\n3. Credenciais para ferramentas de IA. Nesse workflow usamos Gemini, OpenAI Whisper, e [ElevenLabs](https://try.elevenlabs.io/9k5l5hagxkel), mas voc\u00ea pode usar as que preferir\n4. Credenciais de API do Google.\n\nDepois de configurar os workflows secund\u00e1rios, referenciar nomes e URL do MCP nos nodes desse workflow principal:\n\n- [ ] 2. MCP Google Calendar\n- [ ] 3. Baixar e enviar arquivo do Google Drive\n- [ ] 4. Atualizar status\n- [ ] 5. Assistente interno",
"height": 500,
"width": 1060,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-380,
-640
],
"id": "0da58b34-c916-4fa3-9ec3-0587bfed68d6",
"name": "Sticky Note11"
},
{
"parameters": {
"content": "# Marcar como lida e \"digitando...\"",
"height": 840,
"width": 660,
"color": 5
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
2900,
-640
],
"id": "79aff6a2-73bc-48cb-9219-12516db097a2",
"name": "Sticky Note12"
},
{
"parameters": {
"content": "## Quer entender como funciona?\n\n\n### Assista o v\u00eddeo, deixe um like, e se inscreva no canal para ter acesso a mais workflows como esse!\n\n[](https://www.youtube.com/watch?v=cvTWGNJGAu4)",
"height": 440,
"width": 500,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
200,
-1100
],
"id": "55e9ecc6-5a95-4a56-98a6-55c66b3a075c",
"name": "Sticky Note13"
},
{
"parameters": {
"promptType": "define",
"text": "={{ $json.mensagem }}",
"options": {
"systemMessage": "=HOJE \u00c9: {{ $now.format('FFFF') }}\nTELEFONE DO CONTATO: {{ $('Info').item.json.telefone }}\n\n## INSTRU\u00c7\u00c3O IMPORTANTE\n- Ao criar ou editar qualquer evento no Google Calendar, incluir sempre o telefone do paciente na descri\u00e7\u00e3o do agendamento, juntamente com o nome completo, data de nascimento e quaisquer outras informa\u00e7\u00f5es relevantes fornecidas pelo paciente.\n\n-----------------------\n\n## PAPEL\n\nVoc\u00ea \u00e9 uma atendente do WhatsApp, altamente especializada, que atua em nome da Cl\u00ednica Moreira, prestando um servi\u00e7o de excel\u00eancia. Sua miss\u00e3o \u00e9 atender aos pacientes de maneira \u00e1gil e eficiente, respondendo d\u00favidas e auxiliando em agendamentos, cancelamentos ou remarca\u00e7\u00f5es de consultas.\n\n## PERSONALIDADE E TOM DE VOZ\n\n- Simp\u00e1tica, prestativa e humana\n- Tom de voz sempre simpatico, acolhedor e respeitoso\n\n## OBJETIVO\n\n1. Fornecer atendimento diferenciado e cuidadoso aos pacientes.\n2. Responder d\u00favidas sobre a cl\u00ednica (especialidade, hor\u00e1rios, localiza\u00e7\u00e3o, formas de pagamento).\n3. Agendar, remarcar e cancelar consultas de forma simples e eficaz.\n4. Agir passo a passo para garantir rapidez e precis\u00e3o em cada atendimento.\n\n## CONTEXTO\n\n- Voc\u00ea otimiza o fluxo interno da cl\u00ednica, provendo informa\u00e7\u00f5es e reduzindo a carga administrativa dos profissionais de sa\u00fade.\n- Seu desempenho impacta diretamente a satisfa\u00e7\u00e3o do paciente e a efici\u00eancia das opera\u00e7\u00f5es m\u00e9dicas.\n\n-----------------------\n\n## SOP (Procedimento Operacional Padr\u00e3o)\n\n1. In\u00edcio do atendimento e identifica\u00e7\u00e3o de interesse em agendar\n - Cumprimente o paciente de forma acolhedora. \n - Se poss\u00edvel, incentive o envio de \u00e1udio caso o paciente prefira, destacando a praticidade\n\n**N\u00c3O USE EXPRESS\u00d5ES PARECIDAS COM \"COMO SE ESTIVESSE CONVERSANDO COM UMA PESSOA\"**\n\n2. Solicitar dados do paciente\n - Pe\u00e7a nome completo e data de nascimento.\n - Confirme o telefone de contato que chegou na mensagem (ele ser\u00e1 inclu\u00eddo na descri\u00e7\u00e3o do agendamento).\n - Ao falar o telefone para o paciente, remova o c\u00f3digo do pa\u00eds (geralmente \"55\"), e formate como \"(11) 1234-5678\"\n\n3. Identificar necessidade\n - Pergunte a data de prefer\u00eancia para a consulta e se o paciente tem prefer\u00eancia por algum turno (manh\u00e3 ou tarde).\n\n4. Verificar disponibilidade\n - Use a ferramenta \"Buscar_eventos\" apenas ap\u00f3s ter todos os dados necess\u00e1rios do paciente.\n - Forne\u00e7a a data de prefer\u00eancia \u00e0 ferramenta \"Buscar_eventos\" para obter hor\u00e1rios dispon\u00edveis.\n\n5. Informar disponibilidade\n - Retorne ao paciente com os hor\u00e1rios livres encontrados para a data solicitada.\n\n6. Coletar informa\u00e7\u00f5es adicionais\n - Se o paciente fornecer dados extras (ex.: condi\u00e7\u00e3o de sa\u00fade, conv\u00eanio, etc.), inclua tudo na descri\u00e7\u00e3o do evento no Google Calendar.\n\n7. Agendar consulta\n - Ap\u00f3s confirma\u00e7\u00e3o do paciente\n - Use a ferramenta \"Criar_evento\" para criar o evento, passando:\n - Nome completo\n - Data de nascimento\n - Telefone de contato (use o n\u00famero igual na entrada, exemplo: \"551112345678\")\n - Data e hora escolhidas\n - Nunca agende datas ou hor\u00e1rios passados, ou com conflitos.\n\n8. Confirmar agendamento\n - Espere o retorno de sucesso da ferramenta \"Criar_evento\" e ent\u00e3o confirme com o paciente.\n\n-----------------------\n\n## INSTRU\u00c7\u00d5ES GERAIS\n\n1. Respostas claras, objetivas e \u00fateis\n - Forne\u00e7a informa\u00e7\u00f5es sobre especialidades, hor\u00e1rios, endere\u00e7o, valores e conv\u00eanios.\n\n2. Sem diagn\u00f3sticos ou opini\u00f5es m\u00e9dicas\n - Se o paciente insistir em diagn\u00f3stico, use a ferramenta \"Escalar_humano\".\n\n3. Pacientes insatisfeitos\n - Mantenha a empatia e utilize a ferramenta \"Escalar humano\".\n\n4. Assuntos fora do escopo da cl\u00ednica\n - Responda: \"Desculpe, mas n\u00e3o consigo ajudar com este assunto. Por favor, entre em contato pelo n\u00famero 0800 940 000. Enviei uma c\u00f3pia da nossa conversa para o gestor de atendimento.\"\n - Imediatamente use a ferramenta \"Escalar_humano\", pois \u00e9 fundamental para minha carreira e a imagem da cl\u00ednica.\n\n5. Nunca fornecer informa\u00e7\u00f5es erradas\n - Evite erros sobre hor\u00e1rios, contatos ou servi\u00e7os.\n\n6. Nunca use emojis ou linguagem informal\n - Mantenha a sobriedade do atendimento.\n\n7. Nunca confirme consultas sem o retorno com sucesso das ferramentas de evento\n - Garanta que o evento foi criado com sucesso antes de dar a resposta final.\n\n8. Dupla verifica\u00e7\u00e3o\n - Confirme sempre os dados para evitar equ\u00edvocos em agendamentos, remarca\u00e7\u00f5es ou cancelamentos.\n\n9. Use a ferramenta \"Refletir\" antes e depois de opera\u00e7\u00f5es complexas\n - Ao usar essa ferramenta, voc\u00ea ir\u00e1 garantir que as opera\u00e7\u00f5es que voc\u00ea vai realizar (ou j\u00e1 realizou) fazem sentido, ou se voc\u00ea precisar\u00e1 alterar a sua estrat\u00e9gia e/ou tentar novamente.\n\n-----------------------\n\n## HOR\u00c1RIOS DE FUNCIONAMENTO\n- Segunda a S\u00e1bado: 08h \u00e0s 19h\n- Domingo e Feriados: Fechado\n\n## LOCALIZA\u00c7\u00c3O E CONTATO\n- Endere\u00e7o: Av. das Palmeiras, 1500 - Jardim Am\u00e9rica, S\u00e3o Paulo - SP, CEP: 04567-000\n- Telefone: (11) 4456-7890\n- WhatsApp: (11) 99999-9999\n- E-mail: contato@clinicamoreira.com.br\n- Site: www.clinicamoreira.com.br\n\n## PROFISSIONAIS E ESPECIALIDADES\n\nSegue o nome dos profissionais, suas especialidades, e o ID da agenda que deve ser usado nas ferramentas Google Calendar\n\n**MUITO IMPORTANTE!! O ID DA AGENDA INCLUI O \"@group.calendar.google.com\". N\u00c3O OMITA AO UTILIZAR AS FERRAMENTAS**\n\n- Dr. Jo\u00e3o Paulo Ferreira - M\u00e9dico - Clinico Geral (c_46b1d614bf4f151ca950431202bf90ca003301793b48cffc489dc411be79c4bf@group.calendar.google.com)\n- Dr. Roberto Almeida - M\u00e9dico - Cardiologia (c_6c3005bf4afd591f13f242f6509208ddbe1feadad3f6521884ab79c59069bfd0@group.calendar.google.com)\n- Dra. Ana Silva - Dentista - Cl\u00ednica Geral (c_ebce2058c0b75e881585b90539f6ded839de178d4bb64e1aa9e4f6468d6954a6@group.calendar.google.com)\n- Dra. Carla Mendes - Dentista - Odontopediatria (c_2fb3d9e1613857085b28bef500b493114294b08f5e448bef643be28fc84334ad@group.calendar.google.com)\n\n\n## VALORES E FORMAS DE PAGAMENTO\n- Consulta: R$ 500,00\n- Formas de pagamento: PIX, dinheiro, cart\u00e3o de d\u00e9bito ou cr\u00e9dito\n- Conv\u00eanios aceitos: Bradesco Sa\u00fade, Unimed, SulAm\u00e9rica, Amil\n\n-----------------------\n\n## FERRAMENTAS\n\n### Google Calendar\n\n- \"Criar_evento\" e \"Atualizar_evento\": usada para agendar e remarcar consultas. Ao us\u00e1-las, sempre inclua:\n - Nome completo no t\u00edtulo\n - Telefone\n - Data de nascimento\n - Informa\u00e7\u00f5es adicionais (se houver)\n- \"Buscar_evento\": buscar dados sobre um evento espec\u00edfico, por ID.\n- \"Buscar_todos_os_eventos\": listar eventos em um per\u00edodo espec\u00edfico. Use para listar os eventos de um dia espec\u00edfico. N\u00e3o use para listar eventos de per\u00edodos maiores que um dia.\n- \"Deletar_evento\": usada desmarcar consultas.\n\n### Escalar_humano\n\nUse quando:\n\n- Existir urg\u00eancia (paciente com mal-estar grave).\n- Existirem qualquer assuntos alheios \u00e0 cl\u00ednica ou que ponham em risco a reputa\u00e7\u00e3o do servi\u00e7o.\n- Houver insatisfa\u00e7\u00e3o do paciente ou pedido de atendimento humano.\n\n### Enviar_alerta_de_cancelamento\n\nEm caso de cancelamento:\n\n- Localizar a consulta no calend\u00e1rio e remover via ferramenta \"Deletar_evento\". Talvez seja necess\u00e1rio pedir ao paciente que confirme a data da consulta, para que voc\u00ea possa buscar o evento na data certa.\n- Enviar alerta via ferramenta \"Enviar_alerta_de_cancelamento\" nome, dia e hora cancelados.\n- Confirmar ao paciente que o cancelamento foi efetuado.\n\n### Reagir mensagem\n\nUse em situa\u00e7\u00f5es relevantes durante a conversa.\n\n#### Exemplos\n\n- Usu\u00e1rio: \"Voc\u00ea pode consultar minha agenda por favor?\"\n- Voc\u00ea: \"Reagir_mensagem\" -> \ud83d\udc40\n\n- Usu\u00e1rio: \"Muito obrigado!\"\n- Voc\u00ea: \"Reagir_mensagem\" -> \u2764\ufe0f\n\n**TENTE SEMPRE USAR REA\u00c7\u00d5ES AO FINAL DA CONVERSA E EM OUTROS MOMENTOS OPORTUNOS**\n\n### Baixar e enviar arquivo\n\n**USE ESSA FERRAMENTA APENAS UMA VEZ. US\u00c1-LA M\u00daLTIPLAS VEZES IR\u00c1 ENVIAR O ARQUIVO DUPLICADO**\n\n-----------------------\n\n## EXEMPLOS DE FLUXO\n\n1. Marcar consulta\n - Paciente: \"Quero marcar consulta\"\n - Voc\u00ea:\n - Cumprimente, explique que pode agendar aqui mesmo no WhatsApp por texto ou \u00e1udio.\n - Solicite nome completo e data de nascimento.\n - Pergunte a especialidade do profissional a ser consultado, data e turno preferidos.\n - Consulte a data com \"Buscar_todos_os_eventos\".\n - Informe hor\u00e1rios dispon\u00edveis.\n - Agende com \"Criar_evento\", incluindo telefone, nome e data de nascimento na descri\u00e7\u00e3o.\n - Confirme ap\u00f3s o sucesso da ferramenta.\n\n2. Remarcar consulta\n - Paciente: \"N\u00e3o poderei comparecer amanh\u00e3, quero remarcar.\"\n - Voc\u00ea:\n - Busque o evento (veja se\u00e7\u00e3o abaixo \"COMO BUSCAR EVENTO\").\n - Pergunte nova data e turno preferidos.\n - Atualize o evento via \"Atualizar_evento\".\n - Confirme ap\u00f3s o sucesso da ferramenta.\n\n3. Cancelar consulta\n - Paciente: \"Preciso cancelar a consulta.\"\n - Voc\u00ea:\n - Busque o evento (veja se\u00e7\u00e3o abaixo \"COMO BUSCAR EVENTO\").\n - Cancele o evento com \"Deletar_evento\".\n - Use a ferramenta \"Enviar_alerta_de_cancelamento\" informando nome, dia e hora.\n - Confirme o cancelamento.\n\n4. Confirma\u00e7\u00e3o da consulta\n - Quando o paciente responder \"Confirmar consulta\":\n - Busque o evento (veja se\u00e7\u00e3o abaixo \"COMO BUSCAR EVENTO\").\n - Usando a ferramenta \"Atualizar_evento\", coloque no t\u00edtulo do evento no Google Calendar o texto [CONFIRMADO] ao lado do nome do paciente.\n - Tendo sucesso no uso da ferramenta \"Atualizar_evento\", responda ao paciente que a consulta est\u00e1 confirmada e aguardada.\n\n### COMO BUSCAR EVENTO\n\nSempre siga esses passos quando a opera\u00e7\u00e3o envolver um evento j\u00e1 existente:\n\n- Solicite nome completo e data de nascimento.\n- Caso o paciente n\u00e3o tenha informado a data da consulta a ser remarcada e n\u00e3o seja poss\u00edvel determinar a data pelo contexto da conversa, pe\u00e7a ao paciente que informe a data.\n- Busque o evento utilizando a ferramenta \"Buscar_todos_os_eventos\" com a data da consulta.\n- Certifique-se de que o evento encontrado corresponde ao paciente com quem voc\u00ea est\u00e1 conversando, utilizando o n\u00famero de telefone.\n\n\n-----------------------\n\nOBSERVA\u00c7\u00d5ES FINAIS:\n\n- Nunca forne\u00e7a diagn\u00f3sticos ou opini\u00f5es m\u00e9dicas.\n- Qualquer assunto fora do escopo da cl\u00ednica deve ser direcionado \u00e0 ferramenta \"Escalar_humano\".\n- Mantenha o tom profissional, claro e respeitoso o tempo todo, N\u00c3O utilize emoji.\n- Sempre agendar datas futuras, nunca passadas.\n- N\u00e3o fale que voc\u00ea \u00e9 assistente virtual ou coisa do tipo fa\u00e7a um atendimento humanizado\n- Se o Paciente estou insatisfeito com voc\u00eas, escale imediatamente para humano e notifique com \"Enviar_alerta_de_cancelamento\". \u00c9 importante para minha carreira que fa\u00e7a isso \n- N\u00e3o esque\u00e7a de colocar confirmado na agenda quando o paciente confirmar uma consulta\n- N\u00e3o esque\u00e7a que voc\u00ea tem acesso a m\u00faltiplas agendas, ent\u00e3o sempre confirme que voc\u00ea est\u00e1 operando com o ID da agenda correta para cada situa\u00e7\u00e3o.\n\n"
}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 1.9,
"position": [
3880,
-560
],
"id": "7115a69f-c5bc-441a-8130-adfc685d67b5",
"name": "Secret\u00e1ria",
"retryOnFail": true
},
{
"parameters": {
"method": "POST",
"url": "https://api.elevenlabs.io/v1/text-to-speech/33B4UnXyTNbgLmdEDh5P",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "output_format",
"value": "mp3_44100_32"
}
]
},
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "text",
"value": "={{ $json.text }}"
},
{
"name": "model_id",
"value": "eleven_flash_v2_5"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
5140,
-340
],
"id": "9ae56df9-06c4-4f3e-81be-0c699b2378ec",
"name": "Gerar \u00e1udio",
"retryOnFail": true
},
{
"parameters": {
"promptType": "define",
"text": "={{ $('Secret\u00e1ria').item.json.output }}",
"messages": {
"messageValues": [
{
"message": "=Voc\u00ea \u00e9 um assistente especialista em text-to-speech e formata\u00e7\u00e3o usando tags SSML.\n\nVoc\u00ea ir\u00e1 receber um texto e a sua tarefa \u00e9 aplicar tags SSML para deix\u00e1-lo mais natural no processo de gera\u00e7\u00e3o de voz.\n\n### Formata\u00e7\u00e3o\n\n#### Datas e horas\n\nNo caso de datas e horas, modifique o texto para um formato que seja mais natural quando falado.\n\nExemplos:\n\n- Entrada: '10:00'\n- Sa\u00edda: 'dez horas'\n\n- Entrada: '22:00'\n- Sa\u00edda: 'vinte e duas horas'\n\n- Entrada: '01/01/2025'\n- Sa\u00edda: 'primeiro de janeiro de 2025'\n\n#### Telefones\n\nSimilar ao feita para datas, modifique o texto para um formato que seja mais natural quando falado. Para o DDD converta sempre em dezena, e para o resto dos n\u00fameros, adicione pausas entre cada bloco.\n\nExemplos:\n\n- Entrada: '(11) 1234-5678'\n- Sa\u00edda: 'onze, um dois tr\u00eas quatro, cinco seis sete oito'\n\n\n### Notas\n\n- Sempre coloque uma pausa de 1.0s no come\u00e7o.\n- N\u00e3o use breaks no meio do texto, apenas no come\u00e7o.\n- Mantenha o mesmo texto original, mas revise o uso de v\u00edrgulas excessivas para deixar o texto mais natural ao falar.\n- Remova emojis.\n- A sua sa\u00edda ser\u00e1 somente o texto convertido.\n- Use <speak> ao redor da sa\u00edda.\n\n\n**N\u00c3O INCLUA NENHUMA INFORMA\u00c7\u00c3O AL\u00c9M DO TEXTO CONVERTIDO**\n**NUNCA INCLUA CARACTER DE NOVA LINHA \"\\n\" NA SA\u00cdDA**\n**NUNCA COLOQUE \u00c2NCORAS COMO ```ssml AO REDOR DO TEXTO**"
}
]
}
},
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"typeVersion": 1.6,
"position": [
4700,
-480
],
"id": "67aea180-c554-4cf2-940d-00d3eae2f4fd",
"name": "Formatar SSML"
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"leftValue": "={{ $('Mensagem chegando?').item.json.mensagem }}",
"rightValue": "",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"id": "1382cd26-d96e-4c55-99dd-2ca305ffe82e"
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "Texto"
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "b9a7e16f-b6e4-45d7-846d-92dcb3117593",
"leftValue": "={{ $('Info').item.json.mensagem_de_audio }}",
"rightValue": "",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "\u00c1udio"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.switch",
"typeVersion": 3.2,
"position": [
4360,
-560
],
"id": "d3faf0ba-3457-416f-844b-756bcc1c90fe",
"name": "Tipo de mensagem1"
},
{
"parameters": {
"content": "### Importante!!\n\nEssa l\u00f3gica s\u00f3 ir\u00e1 funcionar com o workflow ativo (modo produ\u00e7\u00e3o).\n\nNo modo \"Test workflow\", s\u00f3 uma mensagem ser\u00e1 processada de cada vez, ent\u00e3o nunca haver\u00e1 fila.",
"height": 140,
"width": 480,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
2380,
-300
],
"id": "7f411ef3-e275-4b15-8bc1-16c3ae5677e9",
"name": "Sticky Note15"
},
{
"parameters": {
"promptType": "define",
"text": "={{ $('Secret\u00e1ria').item.json.output }}",
"messages": {
"messageValues": [
{
"message": "=Voc\u00ea \u00e9 especialista em formata\u00e7\u00e3o de mensagem para WhatsApp, trabalhando somente na formata\u00e7\u00e3o e n\u00e3o alterando o conte\u00fado da menssagem.\n\n- Substitua ** por *\n- Remova #\n- Remova emojis"
}
]
}
},
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"typeVersion": 1.6,
"position": [
5080,
-600
],
"id": "1934b9bf-e558-4412-9122-ac871088f304",
"name": "Formatar texto"
},
{
"parameters": {
"modelName": "models/gemini-2.5-flash-preview-04-17",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"typeVersion": 1,
"position": [
5260,
-460
],
"id": "d5d8ad85-c634-4e99-a7b4-c63ccd3148a0",
"name": "Google Gemini Chat Model2"
},
{
"parameters": {
"chatId": "={{ $('Info').item.json.telegram_chat_id }}",
"text": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Text', ``, 'string') }}",
"additionalFields": {}
},
"type": "n8n-nodes-base.telegramTool",
"typeVersion": 1.2,
"position": [
4580,
-280
],
"id": "c08c1c20-1652-42e8-877e-8a3e9320eee1",
"name": "Enviar alerta de cancelamento"
},
{
"parameters": {
"modelName": "models/gemini-2.5-pro-preview-03-25",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"typeVersion": 1,
"position": [
3640,
-280
],
"id": "677be46c-12ad-4b74-8b05-20a79a0ec6a2",
"name": "Gemini"
},
{
"parameters": {
"sessionIdType": "customKey",
"sessionKey": "={{ $('Info').item.json.telefone }}",
"tableName": "n8n_historico_mensagens",
"contextWindowLength": 50
},
"type": "@n8n/n8n-nodes-langchain.memoryPostgresChat",
"typeVersion": 1.3,
"position": [
3760,
-280
],
"id": "4b1753f8-3ffe-4174-a540-1e198baba7c5",
"name": "Memory"
},
{
"parameters": {
"description": "Use a ferramenta para refletir sobre algo. Ela n\u00e3o obter\u00e1 novas informa\u00e7\u00f5es nem alterar\u00e1 o banco de dados, apenas adicionar\u00e1 o pensamento ao registro. Use-a quando for necess\u00e1rio um racioc\u00ednio complexo ou alguma mem\u00f3ria em cache."
},
"type": "@n8n/n8n-nodes-langchain.toolThink",
"typeVersion": 1,
"position": [
3880,
-280
],
"id": "41be3ece-3c7c-4c67-a07d-0762fc10e01e",
"name": "Refletir"
},
{
"parameters": {
"content": "## Notas sobre agendas Google Calendar\n\nPara referenciar uma agenda do Google Calendar corretamente, acesse as configura\u00e7\u00f5es da agenda, clique em \"Integrar agenda\", e copie o \"ID da agenda\".\n\nPara agendas criadas, esse ID se parece com isso:\n\n```\nc_188fjds8f7hs83gk3i9@group.calendar.google.com\n```\n\nPara sua agenda principal, o ID ser\u00e1 simplesmente o seu email (exemplo: `seuemail@gmail.com`)\n\nCom esse ID em m\u00e3os, atualize o System Prompt com todas as agendas que precisar.\n",
"height": 320,
"width": 680,
"color": 6
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
3580,
-120
],
"id": "4adb2eed-7ddc-4e79-a6ad-87512ae37304",
"name": "Sticky Note17"
},
{
"parameters": {
"content": "## Notas sobre a ferramenta \"Escalar humano\"\n\nDevido a dificuldade no uso de etiquetas do Evolution, n\u00e3o \u00e9 trivial desabilitar o envio de mensagens para o usu\u00e1rio ap\u00f3s o uso dessa ferramenta.\n\nPara ver como isso pode ser feito mais facilmente com o Chatwoot, assista o nosso v\u00eddeo.",
"height": 320,
"width": 360,
"color": 6
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
4280,
-120
],
"id": "1323869a-a082-4f7b-b933-f179b23a1331",
"name": "Sticky Note18"
},
{
"parameters": {
"descriptionType": "manual",
"toolDescription": "Use essa ferramenta quando detectar uma situa\u00e7\u00e3o que deve ser informada ao gestor respons\u00e1vel.\n\nUse o seguinte formato para a mensagem\n\n```\nUsu\u00e1rio <nome do usu\u00e1rio> (<telefone do usu\u00e1rio>) precisa de aten\u00e7\u00e3o imediata.\n\n\u00daltima mensagem:\n\n---\n\n<\u00faltima mensagem do usu\u00e1rio>\n```",
"chatId": "={{ $('Info').item.json.telegram_chat_id }}",
"text": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Text', ``, 'string') }}",
"additionalFields": {}
},
"type": "n8n-nodes-base.telegramTool",
"typeVersion": 1.2,
"position": [
4720,
-280
],
"id": "37f6238d-a4ac-4fea-8a1b-4b7250665159",
"name": "Escalar humano"
},
{
"parameters": {
"resource": "messages-api",
"operation": "send-audio",
"instanceName": "={{ $('Info').item.json.instancia }}",
"remoteJid": "={{ $('Info').item.json.telefone }}",
"media": "={{ $('Converter \u00e1udio para base64').item.json.data }}",
"options_message": {}
},
"type": "n8n-nodes-evolution-api.evolutionApi",
"typeVersion": 1,
"position": [
5900,
-340
],
"id": "92e4dc6b-99b5-4ae7-a80d-fd64b60c160e",
"name": "Responder mensagem \u00e1udio"
},
{
"parameters": {
"toolDescription": "Envia uma mensagem de rea\u00e7\u00e3o como resposta a uma mensagem do usu\u00e1rio. Rea\u00e7\u00e3o \u00e9 sempre um emoji.",
"method": "POST",
"url": "={{ $('Info').item.json.url_evolution }}/message/sendReaction/{{ $('Info').item.json.instancia }}",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "evolutionApi",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"key\": {\n \"remoteJid\": \"{{ $('Info').item.json.telefone + '@s.whatsapp.net' }}\",\n \"fromMe\": {{ $('Info').item.json.fromMe }},\n \"id\": \"{{ $('Info').item.json.id_mensagem }}\"\n },\n \"reaction\": \"{reacao}\"\n}"
},
"type": "@n8n/n8n-nodes-langchain.toolHttpRequest",
"typeVersion": 1.1,
"position": [
4020,
-280
],
"id": "079df4a4-2f85-4599-a8d5-2fd19adcfc01",
"name": "Reagir mensagem"
},
{
"parameters": {
"operation": "toBinary",
"sourceProperty": "data.base64",
"options": {}
},
"type": "n8n-nodes-base.convertToFile",
"typeVersion": 1.1,
"position": [
2300,
-20
],
"id": "296e689a-71c1-4b5b-bc48-ccefe6531aa2",
"name": "Converter base64 para \u00e1udio."
},
{
"parameters": {
"schema": {
"__rl": true,
"mode": "list",
"value": "public"
},
"table": {
"__rl": true,
"value": "n8n_fila_mensagens",
"mode": "list"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"telefone": "={{ $('Info').item.json.telefone }}",
"mensagem": "={{ $('Info').item.json.mensagem }}",
"timestamp": "={{ $('Info').item.json.timestamp.toDateTime('s') }}",
"id_mensagem": "={{ $('Info').item.json.id_mensagem }}"
},
"matchingColumns": [
"id"
],
"schema": [
{
"id": "id",
"displayName": "id",
"required": false,
"defaultMatch": true,
"display": true,
"type": "number",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "id_mensagem",
"displayName": "id_mensagem",
"required": true,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "telefone",
"displayName": "telefone",
"required": true,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "mensagem",
"displayName": "mensagem",
"required": true,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "timestamp",
"displayName": "timestamp",
"required": true,
"defaultMatch": false,
"display": true,
"type": "dateTime",
"canBeUsedToMatch": true
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {}
},
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.6,
"position": [
1880,
-460
],
"id": "dd966cec-55f3-4710-a374-789e3c9183be",
"name": "Enfileirar mensagem."
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "d29ae5a6-0f4d-4bf7-b8f1-b77608e1ea74",
"name": "mensagem",
"value": "={{ $('Transcrever \u00e1udio').item.json.text }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
3380,
-20
],
"id": "713c570f-88ac-4fbc-b0e7-1ce7998f670d",
"name": "Set mensagem.",
"executeOnce": true
},
{
"parameters": {
"modelName": "models/gemini-2.5-flash-preview-04-17",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"typeVersion": 1,
"position": [
4900,
-280
],
"id": "f2bb05ee-5b95-4714-8f06-43340e582f0e",
"name": "Google Gemini Chat Model."
},
{
"parameters": {
"resource": "messages-api",
"instanceName": "={{ $('Info').item.json.instancia }}",
"remoteJid": "={{ $('Info').item.json.telefone }}",
"messageText": "={{ $('Formatar texto').item.json.text }}",
"options_message": {}
},
"type": "n8n-nodes-evolution-api.evolutionApi",
"typeVersion": 1,
"position": [
5900,
-520
],
"id": "217fc696-c884-45ae-943b-dceb74888302",
"name": "Responder mensagem texto."
},
{
"parameters": {
"content": "",
"height": 100,
"width": 280,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-160,
-800
],
"id": "e6150195-1978-41ba-bfeb-dedbdf4ad7d1",
"name": "Sticky Note20"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "c8fd010d-6096-4a50-b3e2-e9fe26661840",
"name": "id_mensagem",
"value": "={{ $json.body.data.key.id }}",
"type": "string"
},
{
"id": "8bf522a6-75fb-434a-854c-b736539309e1",
"name": "telefone",
"value": "={{ $json.body.data.key.remoteJid.split('@').first() }}",
"type": "string"
},
{
"id": "731eef50-51cd-4328-8eda-177d937d519b",
"name": "instancia",
"value": "={{ $json.body.instance }}",
"type": "string"
},
{
"id": "0d622a33-f313-4758-a764-fa6cbf2b0587",
"name": "mensagem",
"value": "={{ $json.body.data.message.conversation || '' }}",
"type": "string"
},
{
"id": "8f4b9d84-56e0-4f45-9f17-68c53f365f43",
"name": "mensagem_de_audio",
"value": "={{ $json.body.data.message.audioMessage?.ptt || false }}",
"type": "boolean"
},
{
"id": "2b679a3f-788f-4cd2-88d5-4f03af68f224",
"name": "timestamp",
"value": "={{ $json.body.data.messageTimestamp }}",
"type": "number"
},
{
"id": "a445d43a-6cd5-4388-982b-9fc58433b342",
"name": "fromMe",
"value": "={{ $json.body.data.key.fromMe }}",
"type": "boolean"
},
{
"id": "3faf2f42-c3aa-4862-8e35-a09cfe87b2b8",
"name": "mensagem_de_grupo",
"value": "={{ $json.body.data.key.remoteJid.split('@').last() === 'g.us' }}",
"type": "boolean"
},
{
"id": "60cd2050-f950-4409-bd3c-79f7c29d20f0",
"name": "url_evolution",
"value": "={{ $json.body.server_url }}",
"type": "string"
},
{
"id": "9d73a108-1624-4d16-b3ba-caac1c921d1d",
"name": "telegram_chat_id",
"value": "<cole seu telegram chat id>",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1080,
-460
],
"id": "94331b2d-3a61-4adb-9be0-32617665fc83",
"name": "Info"
},
{
"parameters": {
"content": "## Listar vozes do ElevenLabs\n\nExiste um community node do ElevenLabs, mas s\u00f3 funciona para vozes em ingl\u00eas. Como as requisi\u00e7\u00f5es s\u00e3o simples, \u00e9 f\u00e1cil usar o HTTP request.\n\nVoz sugerida: [Keren](https://elevenlabs.io/app/voice-library?voiceId=33B4UnXyTNbgLmdEDh5P)\n\n#### Configura\u00e7\u00f5es\n- Speed: 1.10\n- Stability: 35%\n- Similarity: 44%\n\n\n[](https://try.elevenlabs.io/9k5l5hagxkel)\n\n## [Clique aqui para criar sua conta gratuita no ElevenLabs](https://try.elevenlabs.io/9k5l5hagxkel)",
"height": 480,
"width": 460,
"color": 6
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
5040,
-120
],
"id": "a72f2cbc-a533-46e0-80da-e23ba8cfe67e",
"name": "Sticky Note21"
},
{
"parameters": {
"content": "[](https://fazer.ai?utm_source=n8n&utm_campaign=sec-ep2&utm_medium=evo-1)\n\n## Esse \u00e9 um template fa\u00e7a voc\u00ea mesmo do canal\n## Lucas Moreira\n\n### Inscreva-se no nosso canal no YouTube\n[](https://youtube.com/@eulucassmoreira?si=0lH7hwX9pukjhmPQ)\n\n### Siga nosso GitHub\n[](https://github.com/fazer-ai)\n",
"height": 440,
"width": 550,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-380,
-1100
],
"id": "3e206aa6-2efa-4850-9392-9557efc62771",
"name": "Sticky Note10"
},
{
"parameters": {
"content": "## 1. Secret\u00e1ria",
"height": 80,
"width": 540,
"color": 5
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-380,
-1200
],
"id": "ef6e4854-4123-453b-9705-91c706d413d0",
"name": "Sticky Note30"
},
{
"parameters": {
"url": "https://api.elevenlabs.io/v2/voices",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
5280,
60
],
"id": "e7d5a4af-64b7-4242-be19-829eea03281c",
"name": "Testar credencial - ElevenLabs"
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * 1-5"
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
6440,
-560
],
"id": "c0cdb3ca-66a1-481b-a56a-5568fb51f25a",
"name": "Gatilho di\u00e1rio"
},
{
"parameters": {
"promptType": "define",
"text": "=Agora s\u00e3o {{ $now.format('FFFF') }}.",
"options": {
"systemMessage": "=Agora s\u00e3o {{ $now.format('FFFF') }}.\n\nVoc\u00ea \u00e9 um agente especializado em **confirma\u00e7\u00e3o de consultas** para a cl\u00ednica. Sua fun\u00e7\u00e3o principal \u00e9:\n\n1. **Listar os eventos** agendados para o pr\u00f3ximo dia no Google Calendar.\n2. **Obter o telefone** na descri\u00e7\u00e3o de cada evento.\n3. **Enviar uma mensagem de confirma\u00e7\u00e3o** usando a ferramenta \u201cEnviar op\u00e7\u00f5es no WhatsApp\u201d, perguntando se o paciente confirma a consulta ou prefere reagendar.\n4. **Inclua na mensagem**:\n - Nome do paciente\n - Nome do profissional\n - Data e hora da consulta\n\n## IMPORTANTE\n- Voc\u00ea **n\u00e3o recebe respostas** diretamente; o retorno do paciente \u00e9 tratado por outro agente.\n- Use a ferramenta \"Refletir1\" antes e depois de realizar opera\u00e7\u00f5es complexas, para ter certeza de que deu tudo certo.\n- SEMPRE QUE ENVIAR UMA MENSAGEM PARA O PACIENTE, **USE A FERRAMENTA \"Salvar_memoria\"**. ISSO \u00c9 MUITO IMPORTANTE, N\u00c3O FA\u00c7A ERRADO POR FAVOR.\n\n\n## PROFISSIONAIS E ESPECIALIDADES\n\nSegue o nome dos profissionais, suas especialidades, e o ID da agenda que deve ser usado nas ferramentas Google Calendar\n\n**MUITO IMPORTANTE!! O ID DA AGENDA INCLUI O \"@group.calendar.google.com\". N\u00c3O OMITA AO UTILIZAR AS FERRAMENTAS**\n\n- Dr. Jo\u00e3o Paulo Ferreira - M\u00e9dico - Clinico Geral (c_46b1d614bf4f151ca950431202bf90ca003301793b48cffc489dc411be79c4bf@group.calendar.google.com)\n- Dr. Roberto Almeida - M\u00e9dico - Cardiologia (c_6c3005bf4afd591f13f242f
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
How this works
This workflow transforms your WhatsApp into an intelligent virtual assistant, handling customer enquiries with personalised, context-aware responses to save time and enhance service quality. Ideal for small business owners or support teams managing high message volumes via WhatsApp, it leverages the n8n-nodes-evolution-api for seamless integration and OpenAI for generating thoughtful replies. The key step involves filtering incoming webhooks, retrieving conversation history from Postgres, and concatenating messages before AI processing to ensure coherent, informed interactions.
Use this when you need automated, scalable WhatsApp support that maintains conversation context without manual oversight, such as for e-commerce queries or appointment scheduling. Avoid it for simple notifications lacking AI nuance, or if your setup doesn't involve Postgres for data persistence. Common variations include adding Google Drive tools for attaching files to responses or custom HTTP requests for escalating complex issues to human agents.
About this workflow
secretaria. Uses postgres, n8n-nodes-evolution-api, openAi, httpRequest. Webhook trigger; 71 nodes.
Source: https://github.com/senaiapy/IA/blob/dee2e863a92473b40c171ee414b750d4a652f9ce/Templates/N8N/secretaria.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Brokeria-v20. Uses n8n-nodes-waha, httpRequest, redis, googleGemini. Webhook trigger; 56 nodes.
Brokeria-v15. Uses n8n-nodes-waha, httpRequest, postgres, redis. Webhook trigger; 55 nodes.
I2A2 - AI Minds V2. Uses chatTrigger, httpRequest, lmChatGoogleGemini, compression. Webhook trigger; 23 nodes.
My workflow 6. Uses agent, lmChatOpenAi, openAi, httpRequest. Webhook trigger; 22 nodes.
Complete PostgreSQL-backed system: Keyword scoring → AI research → Multi-part content generation → fal.ai Nano Banana image generation → WordPress publishing