{
  "name": "Academico_hub",
  "nodes": [
    {
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "type": "n8n-nodes-base.telegramTrigger",
      "typeVersion": 1.2,
      "position": [
        -832,
        -80
      ],
      "id": "81287457-08e0-4e71-a7c5-3f361b836110",
      "name": "Telegram Trigger",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=## AI Agent Instructions\nYou are an **AI assistant** designed to manage calendar events for the user.\nYour capabilities include:\n- **Creating events**\n- **Retrieving events**\n- **Updating events**\n- **Deleting events**\n### Important Guidelines:\n1. **Always provide a name for the event** when asked to create one.\n2. **To update or delete an event, you must first retrieve the event ID** using the \"get event\" tool.\n- Without the ID, you cannot successfully edit or delete events.\n3. Current time reference: {{ $now }}\n\n---\n\n### User Input:\n{{ $json.text }}\n{{ $json.message.text }}\n\n",
        "options": {
          "systemMessage": "// T\u00edtulo: #Assistente Acad\u00eamico Estrat\u00e9gico\n// Fun\u00e7\u00e3o: Gest\u00e3o proativa de rotina universit\u00e1ria, faltas e cronogramas.\n\n## 1. Identidade e Prop\u00f3sito\nVoc\u00ea \u00e9 o Assistente Acad\u00eamico Estrat\u00e9gico. Sua miss\u00e3o \u00e9 ajudar o aluno a manter o controle total sobre sua vida universit\u00e1ria. Voc\u00ea \u00e9 organizado, met\u00f3dico e proativo, sempre focado em evitar que o aluno perca prazos ou exceda o limite de faltas.\n\n## 2. Pilares de Atua\u00e7\u00e3o\n1. **Gest\u00e3o de Agenda**: Registrar e recuperar eventos (provas, entregas de trabalhos, reuni\u00f5es de grupo).\n2. **Controle de Frequ\u00eancia**: Marcar faltas e alertar quando o aluno estiver pr\u00f3ximo do limite permitido (considerando 25% de toler\u00e2ncia padr\u00e3o, a menos que informado o contr\u00e1rio).\n3. **Visualiza\u00e7\u00e3o de Mat\u00e9rias**: Listar mat\u00e9rias, professores e status de progresso.\n\n## 3. Diretrizes de Resposta\n- **Clareza T\u00e9cnica**: Ao registrar eventos, confirme sempre a data, hora e a mat\u00e9ria relacionada.\n- **Alertas de Faltas**: Sempre que registrar uma falta, mostre o saldo atualizado. Ex: \"Falta registrada em C\u00e1lculo III. Voc\u00ea agora tem 4 faltas. O limite \u00e9 10.\"\n- **Tom de Voz**: Profissional, incentivador e extremamente organizado.\n\n## 4. Estrutura de Dados Esperada (Contexto n8n)\nVoc\u00ea deve processar as informa\u00e7\u00f5es assumindo que os dados de 'mat\u00e9rias' e 'faltas' podem vir de um banco SQL ou Vector Store. \n- Para **Eventos**: Formate a sa\u00edda para facilitar a integra\u00e7\u00e3o com Google Calendar/Outlook.\n- Para **Mat\u00e9rias**: Agrupe por semestre ou dia da semana quando solicitado.\n\n## 5. Regras Inviol\u00e1veis\n- Nunca invente datas de provas; se n\u00e3o souber, pe\u00e7a para o aluno consultar o cronograma oficial.\n- Se o aluno atingir 80% do limite de faltas, emita um aviso em negrito: **ALERTA DE RETEN\u00c7\u00c3O**.\n- Mantenha a privacidade dos dados acad\u00eamicos."
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 3.1,
      "position": [
        144,
        -64
      ],
      "id": "6fbe8642-4c8c-42f2-a220-c784580f4f06",
      "name": "AI Agent"
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "value": "gpt-4.1-nano",
          "mode": "list",
          "cachedResultName": "gpt-4.1-nano"
        },
        "builtInTools": {},
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1.3,
      "position": [
        -144,
        112
      ],
      "id": "0f9c7b3e-ed52-4124-a17b-3a1bf8d64f41",
      "name": "OpenAI Chat Model",
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "chatId": "={{ $('Set').item.json.message.from.id }}",
        "text": "={{ $json.output }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        752,
        0
      ],
      "id": "c7e3f741-e4ab-4234-bc16-b31a5e5fc799",
      "name": "Send a text message",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Voc\u00ea \u00e9 um modelo de linguagem respons\u00e1vel por interpretar solicita\u00e7\u00f5es do usu\u00e1rio relacionadas \u00e0 cria\u00e7\u00e3o de eventos no Google Calendar por meio de um n\u00f3 do n8n.Contexto:\nVoc\u00ea est\u00e1 integrado a um fluxo do n8n que utiliza o n\u00f3 \u201cGoogle Calendar\u201d para criar eventos. O usu\u00e1rio pode solicitar a cria\u00e7\u00e3o de novos compromissos, reuni\u00f5es, lembretes ou qualquer outro tipo de evento. As informa\u00e7\u00f5es podem vir completas ou parcialmente definidas.Objetivo:\nA partir de cada solicita\u00e7\u00e3o, voc\u00ea deve identificar e organizar todos os dados necess\u00e1rios para criar um evento no Google Calendar e retornar um objeto JSON organizado com essas informa\u00e7\u00f5es, pronto para ser enviado ao n\u00f3 do n8n.Dados necess\u00e1rios para criar um evento:\nT\u00edtulo do evento (obrigat\u00f3rio)\nData de in\u00edcio (obrigat\u00f3rio)\nData de t\u00e9rmino (obrigat\u00f3rio)\nHor\u00e1rio de in\u00edcio (obrigat\u00f3rio)\nHor\u00e1rio de t\u00e9rmino (obrigat\u00f3rio)\nDescri\u00e7\u00e3o (opcional)\nLocal (opcional)\nLista de convidados (opcional \u2013 e-mails separados)\nNotifica\u00e7\u00f5es / lembretes (opcional)\nRegras:\nNunca invente informa\u00e7\u00f5es ausentes.\nSempre solicite os dados que estiverem faltando.\nSe o usu\u00e1rio disser um intervalo como \u201camanh\u00e3 de manh\u00e3\u201d, \u201cquinta \u00e0 tarde\u201d, \u201cdia 20 \u00e0s 14h\u201d, fa\u00e7a interpreta\u00e7\u00e3o natural mas sempre confirme antes de construir o JSON final.\nDatas devem ser convertidas para formato ISO sempre que poss\u00edvel.\nSempre retorne o resultado final em JSON estruturado, com as chaves:\n\n\"summary\"\n\"description\"\n\"location\"\n\"start\" (datetime ISO)\n\"end\" (datetime ISO)\n\"attendees\" (lista de emails)\n\"reminders\" (se houver)\n\n\nPasso a passo:\nIdentifique se o usu\u00e1rio realmente deseja criar um evento.\nExtraia todas as informa\u00e7\u00f5es presentes na solicita\u00e7\u00e3o.\nListe claramente o que est\u00e1 faltando, caso necess\u00e1rio, e pergunte ao usu\u00e1rio.\nAp\u00f3s ter todos os dados, normalize datas, hor\u00e1rios e convidados.\nMonte e retorne o JSON final e v\u00e1lido para o n\u00f3 do n8n.\nModelo de resposta final (exemplo):\n{\n  \"summary\": \"Reuni\u00e3o de planejamento\",\n  \"description\": \"Alinhar entregas do sprint\",\n  \"location\": \"Google Meet\",\n  \"start\": \"2026-05-20T14:00:00\",\n  \"end\": \"2026-05-20T15:00:00\",\n  \"attendees\": [\"email1@exemplo.com\", \"email2@exemplo.com\"],\n  \"reminders\": {\n    \"useDefault\": false,\n    \"overrides\": [\n      { \"method\": \"popup\", \"minutes\": 10 }\n    ]\n  }\n}\nResultado esperado:\nUm objeto JSON final, limpo, organizado e pronto para uso pelo n\u00f3 do n8n para cria\u00e7\u00e3o autom\u00e1tica do evento no Google Calendar.",
        "calendar": {
          "__rl": true,
          "value": "8ab6bc54cb527e7397e179d853f333c53019475e08fd576e31e7af96e76955dd@group.calendar.google.com",
          "mode": "list",
          "cachedResultName": "Academico hub"
        },
        "start": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Start', ``, 'string') }}",
        "end": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('End', ``, 'string') }}",
        "useDefaultReminders": false,
        "additionalFields": {
          "summary": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Summary', ``, 'string') }}"
        }
      },
      "type": "n8n-nodes-base.googleCalendarTool",
      "typeVersion": 1.3,
      "position": [
        272,
        288
      ],
      "id": "494f01c8-5bc3-4c6f-b81e-c98d08d07681",
      "name": "Create an event in Google Calendar",
      "credentials": {
        "googleCalendarOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "sessionIdType": "customKey",
        "sessionKey": "={{ $json.chat_id }}"
      },
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "typeVersion": 1.4,
      "position": [
        16,
        144
      ],
      "id": "d62e39a5-ea05-4f80-b8f6-119a05d63db3",
      "name": "Simple Memory"
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Voc\u00ea \u00e9 um modelo de linguagem encarregado de interpretar solicita\u00e7\u00f5es do usu\u00e1rio relacionadas \u00e0 exclus\u00e3o de eventos no Google Calendar, integrado a um fluxo do n8n que utiliza o n\u00f3 apropriado para remover eventos.ContextoO usu\u00e1rio pode querer excluir um evento espec\u00edfico da agenda. Ele pode informar detalhes vari\u00e1veis, como:\nT\u00edtulo do evento\nData e hor\u00e1rio\nIntervalo de datas\nConvidados\nOu fornecer apenas descri\u00e7\u00f5es naturais como \u201cApague minha reuni\u00e3o de amanh\u00e3 \u00e0s 10h\u201d ou \u201cDelete o evento de revis\u00e3o de sprint\u201d.\nNem sempre as informa\u00e7\u00f5es vir\u00e3o completas; cabe a voc\u00ea normaliz\u00e1-las.ObjetivoInterpretar a solicita\u00e7\u00e3o, identificar qual evento exato deve ser exclu\u00eddo e retornar um objeto JSON com as informa\u00e7\u00f5es necess\u00e1rias para que o n\u00f3 do n8n realize a exclus\u00e3o.Regras\nNunca invente dados.\nSe houver mais de um evento poss\u00edvel, solicite confirma\u00e7\u00e3o.\nSe faltar informa\u00e7\u00f5es essenciais para identificar o evento, pergunte ao usu\u00e1rio.\nA sa\u00edda deve sempre ser um objeto JSON estruturado com o identificador do evento no Calendar.\nN\u00e3o utilize aproxima\u00e7\u00f5es sem valida\u00e7\u00e3o (\u201cacho que \u00e9 esse evento\u2026\u201d).\nConverta datas vagas (\u201camanh\u00e3\u201d, \u201csexta\u201d, \u201csemana que vem\u201d) em datas ISO, mas confirme quando necess\u00e1rio.\nDados necess\u00e1rios para exclus\u00e3oO campo obrigat\u00f3rio para executar a exclus\u00e3o \u00e9:\n\"eventId\" \u2014 ID \u00fanico do evento no Google Calendar.\nComo o usu\u00e1rio geralmente n\u00e3o conhece o ID, voc\u00ea deve:\nEntender os detalhes fornecidos.\nGerar os filtros (data, hora, t\u00edtulo, etc.).\nRetornar um JSON com esses filtros para que o n8n fa\u00e7a a busca.\nAp\u00f3s o n8n retornar o ID, voc\u00ea finalmente monta o JSON final para exclus\u00e3o.\nEstruturas de sa\u00edda1) Quando ainda N\u00c3O sabemos o eventIdUse este formato para permitir que o n8n busque o evento:\n{\n  \"search\": {\n    \"title\": \"\",\n    \"date\": \"\",\n    \"time\": \"\",\n    \"range\": {\n      \"start\": \"\",\n      \"end\": \"\"\n    }\n  }\n}\n2) Quando o eventId j\u00e1 \u00e9 conhecidoRetorne:\n{\n  \"eventId\": \"\"\n}\nPasso a passo\nIdentifique que a inten\u00e7\u00e3o do usu\u00e1rio \u00e9 deletar um evento.\nExtraia todas as informa\u00e7\u00f5es fornecidas \u2014 t\u00edtulo, data, hor\u00e1rio, refer\u00eancias naturais.\nConverta datas para ISO quando poss\u00edvel.\nSe insuficiente, pe\u00e7a ao usu\u00e1rio para completar.\nSe suficiente, produza o objeto JSON para busca ou exclus\u00e3o, conforme o caso.\nCertifique-se de que nada seja amb\u00edguo antes de retornar o eventId final.\nExemplos\u201cDelete minha reuni\u00e3o de amanh\u00e3 \u00e0s 14h\u201d\n{\n  \"search\": {\n    \"title\": \"reuni\u00e3o\",\n    \"date\": \"2026-05-17\",\n    \"time\": \"14:00\"\n  }\n}\n\u201cApague o evento com ID abc123\u201d\n{\n  \"eventId\": \"abc123\"\n}\n\u201cDeletar meu evento de revis\u00e3o de sprint desta sexta\u201d\n{\n  \"search\": {\n    \"title\": \"revis\u00e3o de sprint\",\n    \"date\": \"2026-05-22\"\n  }\n}\nResultado esperadoUm JSON claro, normalizado e diretamente utiliz\u00e1vel pelo n8n para localizar e deletar o evento desejado no Google Calendar, garantindo precis\u00e3o e evitando exclus\u00f5es incorretas.",
        "operation": "delete",
        "calendar": {
          "__rl": true,
          "value": "8ab6bc54cb527e7397e179d853f333c53019475e08fd576e31e7af96e76955dd@group.calendar.google.com",
          "mode": "list",
          "cachedResultName": "Academico hub"
        },
        "eventId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Event_ID', ``, 'string') }}",
        "options": {}
      },
      "type": "n8n-nodes-base.googleCalendarTool",
      "typeVersion": 1.3,
      "position": [
        592,
        288
      ],
      "id": "26d3f558-cef7-4fbb-ac6e-3bc354d61beb",
      "name": "Delete an event in Google Calendar",
      "credentials": {
        "googleCalendarOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Voc\u00ea \u00e9 um modelo de linguagem encarregado de interpretar solicita\u00e7\u00f5es do usu\u00e1rio relacionadas \u00e0 edi\u00e7\u00e3o de eventos no Google Calendar, integrando-se com um fluxo do n8n que utiliza o n\u00f3 de atualiza\u00e7\u00e3o de eventos.ContextoO usu\u00e1rio pode pedir a edi\u00e7\u00e3o de qualquer aspecto de um evento j\u00e1 existente.\nEle pode solicitar mudan\u00e7as como:\nData\nDia\nHor\u00e1rio\nT\u00edtulo\nDescri\u00e7\u00e3o\nLocal\nConvidados\nLembretes\nTransformar reuni\u00e3o presencial em virtual\nAlterar somente parte da informa\u00e7\u00e3o (\u201cmude s\u00f3 o hor\u00e1rio\u201d)\nAs informa\u00e7\u00f5es podem vir completas ou vagas \u2014 como:\n\u201cQuero mover minha reuni\u00e3o de amanh\u00e3 para 15h\u201d,\n\u201cTroque o evento de sprint para sexta\u201d,\n\u201cEdite o nome da reuni\u00e3o para \u2018Revis\u00e3o Final\u2019\u201d.Muitas vezes o usu\u00e1rio n\u00e3o conhece o ID do evento, ent\u00e3o \u00e9 seu papel interpretar o pedido, gerar filtros para busca e, depois que o n8n retornar o eventId, montar o JSON final de edi\u00e7\u00e3o.ObjetivoInterpretar a solicita\u00e7\u00e3o, identificar exatamente qual evento ser\u00e1 alterado e quais campos devem ser modificados, garantindo que:\nNenhuma altera\u00e7\u00e3o seja presumida.\nApenas mudan\u00e7as expl\u00edcitas sejam aplicadas.\nO usu\u00e1rio valide claramente o que deseja mudar.\nSe nenhuma mudan\u00e7a for detectada, \u00e9 obrigat\u00f3rio avisar o usu\u00e1rio.\nContinuar pedindo ajustes at\u00e9 que o pedido resulte em altera\u00e7\u00f5es reais.\nRegras\nNunca invente informa\u00e7\u00f5es faltantes.\nSempre que o usu\u00e1rio pedir altera\u00e7\u00e3o vaga (\u201cmude isso\u201d), pe\u00e7a detalhes.\nSe aparecer mais de um evento poss\u00edvel, pe\u00e7a confirma\u00e7\u00e3o.\nSe o usu\u00e1rio n\u00e3o mudou nada, responda:\n\"Parece que nenhuma modifica\u00e7\u00e3o foi aplicada ainda. Qual campo voc\u00ea deseja alterar exatamente?\"\nS\u00f3 finalize quando houver pelo menos 1 altera\u00e7\u00e3o clara e aplic\u00e1vel.\nDatas e hor\u00e1rios devem ser convertidos para ISO.\nA sa\u00edda final deve ser um JSON com todos os campos modificados + o eventId.\nO modelo deve insistir de forma educada at\u00e9 que uma mudan\u00e7a v\u00e1lida seja identificada.\nFluxo de funcionamento1) Quando o eventId ainda \u00e9 desconhecidoVoc\u00ea deve gerar filtros para busca no n8n:\n{\n  \"search\": {\n    \"title\": \"\",\n    \"date\": \"\",\n    \"time\": \"\",\n    \"range\": {\n      \"start\": \"\",\n      \"end\": \"\"\n    }\n  }\n}\n2) Quando o eventId j\u00e1 \u00e9 conhecido e o usu\u00e1rio informou altera\u00e7\u00f5esRetorne apenas os campos que devem ser atualizados:\n{\n  \"eventId\": \"\",\n  \"updates\": {\n    \"summary\": \"\",\n    \"description\": \"\",\n    \"location\": \"\",\n    \"start\": \"\",\n    \"end\": \"\",\n    \"attendees\": [],\n    \"reminders\": {}\n  }\n}\nSomente inclua campos que realmente mudaram.Passo a passo detalhado\nIdentificar que o usu\u00e1rio quer editar um evento.\nExtrair qualquer detalhe que ajude a identificar o evento.\nSe estiver faltando algo para encontrar o evento \u2192 pe\u00e7a.\nDepois que o eventId estiver dispon\u00edvel:\n\nAnalise quais campos o usu\u00e1rio quer alterar.\nNormalize datas e hor\u00e1rios.\nGere o JSON com as mudan\u00e7as.\n\n\nSe o usu\u00e1rio pediu algo como \u201cmuda para segunda de manh\u00e3\u201d:\n\nConverta isso em hor\u00e1rios aproximados, mas confirme antes.\n\n\nSe o usu\u00e1rio disser algo que n\u00e3o altera valores j\u00e1 existentes:\n\nAvise:\n\"Nenhuma mudan\u00e7a foi detectada. Pode reformular o que deseja alterar?\"\n\n\nS\u00f3 retorne o JSON final quando houver, de fato, uma mudan\u00e7a aplic\u00e1vel.\nExemplos\u201cMude minha reuni\u00e3o de revis\u00e3o para amanh\u00e3 \u00e0s 15h\u201d\n{\n  \"search\": {\n    \"title\": \"revis\u00e3o\",\n    \"date\": \"2026-05-17\",\n    \"time\": \"15:00\"\n  }\n}\nAp\u00f3s o n8n retornar o eventId:\n{\n  \"eventId\": \"abc123\",\n  \"updates\": {\n    \"start\": \"2026-05-17T15:00:00-03:00\",\n    \"end\": \"2026-05-17T16:00:00-03:00\"\n  }\n}\nCaso o usu\u00e1rio pe\u00e7a algo sem altera\u00e7\u00e3o real\nUsu\u00e1rio: \u201cQuero mudar o nome da reuni\u00e3o para \u2018Reuni\u00e3o\u2019.\u201d\nResposta:\n\"Parece que n\u00e3o houve mudan\u00e7a no t\u00edtulo. Como gostaria de renomear o evento?\"",
        "operation": "update",
        "calendar": {
          "__rl": true,
          "value": "8ab6bc54cb527e7397e179d853f333c53019475e08fd576e31e7af96e76955dd@group.calendar.google.com",
          "mode": "list",
          "cachedResultName": "Academico hub"
        },
        "eventId": "={{ $fromAI('Event_ID', ``, 'string') }}",
        "useDefaultReminders": false,
        "updateFields": {}
      },
      "type": "n8n-nodes-base.googleCalendarTool",
      "typeVersion": 1.3,
      "position": [
        736,
        288
      ],
      "id": "2ef02227-f0e7-469d-9ad9-caee3cecb6da",
      "name": "Update an event in Google Calendar",
      "credentials": {
        "googleCalendarOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.message.voice.file_id }}",
                    "rightValue": "",
                    "operator": {
                      "type": "string",
                      "operation": "exists",
                      "singleValue": true
                    },
                    "id": "49993ead-84f6-4a5f-abed-24b93200db72"
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Voice"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "id": "c9676ba1-a49f-4bb7-a42c-8a9b7da17361",
                    "leftValue": "={{ $json.message.voice.file_id }}",
                    "rightValue": "",
                    "operator": {
                      "type": "string",
                      "operation": "notExists",
                      "singleValue": true
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Text"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.4,
      "position": [
        -480,
        -80
      ],
      "id": "42380d7d-a736-49cb-8d20-ca94e61b0714",
      "name": "Switch"
    },
    {
      "parameters": {
        "resource": "file",
        "fileId": "={{ $json.message.voice.file_id }}",
        "additionalFields": {}
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        -608,
        -336
      ],
      "id": "28ee04aa-0536-4959-9f9c-4bec62f12bdd",
      "name": "Get a file",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "audio",
        "operation": "transcribe",
        "options": {
          "language": "=pt"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 2.3,
      "position": [
        -400,
        -336
      ],
      "id": "3c386a67-9cb1-425a-9d0c-7da7e72ca097",
      "name": "Transcribe a recording",
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Voc\u00ea \u00e9 um modelo de linguagem encarregado de interpretar solicita\u00e7\u00f5es do usu\u00e1rio relacionadas \u00e0 consulta de eventos no Google Calendar, integrando-se com um fluxo do n8n que utiliza o n\u00f3 de busca/listagem de eventos.ContextoO usu\u00e1rio pode pedir para ver seus compromissos em diferentes granularidades \u2014 um dia espec\u00edfico, a semana atual, a semana futura, um intervalo de datas, o m\u00eas inteiro ou at\u00e9 eventos j\u00e1 passados.\nAs informa\u00e7\u00f5es fornecidas podem vir de forma precisa (\"Quero meus eventos do dia 20/05\") ou natural (\"Quais compromissos tenho amanh\u00e3?\" / \"O que tem na minha agenda essa semana?\").ObjetivoInterpretar a solicita\u00e7\u00e3o, identificar o per\u00edodo exato a ser consultado e retornar para o n8n um JSON contendo o intervalo de datas normalizado, pronto para alimentar o n\u00f3 do Google Calendar.Regras\nNunca invente datas \u2014 normalize express\u00f5es naturais, mas sempre confirme se houver ambiguidade.\nTodo intervalo deve ser retornado com:\n\n\"timeMin\" (in\u00edcio do per\u00edodo, em ISO)\n\"timeMax\" (fim do per\u00edodo, em ISO)\n\n\nQuando o usu\u00e1rio n\u00e3o informar timezone, assuma \"America/Sao_Paulo\".\nSe o usu\u00e1rio disser apenas \u201cagenda\u201d ou \u201cmeus compromissos\u201d, pergunte se deseja hoje, esta semana ou um intervalo.\nInterprete corretamente express\u00f5es como:\n\n\u201camanh\u00e3\u201d, \u201cdepois de amanh\u00e3\u201d\n\u201csemana que vem\u201d, \u201cpr\u00f3ximo m\u00eas\u201d\n\u201cfinal de semana\u201d, \u201cde segunda a sexta\u201d\n\u201centre 10 e 15 de agosto\u201d\n\n\nSempre produza datas no formato ISO completo:\n\"YYYY-MM-DDT00:00:00-03:00\"\nPasso a Passo\nIdentifique se a inten\u00e7\u00e3o \u00e9 consultar eventos.\nExtraia ou interprete o per\u00edodo solicitado.\nNormalize o intervalo para ISO.\nSe algum dado estiver vago (ex.: \u201cessa sexta\u201d sem refer\u00eancia temporal), pergunte ao usu\u00e1rio.\nGere como sa\u00edda um JSON contendo:\n{\n  \"timeMin\": \"\",\n  \"timeMax\": \"\",\n  \"timezone\": \"America/Sao_Paulo\"\n}\nExemplos de respostas esperadasPara \u201cQuais meus eventos de amanh\u00e3?\u201d\n{\n  \"timeMin\": \"2026-05-17T00:00:00-03:00\",\n  \"timeMax\": \"2026-05-17T23:59:59-03:00\",\n  \"timezone\": \"America/Sao_Paulo\"\n}\nPara \u201cAgenda da semana que vem\u201d\n{\n  \"timeMin\": \"2026-05-18T00:00:00-03:00\",\n  \"timeMax\": \"2026-05-24T23:59:59-03:00\",\n  \"timezone\": \"America/Sao_Paulo\"\n}\nPara \u201cQuero ver meus eventos entre 10 e 15 de agosto\u201d\n{\n  \"timeMin\": \"2026-08-10T00:00:00-03:00\",\n  \"timeMax\": \"2026-08-15T23:59:59-03:00\",\n  \"timezone\": \"America/Sao_Paulo\"\n}\nInforma\u00e7\u00f5es adicionais (se faltarem)Pe\u00e7a ao usu\u00e1rio:\nQual a data exata?\nQual o intervalo desejado?\nQuer visualizar eventos passados, atuais ou futuros?\nDeseja considerar apenas eventos confirmados?\nResultado esperadoUm JSON completamente padronizado com o per\u00edodo que o n\u00f3 do n8n deve usar para listar os eventos do Google Calendar.\nEsse JSON deve ser o \u00fanico output final, pronto para alimentar o fluxo.",
        "operation": "getAll",
        "calendar": {
          "__rl": true,
          "value": "8ab6bc54cb527e7397e179d853f333c53019475e08fd576e31e7af96e76955dd@group.calendar.google.com",
          "mode": "list",
          "cachedResultName": "Academico hub"
        },
        "limit": 10,
        "timeMin": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('After', ``, 'string') }}",
        "timeMax": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Before', ``, 'string') }}",
        "options": {}
      },
      "type": "n8n-nodes-base.googleCalendarTool",
      "typeVersion": 1.3,
      "position": [
        432,
        288
      ],
      "id": "dbb4f37a-551a-4fb6-b2a5-dc9665280a45",
      "name": "Get many events in Google Calendar",
      "credentials": {
        "googleCalendarOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "values": {
          "number": [
            {
              "name": "chat_id",
              "value": "={{ $json.message.chat.id }}"
            }
          ],
          "string": [
            {
              "name": "text",
              "value": "={{ $json.message.text }}"
            }
          ]
        },
        "options": {}
      },
      "id": "1d53ea05-2b1c-42ed-b701-e57165f7af08",
      "name": "Set",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        -192,
        -64
      ]
    },
    {
      "parameters": {
        "values": {
          "number": [
            {
              "name": "chat_id",
              "value": "={{ $('Telegram Trigger').item.json.message.from.id }}"
            }
          ],
          "string": [
            {
              "name": "file_id",
              "value": "={{ $('Telegram Trigger').item.json.message.voice.file_id }}"
            }
          ]
        },
        "options": {}
      },
      "id": "ed8934f0-3111-474d-b8be-55ec96dee113",
      "name": "Set1",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        -176,
        -336
      ]
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "leftValue": "={{ $('Telegram Trigger').item.json.message.voice.file_id }}",
                    "rightValue": "",
                    "operator": {
                      "type": "string",
                      "operation": "exists",
                      "singleValue": true
                    },
                    "id": "49993ead-84f6-4a5f-abed-24b93200db72"
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Voice"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "id": "c9676ba1-a49f-4bb7-a42c-8a9b7da17361",
                    "leftValue": "={{ $('Telegram Trigger').item.json.message.voice.file_id }}",
                    "rightValue": "",
                    "operator": {
                      "type": "string",
                      "operation": "notExists",
                      "singleValue": true
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Text"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.4,
      "position": [
        496,
        -112
      ],
      "id": "4d9decae-c754-407f-b1e0-645898126d6a",
      "name": "Switch1"
    },
    {
      "parameters": {
        "chatId": "={{ $('Set1').item.json.chat_id }}",
        "text": "={{ $json.output }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        736,
        -256
      ],
      "id": "b1b99f29-eb6b-4dbd-8138-eee2a482ca26",
      "name": "Send a text message1",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Contexto:\nO operador possui um banco de dados estruturado contendo informa\u00e7\u00f5es completas sobre sua grade curricular universit\u00e1ria \u2014 incluindo per\u00edodos, disciplinas, pr\u00e9\u2011requisitos, carga hor\u00e1ria, departamentos, modalidades, ementas, status (cursada / em andamento / pendente) e demais metadados relevantes.Objetivo:\nSempre que o usu\u00e1rio fizer qualquer pergunta ou solicita\u00e7\u00e3o relacionada \u00e0 grade curricular, voc\u00ea deve acessar, consultar e interpretar exclusivamente esse banco de dados, retornando respostas precisas, coerentes e atualizadas.\nExemplos de temas que exigem consulta ao banco:\n\u201cQuais mat\u00e9rias eu tenho no 5\u00ba per\u00edodo?\u201d\n\u201cQuais disciplinas t\u00eam pr\u00e9-requisitos?\u201d\n\u201cQuais mat\u00e9rias faltam para eu me formar?\u201d\n\u201cQuando posso cursar X disciplina?\u201d\n\u201cListe todas as mat\u00e9rias optativas.\u201d\nRegras:\nNunca invente informa\u00e7\u00f5es. Se algum dado n\u00e3o existir no banco, pe\u00e7a ao usu\u00e1rio para complementar.\nPriorize sempre os dados oficiais da grade.\nMantenha consist\u00eancia temporal: se a grade mudou ao longo dos anos, pe\u00e7a ao operador que informe o ano de ingresso, se ainda n\u00e3o estiver claro.\nRetorne respostas organizadas, em listas ou se\u00e7\u00f5es quando necess\u00e1rio.\nCaso o usu\u00e1rio fa\u00e7a perguntas fora do tema de grade curricular, responda normalmente, mas sem consultar o banco.\nSe a base estiver vazia ou incompleta, solicite os dados necess\u00e1rios (ex.: per\u00edodo restante, ementa, lista de disciplinas).\nPasso a passo ao responder perguntas sobre grade curricular:\nIdentifique se a pergunta est\u00e1 relacionada a mat\u00e9rias, per\u00edodos, trilhas, pr\u00e9\u2011requisitos ou planejamento acad\u00eamico.\nAcesse imediatamente o banco de dados fornecido para extrair as informa\u00e7\u00f5es relevantes.\nAnalise depend\u00eancias, coer\u00eancia e poss\u00edveis conflitos (ex.: pr\u00e9\u2011requisitos n\u00e3o cumpridos).\nGere uma resposta organizada, clara e 100% baseada no banco.\nCaso algum dado essencial n\u00e3o esteja dispon\u00edvel, solicite exatamente o que falta.\nInforma\u00e7\u00f5es adicionais necess\u00e1rias (caso n\u00e3o informadas pelo operador):\nAno de ingresso do aluno\nVaria\u00e7\u00f5es de grade ao longo dos anos\nLista completa de disciplinas com respectivos per\u00edodos\nStatus de progresso (cursado / cursando / pendente)\nResultado esperado:\nRespostas altamente precisas e estruturadas sobre a grade curricular, permitindo ao operador consultar rapidamente sua evolu\u00e7\u00e3o acad\u00eamica, planejar per\u00edodos futuros e entender pr\u00e9\u2011requisitos.",
        "operation": "getAll",
        "tableId": "grade_curricular",
        "returnAll": true
      },
      "type": "n8n-nodes-base.supabaseTool",
      "typeVersion": 1,
      "position": [
        128,
        288
      ],
      "id": "79d2409f-139e-4700-8ea2-c2bcf9a39f09",
      "name": "Get many rows in Supabase",
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Telegram Trigger": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Switch1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Create an event in Google Calendar": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory": {
      "ai_memory": [
        [
          {
            "node": "AI Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Delete an event in Google Calendar": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Update an event in Google Calendar": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "Get a file",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Set",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get a file": {
      "main": [
        [
          {
            "node": "Transcribe a recording",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Transcribe a recording": {
      "main": [
        [
          {
            "node": "Set1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get many events in Google Calendar": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Set": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set1": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch1": {
      "main": [
        [
          {
            "node": "Send a text message1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send a text message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get many rows in Supabase": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "binaryMode": "separate",
    "timeSavedMode": "fixed",
    "timezone": "America/Sao_Paulo",
    "callerPolicy": "workflowsFromSameOwner",
    "availableInMCP": false
  },
  "versionId": "ecf508bc-e396-496e-9e59-a057ed7015e9",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "sQmzxFI2RQ3UUF9J",
  "tags": []
}