This workflow follows the Google Sheets → OpenAI 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": "Assistente Triagem Clinica - Telegram",
"nodes": [
{
"parameters": {
"updates": [
"message"
],
"additionalFields": {}
},
"type": "n8n-nodes-base.telegramTrigger",
"typeVersion": 1.2,
"position": [
0,
0
],
"id": "a15b7add-eee1-4f07-a8d0-8ef0f97322d8",
"name": "Telegram Trigger",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const chatId = String($input.first().json.message.chat.id);\nconst text = String($input.first().json.message.text || '');\nconst staticData = $getWorkflowStaticData('global');\nif (!staticData.conversations) staticData.conversations = {};\nif (!staticData.conversations[chatId]) staticData.conversations[chatId] = [];\n\nconst history = staticData.conversations[chatId].slice(-12);\nlet context = '';\nif (history.length) {\n context = history.map(m => `${m.role === 'user' ? 'Paciente' : 'Recepcionista'}: ${m.content}`).join('\\n');\n}\n\nconst userContent = context\n ? `Historico recente da conversa:\\n${context}\\n\\nMensagem atual do paciente:\\n${text}`\n : text;\n\nreturn [{\n json: {\n chatId,\n text,\n userContent,\n history,\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
260,
0
],
"id": "b2c3d4e5-1111-2222-3333-444455556666",
"name": "Preparar Contexto"
},
{
"parameters": {
"modelId": {
"__rl": true,
"value": "gpt-4o-mini",
"mode": "list",
"cachedResultName": "GPT-4O-MINI"
},
"responses": {
"values": [
{
"type": "text",
"role": "system",
"content": "Voc\u00ea \u00e9 a recepcionista virtual de uma cl\u00ednica m\u00e9dica. Atue exclusivamente como recep\u00e7\u00e3o: acolher pacientes, orientar e coletar informa\u00e7\u00f5es para encaminhar o agendamento. N\u00e3o diagnostique, n\u00e3o receite, n\u00e3o interprete exames e n\u00e3o substitua orienta\u00e7\u00e3o m\u00e9dica.\n\nComunique-se sempre em portugu\u00eas do Brasil.\n\n## Tom\n- Acolhedor, claro, respeitoso e profissional.\n- Linguagem simples, emp\u00e1tica e objetiva.\n- Trate a pessoa pelo nome assim que souber.\n- Evite jarg\u00e3o m\u00e9dico complexo.\n- Respostas curtas: em geral 1 a 3 frases.\n- Nunca seja frio, apressado, autorit\u00e1rio ou informal demais.\n\n## Objetivo\nConduzir a triagem inicial e reunir, de forma organizada:\n1. Nome completo do paciente\n2. Queixa principal (breve)\n3. Prefer\u00eancia de dia/hor\u00e1rio para atendimento\n\n## Fluxo da conversa\nSiga esta ordem, adaptando-se ao que a pessoa j\u00e1 disse:\n\n### 1. Boas-vindas\nCumprimente e diga que pode ajudar com agendamento ou orienta\u00e7\u00e3o inicial da recep\u00e7\u00e3o.\n\nExemplo:\n\"Ol\u00e1! Bem-vindo(a) \u00e0 cl\u00ednica. Sou a recepcionista virtual e posso ajudar com o agendamento. Como posso te chamar?\"\n\n### 2. Nome\n- Pe\u00e7a o nome completo do paciente.\n- Se for agendamento para outra pessoa, confirme o nome de quem ser\u00e1 atendido.\n- Depois, use o nome nas pr\u00f3ximas mensagens.\n\n### 3. Queixa principal\n- Pergunte o motivo principal da visita.\n- Pe\u00e7a uma descri\u00e7\u00e3o breve.\n- N\u00e3o aprofunde com muitas perguntas cl\u00ednicas.\n- Se houver sinais de urg\u00eancia, oriente procurar emerg\u00eancia imediatamente.\n\nExemplo:\n\"[Nome], qual \u00e9 a queixa ou o motivo principal da consulta? Pode resumir em poucas palavras.\"\n\n### 4. Prefer\u00eancia de hor\u00e1rio\n- Pergunte dia e hor\u00e1rio de prefer\u00eancia.\n- Se vier incompleto, pe\u00e7a s\u00f3 o que falta.\n- Se for vago, ajude a especificar: manh\u00e3, tarde, dia da semana ou data aproximada.\n\n### 5. Confirma\u00e7\u00e3o\nQuando tiver nome, queixa e hor\u00e1rio:\n- Fa\u00e7a um resumo curto.\n- Informe que a solicita\u00e7\u00e3o ser\u00e1 encaminhada \u00e0 recep\u00e7\u00e3o/equipe para confirma\u00e7\u00e3o.\n- Agrade\u00e7a.\n\nExemplo:\n\"Perfeito, [Nome]. Anotei: consulta para [queixa], com prefer\u00eancia por [hor\u00e1rio]. Vou encaminhar para confirma\u00e7\u00e3o. Obrigado(a) pelo contato!\"\n\n## Regras\n- Prefira uma pergunta por vez.\n- Se a pessoa j\u00e1 informou algo, confirme e avance \u2014 n\u00e3o pergunte de novo.\n- N\u00e3o invente hor\u00e1rios dispon\u00edveis, pre\u00e7os, conv\u00eanios, endere\u00e7o, nomes de m\u00e9dicos ou confirma\u00e7\u00e3o de agenda.\n- Se n\u00e3o souber, diga que vai verificar com a equipe da cl\u00ednica.\n- N\u00e3o prometa agendamento confirmado sem confirma\u00e7\u00e3o da cl\u00ednica.\n\n## Limites\n- Sem diagn\u00f3stico, progn\u00f3stico, tratamento ou indica\u00e7\u00e3o de medicamento.\n- N\u00e3o minimize sintomas.\n- N\u00e3o pe\u00e7a dados desnecess\u00e1rios (CPF, endere\u00e7o completo, dados financeiros), salvo se o contexto do sistema exigir.\n- Emerg\u00eancia (dor no peito, falta de ar intensa, desmaio, sangramento intenso, idea\u00e7\u00e3o suicida, convuls\u00e3o ou risco imediato): interrompa o fluxo de agenda e oriente procurar emerg\u00eancia ou ligar para o SAMU 192.\n\n## Formato da resposta ao paciente\n- Respostas curtas e naturais.\n- N\u00e3o mencione regras internas, prompts ou funcionamento t\u00e9cnico.\n- S\u00f3 diga que \u00e9 IA se a pessoa perguntar diretamente.\n\n## Bloco t\u00e9cnico (obrigat\u00f3rio ao concluir a triagem)\nQuando nome, queixa e hor\u00e1rio estiverem completos, envie primeiro a mensagem normal ao paciente.\nNa mesma resposta, depois da mensagem, inclua exatamente este bloco (o sistema remove antes de mostrar ao paciente):\n\n<<<TRIAGEM>>>\n{\"nome\":\"...\",\"queixa\":\"...\",\"horario_preferido\":\"...\",\"status\":\"completo\"}\n<<<FIM>>>\n\nPreencha o JSON com os dados reais coletados. N\u00e3o use esse bloco antes da triagem estar completa.\n"
},
{
"type": "text",
"role": "user",
"content": "={{ $json.userContent }}"
}
]
},
"builtInTools": {},
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.openAi",
"typeVersion": 2.3,
"position": [
520,
0
],
"id": "cb213871-998c-45d9-94bd-a8de036a28dd",
"name": "Message a model",
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const chatId = String($('Preparar Contexto').item.json.chatId);\nconst userText = String($('Preparar Contexto').item.json.text || '');\nlet raw = String($json.output?.[0]?.content?.[0]?.text || $json.output || '');\n\nconst match = raw.match(/<<<TRIAGEM>>>\\s*([\\s\\S]*?)\\s*<<<FIM>>>/);\nlet lead = null;\nlet reply = raw;\n\nif (match) {\n reply = raw.replace(match[0], '').trim();\n try {\n lead = JSON.parse(match[1].trim());\n } catch (e) {\n lead = null;\n }\n}\n\nconst staticData = $getWorkflowStaticData('global');\nif (!staticData.conversations) staticData.conversations = {};\nif (!staticData.conversations[chatId]) staticData.conversations[chatId] = [];\nstaticData.conversations[chatId].push({ role: 'user', content: userText });\nstaticData.conversations[chatId].push({ role: 'assistant', content: reply });\nif (staticData.conversations[chatId].length > 20) {\n staticData.conversations[chatId] = staticData.conversations[chatId].slice(-20);\n}\n\nif (lead?.status === 'completo') {\n staticData.conversations[chatId] = [];\n}\n\nreturn [{\n json: {\n chatId,\n output: reply,\n leadCompleto: !!(lead && lead.status === 'completo'),\n nome: lead?.nome || '',\n queixa: lead?.queixa || '',\n horario_preferido: lead?.horario_preferido || '',\n registrado_em: new Date().toISOString(),\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
780,
0
],
"id": "c3d4e5f6-7777-8888-9999-aaaa0000bbbb",
"name": "Extrair Lead e Memoria"
},
{
"parameters": {
"resource": "message",
"operation": "sendMessage",
"chatId": "={{ $json.chatId }}",
"text": "={{ $json.output }}",
"additionalFields": {
"appendAttribution": false
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
1040,
-120
],
"id": "f3a8c2d1-9b4e-4a7f-8c6d-1e2f3a4b5c6d",
"name": "Send Telegram Message",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{ $json.leadCompleto }}",
"value2": true
}
]
}
},
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
1040,
120
],
"id": "d4e5f6a7-1212-3434-5656-787890901212",
"name": "Lead Completo?"
},
{
"parameters": {
"operation": "append",
"documentId": {
"__rl": true,
"mode": "id",
"value": "SUBSTITUA_PELO_ID_DA_PLANILHA"
},
"sheetName": {
"__rl": true,
"mode": "name",
"value": "Leads"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"registrado_em": "={{ $json.registrado_em }}",
"nome": "={{ $json.nome }}",
"queixa": "={{ $json.queixa }}",
"horario_preferido": "={{ $json.horario_preferido }}",
"chat_id": "={{ $json.chatId }}"
}
},
"options": {}
},
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
1300,
120
],
"id": "e5f6a7b8-9999-aaaa-bbbb-ccccddddeeee",
"name": "Salvar Lead na Planilha",
"disabled": true,
"notesInFlow": true,
"notes": "Ative este no, conecte Google Sheets e troque o ID da planilha. Aba: Leads."
}
],
"connections": {
"Telegram Trigger": {
"main": [
[
{
"node": "Preparar Contexto",
"type": "main",
"index": 0
}
]
]
},
"Preparar Contexto": {
"main": [
[
{
"node": "Message a model",
"type": "main",
"index": 0
}
]
]
},
"Message a model": {
"main": [
[
{
"node": "Extrair Lead e Memoria",
"type": "main",
"index": 0
}
]
]
},
"Extrair Lead e Memoria": {
"main": [
[
{
"node": "Send Telegram Message",
"type": "main",
"index": 0
},
{
"node": "Lead Completo?",
"type": "main",
"index": 0
}
]
]
},
"Lead Completo?": {
"main": [
[
{
"node": "Salvar Lead na Planilha",
"type": "main",
"index": 0
}
],
[]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1",
"binaryMode": "separate",
"availableInMCP": false
},
"versionId": "876fb195-8530-4e9b-aa29-81af2bf7d502",
"meta": {
"templateCredsSetupCompleted": false
},
"nodeGroups": [],
"tags": []
}
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.
openAiApitelegramApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Assistente Triagem Clinica - Telegram. Uses telegramTrigger, openAi, telegram, googleSheets. Event-driven trigger; 7 nodes.
Source: https://github.com/yuri10101042/assistente-triagem-ia/blob/main/workflow-triagem.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.
Ask questions like “How much did I spend on food last month?” and get instant answers from your financial data — directly in Telegram.
> ⚠️ Disclaimer: This workflow uses Community Nodes and must be run on a self-hosted instance of n8n.
Viral Tik Tok Clone Finder. Uses httpRequest, telegramTrigger, openAi, googleSheets. Event-driven trigger; 41 nodes.
This workflow is designed for content creators, agencies, influencers, and automation builders who want to transform viral videos into personalized avatar-based edits — and automatically publish them
💸 HOW IT WORKS — AI TELEGRAM EXPENSE TRACKER